vmm: Create initial VM from its snapshot

The MemoryManager is somehow a special case, as its restore() function
was not implemented as part of the Snapshottable trait. Instead, and
because restoring memory regions rely both on vm.json and every memory
region snapshot file, the memory manager is restored at creation time.
This makes the restore path slightly different from CpuManager, Vcpu,
DeviceManager and Vm, but achieve the correct restoration of the
MemoryManager along with its memory regions filled with the correct
content.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Samuel Ortiz
2020-03-17 00:48:12 +01:00
committed by Sebastien Boeuf
parent b55b83c6e8
commit 2cd0bc0a2c
2 changed files with 100 additions and 2 deletions
+38 -1
View File
@@ -29,7 +29,7 @@ use crate::config::{DeviceConfig, DiskConfig, HotplugMethod, NetConfig, PmemConf
use crate::cpu;
use crate::device_manager::{get_win_size, Console, DeviceManager, DeviceManagerError};
use crate::memory_manager::{Error as MemoryManagerError, MemoryManager};
use crate::migration::{url_to_path, VM_SNAPSHOT_FILE};
use crate::migration::{url_to_path, vm_config_from_snapshot, VM_SNAPSHOT_FILE};
use crate::{CPU_MANAGER_SNAPSHOT_ID, DEVICE_MANAGER_SNAPSHOT_ID, MEMORY_MANAGER_SNAPSHOT_ID};
use anyhow::anyhow;
use arch::{BootProtocol, EntryPoint};
@@ -374,6 +374,43 @@ impl Vm {
)
}
pub fn new_from_snapshot(
snapshot: &Snapshot,
exit_evt: EventFd,
reset_evt: EventFd,
vmm_path: PathBuf,
source_url: &str,
) -> Result<Self> {
let (kvm, fd) = Vm::kvm_new()?;
let config = vm_config_from_snapshot(snapshot).map_err(Error::Restore)?;
let memory_manager = if let Some(memory_manager_snapshot) =
snapshot.snapshots.get(MEMORY_MANAGER_SNAPSHOT_ID)
{
MemoryManager::new_from_snapshot(
memory_manager_snapshot,
fd.clone(),
&config.lock().unwrap().memory.clone(),
source_url,
)
.map_err(Error::MemoryManager)?
} else {
return Err(Error::Restore(MigratableError::Restore(anyhow!(
"Missing memory manager snapshot"
))));
};
Vm::new_from_memory_manager(
config,
memory_manager,
fd,
kvm,
exit_evt,
reset_evt,
vmm_path,
)
}
fn load_initramfs(&mut self, guest_mem: &GuestMemoryMmap) -> Result<arch::InitramfsConfig> {
let mut initramfs = self.initramfs.as_ref().unwrap();
let size: usize = initramfs