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, }) } }