diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 377a49a2f..b56015974 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -972,7 +972,15 @@ impl DeviceManager { ) -> DeviceManagerResult>> { trace_scoped!("DeviceManager::new"); - let device_tree = Arc::new(Mutex::new(DeviceTree::new())); + let (device_tree, device_id_cnt) = if let Some(snapshot) = snapshot.as_ref() { + let state: DeviceManagerState = snapshot.to_state(DEVICE_MANAGER_SNAPSHOT_ID).unwrap(); + ( + Arc::new(Mutex::new(state.device_tree.clone())), + state.device_id_cnt, + ) + } else { + (Arc::new(Mutex::new(DeviceTree::new())), Wrapping(0)) + }; let num_pci_segments = if let Some(platform_config) = config.lock().unwrap().platform.as_ref() { @@ -1081,7 +1089,7 @@ impl DeviceManager { cpu_manager, virtio_devices: Vec::new(), bus_devices: Vec::new(), - device_id_cnt: Wrapping(0), + device_id_cnt, msi_interrupt_manager, legacy_interrupt_manager: None, passthrough_device: None, @@ -1240,11 +1248,6 @@ impl DeviceManager { } } - fn set_state(&mut self, state: &DeviceManagerState) { - *self.device_tree.lock().unwrap() = state.device_tree.clone(); - self.device_id_cnt = state.device_id_cnt; - } - fn get_msi_iova_space(&mut self) -> (u64, u64) { #[cfg(target_arch = "aarch64")] { @@ -4116,38 +4119,6 @@ impl DeviceManager { self.device_tree.clone() } - pub fn restore_devices( - &mut self, - snapshot: Snapshot, - ) -> std::result::Result<(), MigratableError> { - // 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. - for node in self - .device_tree - .lock() - .unwrap() - .breadth_first_traversal() - .rev() - { - // Restore the node - if let Some(migratable) = &node.migratable { - info!("Restoring {} from DeviceManager", node.id); - if let Some(snapshot) = snapshot.snapshots.get(&node.id) { - migratable.lock().unwrap().restore(*snapshot.clone())?; - } else { - return Err(MigratableError::Restore(anyhow!( - "Missing device {}", - node.id - ))); - } - } - } - - Ok(()) - } - #[cfg(target_arch = "x86_64")] pub fn notify_power_button(&self) -> DeviceManagerResult<()> { self.ged_notification_device @@ -4474,19 +4445,6 @@ impl Snapshottable for DeviceManager { Ok(snapshot) } - - fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { - // Let's first restore the DeviceManager. - - self.set_state(&snapshot.to_state(DEVICE_MANAGER_SNAPSHOT_ID)?); - - // Now that DeviceManager is updated with the right states, it's time - // to create the devices based on the configuration. - self.create_devices(None, None, None) - .map_err(|e| MigratableError::Restore(anyhow!("Could not create devices {:?}", e)))?; - - Ok(()) - } } impl Transportable for DeviceManager {} diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index e9be2725a..26008c98b 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -2610,7 +2610,7 @@ impl Snapshottable for Vm { Ok(vm_snapshot) } - fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { + fn restore(&mut self, _snapshot: Snapshot) -> std::result::Result<(), MigratableError> { event!("vm", "restoring"); let current_state = self @@ -2622,33 +2622,17 @@ impl Snapshottable for Vm { })?; #[cfg(all(feature = "kvm", target_arch = "x86_64"))] - self.load_clock_from_snapshot(&snapshot) + self.load_clock_from_snapshot(&_snapshot) .map_err(|e| MigratableError::Restore(anyhow!("Error restoring clock: {:?}", e)))?; - if let Some(device_manager_snapshot) = snapshot.snapshots.get(DEVICE_MANAGER_SNAPSHOT_ID) { - self.device_manager - .lock() - .unwrap() - .restore(*device_manager_snapshot.clone())?; - } else { - return Err(MigratableError::Restore(anyhow!( - "Missing device manager snapshot" - ))); - } + self.device_manager + .lock() + .unwrap() + .create_devices(None, None, None) + .map_err(|e| MigratableError::Restore(anyhow!("Error restoring devices: {:#?}", e)))?; #[cfg(target_arch = "aarch64")] - self.restore_vgic_and_enable_interrupt(&snapshot)?; - - if let Some(device_manager_snapshot) = snapshot.snapshots.get(DEVICE_MANAGER_SNAPSHOT_ID) { - self.device_manager - .lock() - .unwrap() - .restore_devices(*device_manager_snapshot.clone())?; - } else { - return Err(MigratableError::Restore(anyhow!( - "Missing device manager snapshot" - ))); - } + self.restore_vgic_and_enable_interrupt(&_snapshot)?; // Now we can start all vCPUs from here. self.cpu_manager