vmm: support removing devices before VM is booted

If the VM has been configured but not yet booted, all we need to do to
support removing a device is to remove it from the config, so it will
never be created.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
This commit is contained in:
Alyssa Ross
2023-07-10 08:53:34 +00:00
committed by Bo Chen
parent 87d81dd2b1
commit 69bd0036d9
3 changed files with 76 additions and 45 deletions
+63
View File
@@ -2101,6 +2101,69 @@ impl VmConfig {
Ok(config)
}
pub fn remove_device(&mut self, id: &str) -> bool {
let mut removed = false;
// Remove if VFIO device
if let Some(devices) = self.devices.as_mut() {
let len = devices.len();
devices.retain(|dev| dev.id.as_ref().map(|id| id.as_ref()) != Some(id));
removed |= devices.len() != len;
}
// Remove if VFIO user device
if let Some(user_devices) = self.user_devices.as_mut() {
let len = user_devices.len();
user_devices.retain(|dev| dev.id.as_ref().map(|id| id.as_ref()) != Some(id));
removed |= user_devices.len() != len;
}
// Remove if disk device
if let Some(disks) = self.disks.as_mut() {
let len = disks.len();
disks.retain(|dev| dev.id.as_ref().map(|id| id.as_ref()) != Some(id));
removed |= disks.len() != len;
}
// Remove if fs device
if let Some(fs) = self.fs.as_mut() {
let len = fs.len();
fs.retain(|dev| dev.id.as_ref().map(|id| id.as_ref()) != Some(id));
removed |= fs.len() != len;
}
// Remove if net device
if let Some(net) = self.net.as_mut() {
let len = net.len();
net.retain(|dev| dev.id.as_ref().map(|id| id.as_ref()) != Some(id));
removed |= net.len() != len;
}
// Remove if pmem device
if let Some(pmem) = self.pmem.as_mut() {
let len = pmem.len();
pmem.retain(|dev| dev.id.as_ref().map(|id| id.as_ref()) != Some(id));
removed |= pmem.len() != len;
}
// Remove if vDPA device
if let Some(vdpa) = self.vdpa.as_mut() {
let len = vdpa.len();
vdpa.retain(|dev| dev.id.as_ref().map(|id| id.as_ref()) != Some(id));
removed |= vdpa.len() != len;
}
// Remove if vsock device
if let Some(vsock) = self.vsock.as_ref() {
if vsock.id.as_ref().map(|id| id.as_ref()) == Some(id) {
self.vsock = None;
removed = true;
}
}
removed
}
/// # Safety
/// To use this safely, the caller must guarantee that the input
/// fds are all valid.