diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index c08ec9e28..c2fb3e9e6 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -36,7 +36,6 @@ use serde::{Deserialize, Serialize}; use signal_hook::iterator::{Handle, Signals}; use thiserror::Error; use tracer::trace_scoped; -use vm_memory::ReadVolatile; use vm_memory::bitmap::AtomicBitmap; use vm_migration::protocol::*; use vm_migration::{ @@ -1056,21 +1055,16 @@ impl Vmm { Ok(()) } - fn vm_receive_memory( + fn vm_receive_memory( &mut self, req: &Request, - socket: &mut T, + socket: &mut SocketStream, memory_manager: &mut MemoryManager, - ) -> std::result::Result<(), MigratableError> - where - T: Read + ReadVolatile, - { - // Read table + ) -> std::result::Result<(), MigratableError> { let table = MemoryRangeTable::read_from(socket, req.length())?; - // And then read the memory itself - memory_manager.receive_memory_regions(&table, socket)?; - Ok(()) + // And then the memory itself + migration_transport::receive_memory_ranges(&memory_manager.guest_memory(), &table, socket) } /// Performs the initial memory transmission (iteration zero) plus a diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index c8f64b15a..62b4522cc 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -39,7 +39,7 @@ use vm_memory::guest_memory::{Error as MmapError, FileOffset}; use vm_memory::mmap::MmapRegionError; use vm_memory::{ Address, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic, - GuestMemoryError, GuestMemoryRegion, GuestUsize, MmapRegion, ReadVolatile, + GuestMemoryError, GuestMemoryRegion, GuestUsize, MmapRegion, }; use vm_migration::protocol::{MemoryRange, MemoryRangeTable}; use vm_migration::{ @@ -2572,47 +2572,6 @@ impl MemoryManager { debug!("coredump total bytes {total_bytes}"); Ok(()) } - - pub fn receive_memory_regions( - &mut self, - ranges: &MemoryRangeTable, - fd: &mut F, - ) -> std::result::Result<(), MigratableError> - where - F: ReadVolatile, - { - let guest_memory = self.guest_memory(); - let mem = guest_memory.memory(); - - for range in ranges.regions() { - let mut offset: u64 = 0; - // Here we are manually handling the retry in case we can't the - // whole region at once because we can't use the implementation - // from vm-memory::GuestMemory of read_exact_from() as it is not - // following the correct behavior. For more info about this issue - // see: https://github.com/rust-vmm/vm-memory/issues/174 - loop { - let bytes_read = mem - .read_volatile_from( - GuestAddress(range.gpa + offset), - fd, - (range.length - offset) as usize, - ) - .map_err(|e| { - MigratableError::MigrateReceive(anyhow!( - "Error receiving memory from socket: {e}" - )) - })?; - offset += bytes_read as u64; - - if offset == range.length { - break; - } - } - } - - Ok(()) - } } struct MemoryNotify { diff --git a/vmm/src/migration_transport.rs b/vmm/src/migration_transport.rs index 168d718be..12412b0a0 100644 --- a/vmm/src/migration_transport.rs +++ b/vmm/src/migration_transport.rs @@ -278,3 +278,41 @@ pub(crate) fn send_memory_ranges( MigratableError::MigrateSend(anyhow!("Error during dirty memory migration")), ) } + +/// Receive memory contents for the given range table into guest memory. +pub(crate) fn receive_memory_ranges( + guest_memory: &GuestMemoryAtomic, + ranges: &MemoryRangeTable, + socket: &mut SocketStream, +) -> Result<(), MigratableError> { + let mem = guest_memory.memory(); + + for range in ranges.regions() { + let mut offset: u64 = 0; + // Here we are manually handling the retry in case we can't read the + // whole region at once because we can't use the implementation + // from vm-memory::GuestMemory of read_exact_from() as it is not + // following the correct behavior. For more info about this issue + // see: https://github.com/rust-vmm/vm-memory/issues/174 + loop { + let bytes_read = mem + .read_volatile_from( + GuestAddress(range.gpa + offset), + socket, + (range.length - offset) as usize, + ) + .map_err(|e| { + MigratableError::MigrateReceive(anyhow!( + "Error receiving memory from socket: {e}" + )) + })?; + offset += bytes_read as u64; + + if offset == range.length { + break; + } + } + } + + Ok(()) +}