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 <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2019-11-25 14:18:03 +00:00
parent 7543e00a07
commit 82bc07cce4
3 changed files with 52 additions and 9 deletions

View File

@ -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,

View File

@ -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<bool> {
#[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<Self> {
Ok(CpusConfig {
cpu_count: cpus.parse().map_err(Error::ParseCpusParams)?,
})
if let Ok(legacy_vcpu_count) = cpus.parse::<u8>() {
error!("Using deprecated vCPU syntax. Use --cpus boot=<boot_vcpus>[,max=<max_vcpus]");
Ok(CpusConfig {
boot_vcpus: legacy_vcpu_count,
max_vcpus: legacy_vcpu_count,
})
} else {
// Split the parameters based on the comma delimiter
let params_list: Vec<&str> = 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 = &param["boot=".len()..];
} else if param.starts_with("max=") {
max_str = &param["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,
}
}
}

View File

@ -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,