summary refs log tree commit diff
path: root/vhost/src/vsock.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vhost/src/vsock.rs')
-rw-r--r--vhost/src/vsock.rs82
1 files changed, 82 insertions, 0 deletions
diff --git a/vhost/src/vsock.rs b/vhost/src/vsock.rs
new file mode 100644
index 0000000..8c96b9f
--- /dev/null
+++ b/vhost/src/vsock.rs
@@ -0,0 +1,82 @@
+// Copyright 2017 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use libc;
+use std::fs::{File, OpenOptions};
+use std::os::unix::fs::OpenOptionsExt;
+use std::os::unix::io::{AsRawFd, RawFd};
+
+use sys_util::{ioctl_with_ref, GuestMemory};
+use virtio_sys::{VHOST_VSOCK_SET_GUEST_CID, VHOST_VSOCK_SET_RUNNING};
+
+use super::{ioctl_result, Error, Result, Vhost};
+
+static DEVICE: &'static str = "/dev/vhost-vsock";
+
+/// Handle for running VHOST_VSOCK ioctls.
+pub struct Vsock {
+    fd: File,
+    mem: GuestMemory,
+}
+
+impl Vsock {
+    /// Open a handle to a new VHOST_VSOCK instance.
+    pub fn new(mem: &GuestMemory) -> Result<Vsock> {
+        Ok(Vsock {
+            fd: OpenOptions::new()
+                .read(true)
+                .write(true)
+                .custom_flags(libc::O_CLOEXEC | libc::O_NONBLOCK)
+                .open(DEVICE)
+                .map_err(Error::VhostOpen)?,
+            mem: mem.clone(),
+        })
+    }
+
+    /// Set the CID for the guest.  This number is used for routing all data destined for
+    /// programs
+    /// running in the guest.
+    ///
+    /// # Arguments
+    /// * `cid` - CID to assign to the guest
+    pub fn set_cid(&self, cid: u64) -> Result<()> {
+        let ret = unsafe { ioctl_with_ref(&self.fd, VHOST_VSOCK_SET_GUEST_CID(), &cid) };
+        if ret < 0 {
+            return ioctl_result();
+        }
+        Ok(())
+    }
+
+    /// Tell the VHOST driver to start performing data transfer.
+    pub fn start(&self) -> Result<()> {
+        self.set_running(true)
+    }
+
+    /// Tell the VHOST driver to stop performing data transfer.
+    pub fn stop(&self) -> Result<()> {
+        self.set_running(false)
+    }
+
+    fn set_running(&self, running: bool) -> Result<()> {
+        let on: ::std::os::raw::c_int = if running { 1 } else { 0 };
+        let ret = unsafe { ioctl_with_ref(&self.fd, VHOST_VSOCK_SET_RUNNING(), &on) };
+
+        if ret < 0 {
+            return ioctl_result();
+        }
+        Ok(())
+    }
+}
+
+impl Vhost for Vsock {
+    fn mem(&self) -> &GuestMemory {
+        &self.mem
+    }
+}
+
+impl AsRawFd for Vsock {
+    fn as_raw_fd(&self) -> RawFd {
+        self.fd.as_raw_fd()
+    }
+}