fn dump_dirty<T: std::io::Write + std::io::Seek>(
        &self,
        writer: &mut T,
        dirty_bitmap: &DirtyBitmap,
    ) -> std::result::Result<(), Error> {
        let mut writer_offset = 0;
        let page_size = get_page_size().map_err(Error::PageSize)?;

        self.iter()
            .enumerate()
            .try_for_each(|(slot, region)| {
                let kvm_bitmap = dirty_bitmap.get(&slot).unwrap();
                let firecracker_bitmap = region.bitmap();
                let mut write_size = 0;
                let mut dirty_batch_start: u64 = 0;

                for (i, v) in kvm_bitmap.iter().enumerate() {
                    for j in 0..64 {
                        let is_kvm_page_dirty = ((v >> j) & 1u64) != 0u64;
                        let page_offset = ((i * 64) + j) * page_size;
                        let is_firecracker_page_dirty = firecracker_bitmap.dirty_at(page_offset);
                        if is_kvm_page_dirty || is_firecracker_page_dirty {
                            // We are at the start of a new batch of dirty pages.
                            if write_size == 0 {
                                // Seek forward over the unmodified pages.
                                writer
                                    .seek(SeekFrom::Start(writer_offset + page_offset as u64))
                                    .unwrap();
                                dirty_batch_start = page_offset as u64;
                            }
                            write_size += page_size;
                        } else if write_size > 0 {
                            // We are at the end of a batch of dirty pages.
                            region.write_all_to(
                                MemoryRegionAddress(dirty_batch_start),
                                writer,
                                write_size,
                            )?;
                            write_size = 0;
                        }
                    }
                }

                if write_size > 0 {
                    region.write_all_to(
                        MemoryRegionAddress(dirty_batch_start),
                        writer,
                        write_size,
                    )?;
                }
                writer_offset += region.len();
                if let Some(bitmap) = firecracker_bitmap {
                    bitmap.reset();
                }

                Ok(())
            })
            .map_err(Error::WriteMemory)
    }
/// Dumps all pages of GuestMemoryMmap present in `dirty_bitmap` to a writer.
Dumps all pages of GuestMemoryMmap present in `dirty_bitmap` to a writer.
Dumps all pages of GuestMemoryMmap present in ` dirty_bitmap ` to a writer .
fn dump_dirty<T: std::io::Write + std::io::Seek>(
        &self,
        writer: &mut T,
        dirty_bitmap: &DirtyBitmap,
    ) -> std::result::Result<(), Error> {
        let mut writer_offset = 0;
        let page_size = get_page_size().map_err(Error::PageSize)?;
        self.iter()
            .enumerate()
            .try_for_each(|(slot, region)| {
                let kvm_bitmap = dirty_bitmap.get(&slot).unwrap();
                let firecracker_bitmap = region.bitmap();
                let mut write_size = 0;
                let mut dirty_batch_start: u64 = 0;
                for (i, v) in kvm_bitmap.iter().enumerate() {
                    for j in 0..64 {
                        let is_kvm_page_dirty = ((v >> j) & 1u64) != 0u64;
                        let page_offset = ((i * 64) + j) * page_size;
                        let is_firecracker_page_dirty = firecracker_bitmap.dirty_at(page_offset);
                        if is_kvm_page_dirty || is_firecracker_page_dirty {
                            // We are at the start of a new batch of dirty pages.
                            if write_size == 0 {
                                // Seek forward over the unmodified pages.
                                writer
                                    .seek(SeekFrom::Start(writer_offset + page_offset as u64))
                                    .unwrap();
                                dirty_batch_start = page_offset as u64;
                            }
                            write_size += page_size;
                        } else if write_size > 0 {
                            // We are at the end of a batch of dirty pages.
                            region.write_all_to(
                                MemoryRegionAddress(dirty_batch_start),
                                writer,
                                write_size,
                            )?;
                            write_size = 0;
                        }
                    }
                }
                if write_size > 0 {
                    region.write_all_to(
                        MemoryRegionAddress(dirty_batch_start),
                        writer,
                        write_size,
                    )?;
                }
                writer_offset += region.len();
                if let Some(bitmap) = firecracker_bitmap {
                    bitmap.reset();
                }
                Ok(())
            })
            .map_err(Error::WriteMemory)
    }
fn dump_dirty < T : std :: io :: Write + std :: io :: Seek > ( & self , writer : & mut T , dirty_bitmap : & DirtyBitmap , ) -> std :: result :: Result < ( ) , Error > { let mut writer_offset = 0 ; let page_size = get_page_size ( ) . map_err ( Error :: PageSize ) ? ; self . iter ( ) . enumerate ( ) . try_for_each ( | ( slot , region ) | { let kvm_bitmap = dirty_bitmap . get ( & slot ) . unwrap ( ) ; let firecracker_bitmap = region . bitmap ( ) ; let mut write_size = 0 ; let mut dirty_batch_start : u64 = 0 ; for ( i , v ) in kvm_bitmap . iter ( ) . enumerate ( ) { for j in 0 .. 64 { let is_kvm_page_dirty = ( ( v >> j ) & 1u64 ) != 0u64 ; let page_offset = ( ( i * 64 ) + j ) * page_size ; let is_firecracker_page_dirty = firecracker_bitmap . dirty_at ( page_offset ) ; if is_kvm_page_dirty || is_firecracker_page_dirty { // We are at the start of a new batch of dirty pages. if write_size == 0 { // Seek forward over the unmodified pages. writer . seek ( SeekFrom :: Start ( writer_offset + page_offset as u64 ) ) . unwrap ( ) ; dirty_batch_start = page_offset as u64 ; } write_size += page_size ; } else if write_size > 0 { // We are at the end of a batch of dirty pages. region . write_all_to ( MemoryRegionAddress ( dirty_batch_start ) , writer , write_size , ) ? ; write_size = 0 ; } } } if write_size > 0 { region . write_all_to ( MemoryRegionAddress ( dirty_batch_start ) , writer , write_size , ) ? ; } writer_offset += region . len ( ) ; if let Some ( bitmap ) = firecracker_bitmap { bitmap . reset ( ) ; } Ok ( ( ) ) } ) . map_err ( Error :: WriteMemory ) }
Dumps all pages of GuestMemoryMmap present in `dirty_bitmap` to a writer.
Dumps all pages of GuestMemoryMmap present in ` dirty_bitmap ` to a writer .
&self
writer
&mut T
dirty_bitmap
&DirtyBitmap
&self
writer
&mut T
dirty_bitmap
&DirtyBitmap