From 2ad615cd320708f3f8ae12765780b83e7652732f Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Tue, 4 May 2021 16:13:10 +0000 Subject: [PATCH] vmm: Validate config upon hotplug Create a temporary copy of the config, add the new device and validate that. This needs to be done separately to adding it to the config to avoid race conditions that might be result in config changes being overwritten. Fixes: #2564 Signed-off-by: Rob Bradford --- vmm/src/vm.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 636458473..d3ba84efa 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -1253,6 +1253,13 @@ impl Vm { } pub fn add_device(&mut self, mut _device_cfg: DeviceConfig) -> Result { + { + // Validate on a clone of the config + let mut config = self.config.lock().unwrap().clone(); + Self::add_to_config(&mut config.devices, _device_cfg.clone()); + config.validate().map_err(Error::ConfigValidation)?; + } + let pci_device_info = self .device_manager .lock() @@ -1323,6 +1330,13 @@ impl Vm { } pub fn add_disk(&mut self, mut _disk_cfg: DiskConfig) -> Result { + { + // Validate on a clone of the config + let mut config = self.config.lock().unwrap().clone(); + Self::add_to_config(&mut config.disks, _disk_cfg.clone()); + config.validate().map_err(Error::ConfigValidation)?; + } + let pci_device_info = self .device_manager .lock() @@ -1347,6 +1361,13 @@ impl Vm { } pub fn add_fs(&mut self, mut _fs_cfg: FsConfig) -> Result { + { + // Validate on a clone of the config + let mut config = self.config.lock().unwrap().clone(); + Self::add_to_config(&mut config.fs, _fs_cfg.clone()); + config.validate().map_err(Error::ConfigValidation)?; + } + let pci_device_info = self .device_manager .lock() @@ -1371,6 +1392,13 @@ impl Vm { } pub fn add_pmem(&mut self, mut _pmem_cfg: PmemConfig) -> Result { + { + // Validate on a clone of the config + let mut config = self.config.lock().unwrap().clone(); + Self::add_to_config(&mut config.pmem, _pmem_cfg.clone()); + config.validate().map_err(Error::ConfigValidation)?; + } + let pci_device_info = self .device_manager .lock() @@ -1395,6 +1423,13 @@ impl Vm { } pub fn add_net(&mut self, mut _net_cfg: NetConfig) -> Result { + { + // Validate on a clone of the config + let mut config = self.config.lock().unwrap().clone(); + Self::add_to_config(&mut config.net, _net_cfg.clone()); + config.validate().map_err(Error::ConfigValidation)?; + } + let pci_device_info = self .device_manager .lock() @@ -1423,6 +1458,13 @@ impl Vm { return Err(Error::TooManyVsockDevices); } + { + // Validate on a clone of the config + let mut config = self.config.lock().unwrap().clone(); + config.vsock = Some(_vsock_cfg.clone()); + config.validate().map_err(Error::ConfigValidation)?; + } + let pci_device_info = self .device_manager .lock()