diff --git a/src/libs/kata-types/src/config/hypervisor/mod.rs b/src/libs/kata-types/src/config/hypervisor/mod.rs index d749b73df..ae7acb135 100644 --- a/src/libs/kata-types/src/config/hypervisor/mod.rs +++ b/src/libs/kata-types/src/config/hypervisor/mod.rs @@ -301,35 +301,39 @@ impl CpuInfo { pub fn adjust_config(&mut self) -> Result<()> { let features: Vec<&str> = self.cpu_features.split(',').map(|v| v.trim()).collect(); self.cpu_features = features.join(","); + + let cpus = num_cpus::get() as u32; + + // adjust default_maxvcpus + if self.default_maxvcpus == 0 || self.default_maxvcpus > cpus { + self.default_maxvcpus = cpus; + } + + // adjust default_vcpus + if self.default_vcpus < 0 || self.default_vcpus as u32 > cpus { + self.default_vcpus = cpus as i32; + } else if self.default_vcpus == 0 { + self.default_vcpus = default::DEFAULT_GUEST_VCPUS as i32; + } + + if self.default_vcpus > self.default_maxvcpus as i32 { + self.default_vcpus = self.default_maxvcpus as i32; + } + Ok(()) } /// Validate the configuration information. pub fn validate(&self) -> Result<()> { + if self.default_vcpus > self.default_maxvcpus as i32 { + return Err(eother!( + "The default_vcpus({}) is greater than default_maxvcpus({})", + self.default_vcpus, + self.default_maxvcpus + )); + } Ok(()) } - - /// Get default number of guest vCPUs. - pub fn get_default_vcpus(&self) -> u32 { - let cpus = num_cpus::get() as u32; - if self.default_vcpus < 0 || self.default_vcpus as u32 > cpus { - cpus - } else if self.default_vcpus == 0 { - default::DEFAULT_GUEST_VCPUS - } else { - self.default_vcpus as u32 - } - } - - /// Get default maximal number of guest vCPUs. - pub fn get_default_max_vcpus(&self) -> u32 { - let cpus = num_cpus::get() as u32; - if self.default_maxvcpus == 0 || self.default_maxvcpus > cpus { - cpus - } else { - self.default_maxvcpus - } - } } /// Configuration information for debug @@ -1106,4 +1110,80 @@ mod tests { String::from("boo=far a b=c foo bar baz=faz") ); } + + #[test] + fn test_cpu_info_adjust_config() { + // get CPU cores of the test node + let node_cpus = num_cpus::get() as u32; + let default_vcpus = default::DEFAULT_GUEST_VCPUS as i32; + + struct TestData<'a> { + desc: &'a str, + input: &'a mut CpuInfo, + output: CpuInfo, + } + + let tests = &mut [ + TestData { + desc: "all with default values", + input: &mut CpuInfo { + cpu_features: "".to_string(), + default_vcpus: 0, + default_maxvcpus: 0, + }, + output: CpuInfo { + cpu_features: "".to_string(), + default_vcpus: default_vcpus as i32, + default_maxvcpus: node_cpus, + }, + }, + TestData { + desc: "all with big values", + input: &mut CpuInfo { + cpu_features: "a,b,c".to_string(), + default_vcpus: 9999999, + default_maxvcpus: 9999999, + }, + output: CpuInfo { + cpu_features: "a,b,c".to_string(), + default_vcpus: node_cpus as i32, + default_maxvcpus: node_cpus, + }, + }, + TestData { + desc: "default_vcpus lager than default_maxvcpus", + input: &mut CpuInfo { + cpu_features: "a, b ,c".to_string(), + default_vcpus: -1, + default_maxvcpus: 1, + }, + output: CpuInfo { + cpu_features: "a,b,c".to_string(), + default_vcpus: 1, + default_maxvcpus: 1, + }, + }, + ]; + + for (_, tc) in tests.iter_mut().enumerate() { + // we can ensure that unwrap will not panic + tc.input.adjust_config().unwrap(); + + assert_eq!( + tc.input.cpu_features, tc.output.cpu_features, + "test[{}] cpu_features", + tc.desc + ); + assert_eq!( + tc.input.default_vcpus, tc.output.default_vcpus, + "test[{}] default_vcpus", + tc.desc + ); + assert_eq!( + tc.input.default_maxvcpus, tc.output.default_maxvcpus, + "test[{}] default_maxvcpus", + tc.desc + ); + } + } }