Performs the memory migration including multiple iterations. This includes: - initial memory - VM is running - multiple memory delta transmissions - VM is running - final memory iteration - VM is paused Stores the [finalized] [`MemoryMigrationContext`] in the provided [`OngoingMigrationContext`]. [finalized]: MemoryMigrationContext::finalize
(
vm: &mut Vm,
socket: &mut SocketStream,
send_data_migration: &VmSendMigrationData,
mem_send: &mut SendAdditionalConnections,
ctx: &mut OngoingMigrationContext
| 1347 | /// |
| 1348 | /// [finalized]: MemoryMigrationContext::finalize |
| 1349 | fn do_memory_migration( |
| 1350 | vm: &mut Vm, |
| 1351 | socket: &mut SocketStream, |
| 1352 | send_data_migration: &VmSendMigrationData, |
| 1353 | mem_send: &mut SendAdditionalConnections, |
| 1354 | ctx: &mut OngoingMigrationContext, |
| 1355 | ) -> result::Result<(), MigratableError> { |
| 1356 | let mut mem_ctx = MemoryMigrationContext::new(); |
| 1357 | |
| 1358 | vm.start_dirty_log()?; |
| 1359 | let remaining = Self::do_memory_iterations( |
| 1360 | vm, |
| 1361 | socket, |
| 1362 | &mut mem_ctx, |
| 1363 | // We bind send_data_migration to the callback |
| 1364 | |ctx| Self::is_precopy_converged(ctx, send_data_migration), |
| 1365 | mem_send, |
| 1366 | )?; |
| 1367 | let downtime_begin = Instant::now(); |
| 1368 | if vm.get_state() != VmState::Paused { |
| 1369 | vm.pause()?; |
| 1370 | } |
| 1371 | |
| 1372 | // Send last batch of dirty pages: final iteration |
| 1373 | { |
| 1374 | let iteration_begin = Instant::now(); |
| 1375 | |
| 1376 | let mut final_table = vm.dirty_log()?; |
| 1377 | final_table.extend(remaining); |
| 1378 | |
| 1379 | mem_ctx.update_metrics_before_transfer(iteration_begin, &final_table); |
| 1380 | let transfer_begin = Instant::now(); |
| 1381 | mem_send.send_memory(final_table, socket)?; |
| 1382 | let transfer_duration = transfer_begin.elapsed(); |
| 1383 | mem_ctx.update_metrics_after_transfer(transfer_begin, transfer_duration); |
| 1384 | mem_ctx.iteration += 1; |
| 1385 | } |
| 1386 | mem_ctx.finalize(); |
| 1387 | info!("Precopy complete: {mem_ctx}"); |
| 1388 | ctx.set_vm_paused(downtime_begin, mem_ctx) |
| 1389 | .expect("migration context should transition to VmPaused after memory migration"); |
| 1390 | |
| 1391 | Ok(()) |
| 1392 | } |
| 1393 | |
| 1394 | /// Performs a migration including all its phases. |
| 1395 | fn send_migration( |
nothing calls this directly
no test coverage detected