mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-03-20 07:58:55 +00:00
vmm: Directly (de)serialise CpuManager, DeviceManager and MemoryManager state
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
85f7913bb3
commit
a7c4483b8b
@ -365,41 +365,18 @@ impl Snapshottable for Vcpu {
|
||||
}
|
||||
|
||||
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user