From adf297066da060750523f030e943a42df77cb732 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Wed, 29 Apr 2020 11:09:04 +0200 Subject: [PATCH] vmm: Create devices in different path if restoring the VM In case the VM is created from scratch, the devices should be created after the DeviceManager has been created. But this should not affect the restore codepath, as in this case the devices should be created as part of the restore() function. It's necessary to perform this differentiation as the restore must go through the following steps: - Create the DeviceManager - Restore the DeviceManager with the right state - Create the devices based on the restored DeviceManager's device tree - Restore each device based on the restored DeviceManager's device tree That's why this patch leverages the recent split of the DeviceManager's creation to achieve what's needed. Signed-off-by: Sebastien Boeuf --- vmm/src/device_manager.rs | 7 ++++++- vmm/src/vm.rs | 20 ++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 53acc7df1..3dfbe1239 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -2855,7 +2855,12 @@ impl Snapshottable for DeviceManager { ))); } - // Then restore all devices associated with the DeviceManager. + // Now that DeviceManager is updated with the right states, it's time + // to create the devices based on the configuration. + self.create_devices() + .map_err(|e| MigratableError::Restore(anyhow!("Could not create devices {:?}", e)))?; + + // Finally, restore all devices associated with the DeviceManager. // It's important to restore devices in the right order, that's why // the device tree is the right way to ensure we restore a child before // its parent node. diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 6e1ce9e13..a739e180f 100755 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -334,12 +334,6 @@ impl Vm { ) .map_err(Error::DeviceManager)?; - device_manager - .lock() - .unwrap() - .create_devices() - .map_err(Error::DeviceManager)?; - let cpu_manager = cpu::CpuManager::new( &config.lock().unwrap().cpus.clone(), &device_manager, @@ -392,7 +386,7 @@ impl Vm { ) .map_err(Error::MemoryManager)?; - Vm::new_from_memory_manager( + let vm = Vm::new_from_memory_manager( config, memory_manager, fd, @@ -400,7 +394,17 @@ impl Vm { exit_evt, reset_evt, vmm_path, - ) + )?; + + // The device manager must create the devices from here as it is part + // of the regular code path creating everything from scratch. + vm.device_manager + .lock() + .unwrap() + .create_devices() + .map_err(Error::DeviceManager)?; + + Ok(vm) } pub fn new_from_snapshot(