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 /src/main.rs | |
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 'src/main.rs')
-rw-r--r-- | src/main.rs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs index 273b4bb..e3f4da3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -60,11 +60,14 @@ enum Error { VhostNetDeviceNew(hw::virtio::vhost::Error), NetDeviceNew(hw::virtio::NetError), NetDeviceRootSetup(sys_util::Error), + VhostVsockDeviceNew(hw::virtio::vhost::Error), + VsockDeviceRootSetup(sys_util::Error), DeviceJail(io_jail::Error), DevicePivotRoot(io_jail::Error), RegisterBlock(device_manager::Error), RegisterNet(device_manager::Error), RegisterWayland(device_manager::Error), + RegisterVsock(device_manager::Error), Cmdline(kernel_cmdline::Error), MissingWayland(PathBuf), RegisterIrqfd(sys_util::Error), @@ -114,12 +117,17 @@ impl fmt::Display for Error { } &Error::RegisterBlock(ref e) => write!(f, "error registering block device: {:?}", e), &Error::VhostNetDeviceNew(ref e) => write!(f, "failed to set up vhost networking: {:?}", e), + &Error::RegisterVsock(ref e) => write!(f, "error registering virtual socket device: {:?}", e), &Error::NetDeviceNew(ref e) => write!(f, "failed to set up virtio networking: {:?}", e), &Error::NetDeviceRootSetup(ref e) => { write!(f, "failed to create root directory for a net device: {:?}", e) } &Error::DeviceJail(ref e) => write!(f, "failed to jail device: {}", e), &Error::DevicePivotRoot(ref e) => write!(f, "failed to pivot root device: {}", e), + &Error::VhostVsockDeviceNew(ref e) => write!(f, "failed to set up virtual socket device: {:?}", e), + &Error::VsockDeviceRootSetup(ref e) => { + write!(f, "failed to create root directory for a vsock device: {:?}", e) + } &Error::RegisterNet(ref e) => write!(f, "error registering net device: {:?}", e), &Error::RegisterRng(ref e) => write!(f, "error registering rng device: {:?}", e), &Error::RngDeviceNew(ref e) => write!(f, "failed to set up rng: {:?}", e), @@ -190,6 +198,7 @@ struct Config { socket_path: Option<PathBuf>, multiprocess: bool, warn_unknown_ports: bool, + cid: Option<u64>, } const KERNEL_START_OFFSET: usize = 0x200000; @@ -383,6 +392,24 @@ fn run_config(cfg: Config) -> Result<()> { } } + let vsock_root = TempDir::new(&PathBuf::from("/tmp/vsock_root")) + .map_err(Error::VsockDeviceRootSetup)?; + if let Some(cid) = cfg.cid { + let vsock_box = Box::new(hw::virtio::vhost::Vsock::new(cid, &guest_mem) + .map_err(|e| Error::VhostVsockDeviceNew(e))?); + + let jail = if cfg.multiprocess { + let root_path = vsock_root.as_path().unwrap(); + let policy_path = Path::new("vhost_vsock_device.policy"); + + Some(create_base_minijail(root_path, policy_path)?) + } else { + None + }; + + device_manager.register_mmio(vsock_box, jail, &mut cmdline).map_err(Error::RegisterVsock)?; + } + if !cfg.params.is_empty() { cmdline .insert_str(cfg.params) @@ -856,6 +883,17 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument:: "multiprocess" => { cfg.multiprocess = true; } + "cid" => { + if cfg.cid.is_some() { + return Err(argument::Error::TooManyArguments("`cid` alread given".to_owned())); + } + cfg.cid = Some(value.unwrap().parse().map_err(|_| { + argument::Error::InvalidValue { + value: value.unwrap().to_owned(), + expected: "this value for `cid` must be an unsigned integer", + } + })?); + } "help" => return Err(argument::Error::PrintHelp), _ => unreachable!(), } @@ -892,6 +930,7 @@ fn run_vm(args: std::env::Args) { "PATH", "Path to put the control socket. If PATH is a directory, a name will be generated."), Argument::short_flag('u', "multiprocess", "Run each device in a child process."), + Argument::value("cid", "CID", "Context ID for virtual sockets"), Argument::short_flag('h', "help", "Print help message.")]; let mut cfg = Config::default(); |