libs/kata-types: adjust default_vcpus correctly

With default_maxvcpus = 0 and default_vcpus = 1 settings, the
default_vcpus will be set to 0 and leads to starting fail.

The default_maxvcpus is not set correctly when it is set to 0,
and the default_vcpus is set to 0.

The correct action is setting default_maxvcpus to the max number
of CPUs or MAX_DRAGONBALL_VCPUS, and the default_vcpus should be
set to the desired value if the valuse is between 0 and
default_maxvcpus.

Fixes: #5110

Signed-off-by: Bin Liu <bin@hyper.sh>
This commit is contained in:
Bin Liu 2022-09-06 10:29:32 +08:00
parent dd34540b8a
commit 53f209af44

View File

@ -301,34 +301,38 @@ 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<()> {
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 {
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(())
}
}
@ -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
);
}
}
}