diff --git a/vm-migration/src/progress.rs b/vm-migration/src/progress.rs index 8a5083068d..c5babdad92 100644 --- a/vm-migration/src/progress.rs +++ b/vm-migration/src/progress.rs @@ -76,8 +76,12 @@ pub struct MemoryTransmissionInfo { Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, )] pub enum MigrationStateOngoingPhase { - /// The migration starts. Handshake and transfer of VM config. + /// The migration process is initiated. No checks or connections are + /// established yet. Starting, + /// The initial connection is established and the migration protocol + /// handshake succeeded. + Started, /// Transfer of memory FDs. /// /// Only used for local migrations. @@ -96,6 +100,7 @@ impl Display for MigrationStateOngoingPhase { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Starting => write!(f, "starting"), + Self::Started => write!(f, "started"), Self::MemoryFds => write!(f, "memory FDs"), Self::MemoryPrecopy => write!(f, "memory (precopy)"), Self::Completing => write!(f, "completing"), diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index c94eee40ea..0bb2f65301 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -1897,6 +1897,16 @@ impl Vmm { MigratableError::MigrateSend(anyhow!("Error starting migration (got bad response)")), )?; + // Signal that the migration connection has been established. Management + // software can use this to distinguish short send/receive races from a + // real migration startup failure. + { + let mut lock = MIGRATION_PROGRESS_SNAPSHOT.lock().unwrap(); + lock.as_mut() + .expect("live migration should be ongoing") + .update(MigrationStateOngoingPhase::Started, None, None, None); + } + return_if_cancelled_cb(&mut socket)?; // Send config