Performs a migration including all its phases.
(
vm: &mut Vm,
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
hypervisor: &dyn hypervisor::Hypervisor,
send_data_migration: &VmSendMigrationData,
initial_
| 1393 | |
| 1394 | /// Performs a migration including all its phases. |
| 1395 | fn send_migration( |
| 1396 | vm: &mut Vm, |
| 1397 | #[cfg(all(feature = "kvm", target_arch = "x86_64"))] |
| 1398 | hypervisor: &dyn hypervisor::Hypervisor, |
| 1399 | send_data_migration: &VmSendMigrationData, |
| 1400 | initial_vm_state: VmState, |
| 1401 | ) -> result::Result<(), MigratableError> { |
| 1402 | // State machine that is updated with more context as we progress. |
| 1403 | let mut ctx = OngoingMigrationContext::new(); |
| 1404 | |
| 1405 | // Set up the socket connection |
| 1406 | let mut socket = |
| 1407 | migration_transport::send_migration_socket(&send_data_migration.destination_url)?; |
| 1408 | |
| 1409 | // Start the migration |
| 1410 | migration_transport::send_request_expect_ok( |
| 1411 | &mut socket, |
| 1412 | Request::start(), |
| 1413 | MigratableError::MigrateSend(anyhow!("Error starting migration")), |
| 1414 | )?; |
| 1415 | |
| 1416 | // Send config |
| 1417 | let vm_config = vm.get_config(); |
| 1418 | #[cfg(all(feature = "kvm", target_arch = "x86_64"))] |
| 1419 | let common_cpuid = { |
| 1420 | #[cfg(feature = "tdx")] |
| 1421 | if vm_config.lock().unwrap().is_tdx_enabled() { |
| 1422 | return Err(MigratableError::MigrateSend(anyhow!( |
| 1423 | "Live Migration is not supported when TDX is enabled" |
| 1424 | ))); |
| 1425 | } |
| 1426 | |
| 1427 | let amx = vm_config.lock().unwrap().cpus.features.amx; |
| 1428 | let phys_bits = |
| 1429 | vm::physical_bits(hypervisor, vm_config.lock().unwrap().cpus.max_phys_bits); |
| 1430 | arch::generate_common_cpuid( |
| 1431 | hypervisor, |
| 1432 | &arch::CpuidConfig { |
| 1433 | phys_bits, |
| 1434 | kvm_hyperv: vm_config.lock().unwrap().cpus.kvm_hyperv, |
| 1435 | #[cfg(feature = "tdx")] |
| 1436 | tdx: false, |
| 1437 | amx, |
| 1438 | }, |
| 1439 | ) |
| 1440 | .map_err(|e| { |
| 1441 | MigratableError::MigrateSend(anyhow!("Error generating common cpuid': {e:?}")) |
| 1442 | })? |
| 1443 | }; |
| 1444 | |
| 1445 | if send_data_migration.local { |
| 1446 | match &mut socket { |
| 1447 | SocketStream::Unix(unix_socket) => { |
| 1448 | // Proceed with sending memory file descriptors over UNIX socket |
| 1449 | vm.send_memory_fds(unix_socket)?; |
| 1450 | } |
| 1451 | SocketStream::Tcp(_tcp_socket) => { |
| 1452 | return Err(MigratableError::MigrateSend(anyhow!( |
nothing calls this directly
no test coverage detected