vmm: memory_manager: Move the restoration of guest memory later

Rather than filling the guest memory from a file at the point of the the
guest memory region being created instead fill from the file later. This
simplifies the region creation code but also adds flexibility for
sourcing the guest memory from a source other than an on disk file.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2020-10-30 10:26:31 +00:00 committed by Samuel Ortiz
parent 7dcd3aff05
commit cb88ceeae8
2 changed files with 28 additions and 38 deletions

View File

@ -36,7 +36,7 @@ use vm_memory::guest_memory::FileOffset;
use vm_memory::{
mmap::MmapRegionError, Address, Bytes, Error as MmapError, GuestAddress, GuestAddressSpace,
GuestMemory, GuestMemoryAtomic, GuestMemoryError, GuestMemoryLoadGuard, GuestMemoryMmap,
GuestMemoryRegion, GuestRegionMmap, GuestUsize, MemoryRegionAddress, MmapRegion,
GuestMemoryRegion, GuestRegionMmap, GuestUsize, MmapRegion,
};
use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable,
@ -346,7 +346,6 @@ impl MemoryManager {
ram_regions: &[(GuestAddress, usize)],
zones: &[MemoryZoneConfig],
prefault: bool,
saved_regions: Option<Vec<MemoryRegion>>,
) -> Result<(Vec<Arc<GuestRegionMmap>>, MemoryZones), Error> {
let mut zones = zones.to_owned();
let mut mem_regions = Vec::new();
@ -398,7 +397,6 @@ impl MemoryManager {
zone.shared,
zone.hugepages,
zone.host_numa_node,
&saved_regions,
)?;
// Add region to the list of regions associated with the
@ -445,10 +443,32 @@ impl MemoryManager {
Ok((mem_regions, memory_zones))
}
fn fill_saved_regions(&mut self, saved_regions: Vec<MemoryRegion>) -> Result<(), Error> {
for region in saved_regions {
if let Some(content) = region.content {
// Open (read only) the snapshot file for the given region.
let mut memory_region_file = OpenOptions::new()
.read(true)
.open(content)
.map_err(Error::SnapshotOpen)?;
self.guest_memory
.memory()
.read_exact_from(
region.start_addr,
&mut memory_region_file,
region.size as usize,
)
.map_err(Error::SnapshotCopy)?;
}
}
Ok(())
}
pub fn new(
vm: Arc<dyn hypervisor::Vm>,
config: &MemoryConfig,
saved_regions: Option<Vec<MemoryRegion>>,
prefault: bool,
phys_bits: u8,
) -> Result<Arc<Mutex<MemoryManager>>, Error> {
@ -581,7 +601,7 @@ impl MemoryManager {
.collect();
let (mem_regions, mut memory_zones) =
Self::create_memory_regions_from_zones(&ram_regions, &zones, prefault, saved_regions)?;
Self::create_memory_regions_from_zones(&ram_regions, &zones, prefault)?;
let guest_memory =
GuestMemoryMmap::from_arc_regions(mem_regions).map_err(Error::GuestMemory)?;
@ -625,7 +645,6 @@ impl MemoryManager {
zone.shared,
zone.hugepages,
zone.host_numa_node,
&None,
)?;
virtio_mem_regions.push(region.clone());
@ -781,7 +800,9 @@ impl MemoryManager {
}
}
MemoryManager::new(vm, config, Some(saved_regions), prefault, phys_bits)
let mm = MemoryManager::new(vm, config, prefault, phys_bits)?;
mm.lock().unwrap().fill_saved_regions(saved_regions)?;
Ok(mm)
} else {
Err(Error::Restore(MigratableError::Restore(anyhow!(
"Could not find {}-section from snapshot",
@ -837,22 +858,7 @@ impl MemoryManager {
shared: bool,
hugepages: bool,
host_numa_node: Option<u32>,
saved_regions: &Option<Vec<MemoryRegion>>,
) -> Result<Arc<GuestRegionMmap>, Error> {
let mut saved_region_content: Option<PathBuf> = None;
if let Some(saved_regions) = saved_regions {
for saved_region in saved_regions.iter() {
if saved_region.start_addr == start_addr && saved_region.size as usize == size {
saved_region_content = saved_region.content.clone();
// No need to iterate further as we found the saved region
// matching the current region.
break;
}
}
}
let (f, f_off) = match backing_file {
Some(ref file) => {
if file.is_dir() {
@ -921,20 +927,6 @@ impl MemoryManager {
)
.map_err(Error::GuestMemory)?;
// Copy data to the region if needed
if let Some(content) = &saved_region_content {
// Open (read only) the snapshot file for the given region.
let mut memory_region_file = OpenOptions::new()
.read(true)
.open(content)
.map_err(Error::SnapshotOpen)?;
// Fill the region with the file content.
region
.read_exact_from(MemoryRegionAddress(0), &mut memory_region_file, size)
.map_err(Error::SnapshotCopy)?;
}
// Apply NUMA policy if needed.
if let Some(node) = host_numa_node {
let addr = region.deref().as_ptr();
@ -1038,7 +1030,6 @@ impl MemoryManager {
self.shared,
self.hugepages,
None,
&None,
)?;
// Map it into the guest

View File

@ -639,7 +639,6 @@ impl Vm {
let memory_manager = MemoryManager::new(
vm.clone(),
&config.lock().unwrap().memory.clone(),
None,
false,
phys_bits,
)