From 8d9d22436a5e586cfd0526ca1d7d7cbf1b4c8f3a Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Tue, 7 Apr 2020 15:54:33 +0200 Subject: [PATCH] vmm: Add "prefault" option when restoring Now that the restore path uses RestoreConfig structure, we add a new parameter called "prefault" to it. This will give the user the ability to populate the pages corresponding to the mapped regions backed by the snapshotted memory files. Signed-off-by: Sebastien Boeuf --- vmm/src/config.rs | 19 +++++++++++++++---- vmm/src/lib.rs | 1 + vmm/src/memory_manager.rs | 3 ++- vmm/src/vm.rs | 2 ++ 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/vmm/src/config.rs b/vmm/src/config.rs index a50005c2b..e267583ea 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -1117,23 +1117,34 @@ impl VsockConfig { #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct RestoreConfig { pub source_url: PathBuf, + #[serde(default)] + pub prefault: bool, } impl RestoreConfig { pub const SYNTAX: &'static str = "Restore from a VM snapshot. \ - Restore parameters \"source_url=\" \ - source_url should be a valid URL (e.g file:///foo/bar or tcp://192.168.1.10/foo)"; + \nRestore parameters \"source_url=,prefault=on|off\" \ + \n`source_url` should be a valid URL (e.g file:///foo/bar or tcp://192.168.1.10/foo) \ + \n`prefault` brings memory pages in when enabled (disabled by default)"; pub fn parse(restore: &str) -> Result { let mut parser = OptionParser::new(); - parser.add("source_url"); + parser.add("source_url").add("prefault"); parser.parse(restore).map_err(Error::ParseRestore)?; let source_url = parser .get("source_url") .map(PathBuf::from) .ok_or(Error::ParseRestoreSourceUrlMissing)?; + let prefault = parser + .convert::("prefault") + .map_err(Error::ParseRestore)? + .unwrap_or(Toggle(false)) + .0; - Ok(RestoreConfig { source_url }) + Ok(RestoreConfig { + source_url, + prefault, + }) } } diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 9a6426581..85e0032ee 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -331,6 +331,7 @@ impl Vmm { reset_evt, self.vmm_path.clone(), source_url, + restore_cfg.prefault, )?; self.vm = Some(vm); diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index 544a50081..ab8a55e83 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -387,6 +387,7 @@ impl MemoryManager { fd: Arc, config: &MemoryConfig, source_url: &str, + prefault: bool, ) -> Result>, Error> { let url = Url::parse(source_url).unwrap(); /* url must be valid dir which is verified in recv_vm_snapshot() */ @@ -419,7 +420,7 @@ impl MemoryManager { // allows for a faster VM restoration and does not require us to // fill the memory content, hence we can return right away. if config.file.is_none() { - return MemoryManager::new(fd, config, Some(ext_regions), false); + return MemoryManager::new(fd, config, Some(ext_regions), prefault); }; let memory_manager = MemoryManager::new(fd, config, None, false)?; diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 7e0555a5f..cef1a4c7b 100755 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -388,6 +388,7 @@ impl Vm { reset_evt: EventFd, vmm_path: PathBuf, source_url: &str, + prefault: bool, ) -> Result { let (kvm, fd) = Vm::kvm_new()?; let config = vm_config_from_snapshot(snapshot).map_err(Error::Restore)?; @@ -400,6 +401,7 @@ impl Vm { fd.clone(), &config.lock().unwrap().memory.clone(), source_url, + prefault, ) .map_err(Error::MemoryManager)? } else {