diff options
author | Chirantan Ekbote <chirantan@chromium.org> | 2017-08-28 09:51:18 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-09-18 16:48:43 -0700 |
commit | 88f9cba448ff7f1cd61c8bf66e34772132a8663f (patch) | |
tree | be3a916b0991914a841ef51cbc487e07dacacf89 /vhost | |
parent | 270f7b6a16a1c0475da061d5ecb344db10306a64 (diff) | |
download | crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.tar crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.tar.gz crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.tar.bz2 crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.tar.lz crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.tar.xz crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.tar.zst crosvm-88f9cba448ff7f1cd61c8bf66e34772132a8663f.zip |
Implement virtio-vsock
Implement the virtual sockets device using vhost subsystem of the host kernel to handle data transfer. BUG=chromium:708267 TEST=build and run maitred in guest VM without issue Change-Id: I35b542c0fc7e0fd9296f7ba3e1dfce60bf524d15 Signed-off-by: Chirantan Ekbote <chirantan@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/638838 Reviewed-by: Stephen Barber <smbarber@chromium.org>
Diffstat (limited to 'vhost')
-rw-r--r-- | vhost/src/lib.rs | 3 | ||||
-rw-r--r-- | vhost/src/net.rs | 25 | ||||
-rw-r--r-- | vhost/src/vsock.rs | 82 |
3 files changed, 94 insertions, 16 deletions
diff --git a/vhost/src/lib.rs b/vhost/src/lib.rs index b4282d2..4a103a2 100644 --- a/vhost/src/lib.rs +++ b/vhost/src/lib.rs @@ -8,7 +8,10 @@ extern crate sys_util; extern crate virtio_sys; pub mod net; +mod vsock; + pub use net::Net; +pub use vsock::Vsock; use std::io::Error as IoError; use std::mem; diff --git a/vhost/src/net.rs b/vhost/src/net.rs index f7c5dfd..0c6eaad 100644 --- a/vhost/src/net.rs +++ b/vhost/src/net.rs @@ -4,10 +4,9 @@ use libc; use net_util; -use std::ffi::CString; -use std::fs::File; -use std::io::Error as IoError; -use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; +use std::fs::{File, OpenOptions}; +use std::os::unix::fs::OpenOptionsExt; +use std::os::unix::io::{AsRawFd, RawFd}; use virtio_sys; use sys_util::{ioctl_with_ref, GuestMemory}; @@ -43,19 +42,13 @@ impl Net { /// # Arguments /// * `mem` - Guest memory mapping. pub fn new(mem: &GuestMemory) -> Result<Net> { - // Open calls are safe because we give a constant nul-terminated - // string and verify the result. The CString unwrap is safe because - // DEVICE does not have any embedded '\0' characters. - let fd = unsafe { - libc::open(CString::new(DEVICE).unwrap().as_ptr(), - libc::O_RDWR | libc::O_NONBLOCK | libc::O_CLOEXEC) - }; - if fd < 0 { - return Err(Error::VhostOpen(IoError::last_os_error())); - } Ok(Net { - // There are no other users of this fd, so this is safe. - fd: unsafe { File::from_raw_fd(fd) }, + fd: OpenOptions::new() + .read(true) + .write(true) + .custom_flags(libc::O_CLOEXEC | libc::O_NONBLOCK) + .open(DEVICE) + .map_err(Error::VhostOpen)?, mem: mem.clone(), }) } 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() + } +} |