From 11e7ece9f529050ca6837f7145101e283124d50e Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Wed, 4 Sep 2019 10:39:17 -0700 Subject: [PATCH] vmm: Add new flag "--vsock" The new flag vsock is meant to be used in order to create a VM with a virtio-vsock device attached to it. Two parameters are needed with this device, "cid" representing the guest context ID, and "sock" representing the UNIX socket path which can be accessed from the host. Signed-off-by: Sebastien Boeuf --- src/main.rs | 12 ++++++++++++ vmm/src/config.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/main.rs b/src/main.rs index 02eb2a7dc..5009afdf1 100755 --- a/src/main.rs +++ b/src/main.rs @@ -165,6 +165,16 @@ fn main() { .takes_value(true) .min_values(1), ) + .arg( + Arg::with_name("vsock") + .long("vsock") + .help( + "Virtio VSOCK parameters \"cid=,\ + sock=\"", + ) + .takes_value(true) + .min_values(1), + ) .arg( Arg::with_name("v") .short("v") @@ -200,6 +210,7 @@ fn main() { let vhost_user_net: Option> = cmd_arguments .values_of("vhost-user-net") .map(|x| x.collect()); + let vsock: Option> = cmd_arguments.values_of("vsock").map(|x| x.collect()); let log_level = match cmd_arguments.occurrences_of("v") { 0 => LevelFilter::Error, @@ -239,6 +250,7 @@ fn main() { console, devices, vhost_user_net, + vsock, }) { Ok(config) => config, Err(e) => { diff --git a/vmm/src/config.rs b/vmm/src/config.rs index e30f9726c..da26ec507 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -71,6 +71,10 @@ pub enum Error<'a> { ParseVuNetQueueSizeParam(std::num::ParseIntError), /// Failed parsing vhost-user-net server parameter. ParseVuNetServerParam(std::num::ParseIntError), + /// Failed parsing vsock context ID parameter. + ParseVsockCidParam(std::num::ParseIntError), + /// Failed parsing vsock socket path parameter. + ParseVsockSockParam, } pub type Result<'a, T> = result::Result>; @@ -88,6 +92,7 @@ pub struct VmParams<'a> { pub console: &'a str, pub devices: Option>, pub vhost_user_net: Option>, + pub vsock: Option>, } fn parse_size(size: &str) -> Result { @@ -513,6 +518,38 @@ impl<'a> VhostUserNetConfig<'a> { } } +pub struct VsockConfig<'a> { + pub cid: u64, + pub sock: &'a Path, +} + +impl<'a> VsockConfig<'a> { + pub fn parse(vsock: &'a str) -> Result { + // Split the parameters based on the comma delimiter + let params_list: Vec<&str> = vsock.split(',').collect(); + + let mut cid_str: &str = ""; + let mut sock_str: &str = ""; + + for param in params_list.iter() { + if param.starts_with("cid=") { + cid_str = ¶m[4..]; + } else if param.starts_with("sock=") { + sock_str = ¶m[5..]; + } + } + + if sock_str.is_empty() { + return Err(Error::ParseVsockSockParam); + } + + Ok(VsockConfig { + cid: cid_str.parse::().map_err(Error::ParseVsockCidParam)?, + sock: Path::new(sock_str), + }) + } +} + pub struct VmConfig<'a> { pub cpus: CpusConfig, pub memory: MemoryConfig<'a>, @@ -527,6 +564,7 @@ pub struct VmConfig<'a> { pub console: ConsoleConfig<'a>, pub devices: Option>>, pub vhost_user_net: Option>>, + pub vsock: Option>>, } impl<'a> VmConfig<'a> { @@ -591,6 +629,15 @@ impl<'a> VmConfig<'a> { vhost_user_net = Some(vhost_user_net_config_list); } + let mut vsock: Option> = None; + if let Some(vsock_list) = &vm_params.vsock { + let mut vsock_config_list = Vec::new(); + for item in vsock_list.iter() { + vsock_config_list.push(VsockConfig::parse(item)?); + } + vsock = Some(vsock_config_list); + } + Ok(VmConfig { cpus: CpusConfig::parse(vm_params.cpus)?, memory: MemoryConfig::parse(vm_params.memory)?, @@ -605,6 +652,7 @@ impl<'a> VmConfig<'a> { console, devices, vhost_user_net, + vsock, }) } }