MCPcopy Create free account
hub / github.com/cloud-hypervisor/cloud-hypervisor / send

Method send

vmm/src/memory_manager.rs:3145–3237  ·  view source on GitHub ↗
(
        &self,
        _snapshot: &Snapshot,
        destination_url: &str,
    )

Source from the content-addressed store, hash-verified

3143
3144impl Transportable for MemoryManager {
3145 fn send(
3146 &self,
3147 _snapshot: &Snapshot,
3148 destination_url: &str,
3149 ) -> result::Result<(), MigratableError> {
3150 if self.snapshot_memory_ranges.is_empty() {
3151 return Ok(());
3152 }
3153
3154 let mut memory_file_path = url_to_path(destination_url)?;
3155 memory_file_path.push(String::from(SNAPSHOT_FILENAME));
3156
3157 let mut memory_file = OpenOptions::new()
3158 .read(true)
3159 .write(true)
3160 .create_new(true)
3161 .open(&memory_file_path)
3162 .map_err(|e| MigratableError::MigrateSend(e.into()))?;
3163
3164 let total_len: u64 = self
3165 .snapshot_memory_ranges
3166 .regions()
3167 .iter()
3168 .map(|r| r.length)
3169 .sum();
3170
3171 // Pre-size the file so per-region write_at lands at the dense-layout
3172 // offset. On filesystems that support sparse files unwritten bytes
3173 // become real holes; on others the kernel zero-fills the allocation,
3174 // which is still byte-correct. If extending the file is not
3175 // supported by the destination filesystem (some FUSE backends
3176 // reject ftruncate-extend with EOPNOTSUPP), fall back to the dense
3177 // write path which never writes past the growing EOF.
3178 let sparse_layout = memory_file.set_len(total_len).is_ok();
3179
3180 let guest_memory = self.guest_memory.memory();
3181 let mut file_cursor: u64 = 0;
3182
3183 for range in self.snapshot_memory_ranges.regions() {
3184 let mut wrote_sparse = false;
3185 if sparse_layout
3186 && let Some(region) = guest_memory.find_region(GuestAddress(range.gpa))
3187 && (region.flags() & libc::MAP_SHARED) == libc::MAP_SHARED
3188 && let Some(file_offset) = region.file_offset()
3189 {
3190 let region_base = region.start_addr().raw_value();
3191 let in_fd_off = file_offset.start()
3192 + range
3193 .gpa
3194 .checked_sub(region_base)
3195 .expect("range outside its region");
3196 wrote_sparse = write_region_sparse(
3197 file_offset.file(),
3198 in_fd_off,
3199 &memory_file,
3200 file_cursor,
3201 range.length,
3202 )

Callers 2

restore_by_uffdMethod · 0.45
uffd_handler_loopMethod · 0.45

Calls 15

url_to_pathFunction · 0.85
newFunction · 0.85
write_region_sparseFunction · 0.85
openMethod · 0.80
iterMethod · 0.80
memoryMethod · 0.80
find_regionMethod · 0.80
start_addrMethod · 0.80
fileMethod · 0.80
is_emptyMethod · 0.45
pushMethod · 0.45
writeMethod · 0.45

Tested by

no test coverage detected