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 <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2019-09-04 10:39:17 -07:00
parent c48ca61417
commit 11e7ece9f5
2 changed files with 60 additions and 0 deletions

View File

@ -165,6 +165,16 @@ fn main() {
.takes_value(true)
.min_values(1),
)
.arg(
Arg::with_name("vsock")
.long("vsock")
.help(
"Virtio VSOCK parameters \"cid=<context_id>,\
sock=<socket_path>\"",
)
.takes_value(true)
.min_values(1),
)
.arg(
Arg::with_name("v")
.short("v")
@ -200,6 +210,7 @@ fn main() {
let vhost_user_net: Option<Vec<&str>> = cmd_arguments
.values_of("vhost-user-net")
.map(|x| x.collect());
let vsock: Option<Vec<&str>> = 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) => {

View File

@ -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<T, Error<'a>>;
@ -88,6 +92,7 @@ pub struct VmParams<'a> {
pub console: &'a str,
pub devices: Option<Vec<&'a str>>,
pub vhost_user_net: Option<Vec<&'a str>>,
pub vsock: Option<Vec<&'a str>>,
}
fn parse_size(size: &str) -> Result<u64> {
@ -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<Self> {
// 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 = &param[4..];
} else if param.starts_with("sock=") {
sock_str = &param[5..];
}
}
if sock_str.is_empty() {
return Err(Error::ParseVsockSockParam);
}
Ok(VsockConfig {
cid: cid_str.parse::<u64>().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<Vec<DeviceConfig<'a>>>,
pub vhost_user_net: Option<Vec<VhostUserNetConfig<'a>>>,
pub vsock: Option<Vec<VsockConfig<'a>>>,
}
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<Vec<VsockConfig>> = 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,
})
}
}