From a7c4483b8b2e07947dabfc477b30ba6735a734fb Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Wed, 14 Apr 2021 16:50:29 +0100 Subject: [PATCH] vmm: Directly (de)serialise CpuManager, DeviceManager and MemoryManager state Signed-off-by: Rob Bradford --- vmm/src/cpu.rs | 35 ++++--------------- vmm/src/device_manager.rs | 24 +++---------- vmm/src/memory_manager.rs | 71 ++++++++++++++------------------------- 3 files changed, 36 insertions(+), 94 deletions(-) diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 458b98b67..92dfcfec8 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -365,41 +365,18 @@ impl Snapshottable for Vcpu { } fn snapshot(&mut self) -> std::result::Result { - let snapshot = serde_json::to_vec(&self.saved_state) - .map_err(|e| MigratableError::Snapshot(e.into()))?; - let mut vcpu_snapshot = Snapshot::new(&format!("{}", self.id)); - vcpu_snapshot.add_data_section(SnapshotDataSection { - id: format!("{}-section", VCPU_SNAPSHOT_ID), - snapshot, - }); + vcpu_snapshot.add_data_section(SnapshotDataSection::new_from_state( + VCPU_SNAPSHOT_ID, + &self.saved_state, + )?); Ok(vcpu_snapshot) } fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { - if let Some(vcpu_section) = snapshot - .snapshot_data - .get(&format!("{}-section", VCPU_SNAPSHOT_ID)) - { - let vcpu_state = match serde_json::from_slice(&vcpu_section.snapshot) { - Ok(state) => state, - Err(error) => { - return Err(MigratableError::Restore(anyhow!( - "Could not deserialize the vCPU snapshot {}", - error - ))) - } - }; - - self.saved_state = Some(vcpu_state); - - Ok(()) - } else { - Err(MigratableError::Restore(anyhow!( - "Could not find the vCPU snapshot section" - ))) - } + self.saved_state = Some(snapshot.to_state(VCPU_SNAPSHOT_ID)?); + Ok(()) } } diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 8df956c06..59b35cf0d 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -3869,32 +3869,18 @@ impl Snapshottable for DeviceManager { } // Then we store the DeviceManager state. - snapshot.add_data_section(SnapshotDataSection { - id: format!("{}-section", DEVICE_MANAGER_SNAPSHOT_ID), - snapshot: serde_json::to_vec(&self.state()) - .map_err(|e| MigratableError::Snapshot(e.into()))?, - }); + snapshot.add_data_section(SnapshotDataSection::new_from_state( + DEVICE_MANAGER_SNAPSHOT_ID, + &self.state(), + )?); Ok(snapshot) } fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { // Let's first restore the DeviceManager. - if let Some(device_manager_section) = snapshot - .snapshot_data - .get(&format!("{}-section", DEVICE_MANAGER_SNAPSHOT_ID)) - { - let device_manager_state = serde_json::from_slice(&device_manager_section.snapshot) - .map_err(|e| { - MigratableError::Restore(anyhow!("Could not deserialize DeviceManager {}", e)) - })?; - self.set_state(&device_manager_state); - } else { - return Err(MigratableError::Restore(anyhow!( - "Could not find DeviceManager snapshot section" - ))); - } + 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. diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index d12794a9a..3c6f755ee 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -853,47 +853,30 @@ impl MemoryManager { if let Some(source_url) = source_url { let vm_snapshot_path = url_to_path(source_url).map_err(Error::Restore)?; - if let Some(mem_section) = snapshot - .snapshot_data - .get(&format!("{}-section", MEMORY_MANAGER_SNAPSHOT_ID)) - { - let mem_snapshot: MemoryManagerSnapshotData = - match serde_json::from_slice(&mem_section.snapshot) { - Ok(snapshot) => snapshot, - Err(error) => { - return Err(Error::Restore(MigratableError::Restore(anyhow!( - "Could not deserialize MemoryManager {}", - error - )))) - } - }; + let mem_snapshot: MemoryManagerSnapshotData = snapshot + .to_state(MEMORY_MANAGER_SNAPSHOT_ID) + .map_err(Error::Restore)?; - // Here we turn the content file name into a content file path as - // this will be needed to copy the content of the saved memory - // region into the newly created memory region. - // We simply ignore the content files that are None, as they - // represent regions that have been directly saved by the user, with - // no need for saving into a dedicated external file. For these - // files, the VmConfig already contains the information on where to - // find them. - let mut saved_regions = mem_snapshot.memory_regions; - for region in saved_regions.iter_mut() { - if let Some(content) = &mut region.content { - let mut memory_region_path = vm_snapshot_path.clone(); - memory_region_path.push(content.clone()); - *content = memory_region_path; - } + // Here we turn the content file name into a content file path as + // this will be needed to copy the content of the saved memory + // region into the newly created memory region. + // We simply ignore the content files that are None, as they + // represent regions that have been directly saved by the user, with + // no need for saving into a dedicated external file. For these + // files, the VmConfig already contains the information on where to + // find them. + let mut saved_regions = mem_snapshot.memory_regions; + for region in saved_regions.iter_mut() { + if let Some(content) = &mut region.content { + let mut memory_region_path = vm_snapshot_path.clone(); + memory_region_path.push(content.clone()); + *content = memory_region_path; } - - mm.lock().unwrap().fill_saved_regions(saved_regions)?; - - Ok(mm) - } else { - Err(Error::Restore(MigratableError::Restore(anyhow!( - "Could not find {}-section from snapshot", - MEMORY_MANAGER_SNAPSHOT_ID - )))) } + + mm.lock().unwrap().fill_saved_regions(saved_regions)?; + + Ok(mm) } else { Ok(mm) } @@ -2009,14 +1992,10 @@ impl Snapshottable for MemoryManager { // memory region content for the regions requiring it. self.snapshot_memory_regions = memory_regions.clone(); - let snapshot_data_section = - serde_json::to_vec(&MemoryManagerSnapshotData { memory_regions }) - .map_err(|e| MigratableError::Snapshot(e.into()))?; - - memory_manager_snapshot.add_data_section(SnapshotDataSection { - id: format!("{}-section", MEMORY_MANAGER_SNAPSHOT_ID), - snapshot: snapshot_data_section, - }); + memory_manager_snapshot.add_data_section(SnapshotDataSection::new_from_state( + MEMORY_MANAGER_SNAPSHOT_ID, + &MemoryManagerSnapshotData { memory_regions }, + )?); let mut memory_snapshot = self.snapshot.lock().unwrap(); *memory_snapshot = Some(guest_memory);