From 82bc07cce473d700d9ba9e83ad2a8e2c9d8748d6 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Mon, 25 Nov 2019 14:18:03 +0000 Subject: [PATCH] vmm: Add boot and max vCPU handling to command line parser Also retain support (with a warning for the old behaviour.) Signed-off-by: Rob Bradford --- src/main.rs | 5 +++-- vmm/src/config.rs | 52 ++++++++++++++++++++++++++++++++++++++++++----- vmm/src/vm.rs | 4 ++-- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 4910c60e6..9edb10e94 100755 --- a/src/main.rs +++ b/src/main.rs @@ -346,7 +346,7 @@ fn main() { "Cloud Hypervisor Guest\n\tAPI server: {}\n\tvCPUs: {}\n\tMemory: {} MB\ \n\tKernel: {:?}\n\tKernel cmdline: {}\n\tDisk(s): {:?}", api_socket_path, - vm_config.cpus.cpu_count, + vm_config.cpus.boot_vcpus, vm_config.memory.size >> 20, vm_config.kernel, vm_config.cmdline.args.as_str(), @@ -923,7 +923,8 @@ mod tests { } fn api_create_body(&self, cpu_count: u8) -> String { - format! {"{{\"cpus\":{{\"cpu_count\":{}}},\"kernel\":{{\"path\":\"{}\"}},\"cmdline\":{{\"args\": \"\"}},\"net\":[{{\"ip\":\"{}\", \"mask\":\"255.255.255.0\", \"mac\":\"{}\"}}], \"disks\":[{{\"path\":\"{}\"}}, {{\"path\":\"{}\"}}]}}", + format! {"{{\"cpus\":{{\"boot_vcpus\":{},\"max_vcpus\":{}}},\"kernel\":{{\"path\":\"{}\"}},\"cmdline\":{{\"args\": \"\"}},\"net\":[{{\"ip\":\"{}\", \"mask\":\"255.255.255.0\", \"mac\":\"{}\"}}], \"disks\":[{{\"path\":\"{}\"}}, {{\"path\":\"{}\"}}]}}", + cpu_count, cpu_count, self.fw_path.as_str(), self.network.host_ip, diff --git a/vmm/src/config.rs b/vmm/src/config.rs index aab40ed0f..0ed5d90f4 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -21,6 +21,10 @@ pub const DEFAULT_RNG_SOURCE: &str = "/dev/urandom"; pub enum Error<'a> { /// Failed parsing cpus parameters. ParseCpusParams(std::num::ParseIntError), + /// Unexpected vCPU parameter + ParseCpusUnknownParam, + /// Max is less than boot + ParseCpusMaxLowerThanBoot, /// Failed parsing memory file parameter. ParseMemoryFileParam, /// Failed parsing kernel parameters. @@ -132,21 +136,59 @@ fn parse_on_off(param: &str) -> Result { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct CpusConfig { - pub cpu_count: u8, + pub boot_vcpus: u8, + pub max_vcpus: u8, } impl CpusConfig { pub fn parse(cpus: &str) -> Result { - Ok(CpusConfig { - cpu_count: cpus.parse().map_err(Error::ParseCpusParams)?, - }) + if let Ok(legacy_vcpu_count) = cpus.parse::() { + error!("Using deprecated vCPU syntax. Use --cpus boot=[,max= = cpus.split(',').collect(); + + let mut boot_str: &str = ""; + let mut max_str: &str = ""; + + for param in params_list.iter() { + if param.starts_with("boot=") { + boot_str = ¶m["boot=".len()..]; + } else if param.starts_with("max=") { + max_str = ¶m["max=".len()..]; + } else { + return Err(Error::ParseCpusUnknownParam); + } + } + + let boot_vcpus: u8 = boot_str.parse().map_err(Error::ParseCpusParams)?; + let max_vcpus = if max_str != "" { + max_str.parse().map_err(Error::ParseCpusParams)? + } else { + boot_vcpus + }; + + if max_vcpus < boot_vcpus { + return Err(Error::ParseCpusMaxLowerThanBoot); + } + + Ok(CpusConfig { + boot_vcpus, + max_vcpus, + }) + } } } impl Default for CpusConfig { fn default() -> Self { CpusConfig { - cpu_count: DEFAULT_VCPUS, + boot_vcpus: DEFAULT_VCPUS, + max_vcpus: DEFAULT_VCPUS, } } } diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 77286a02c..8571803d4 100755 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -450,8 +450,8 @@ impl Vm { let on_tty = unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0; - let boot_vcpus = config.cpus.cpu_count; - let max_vcpus = config.cpus.cpu_count; + let boot_vcpus = config.cpus.boot_vcpus; + let max_vcpus = config.cpus.max_vcpus; let cpu_manager = cpu::CpuManager::new( boot_vcpus, max_vcpus,