in host/common/hostrecoverymanager.cpp [227:373]
void HostRecoveryManager::GetRecoveryInfo(bool & bIsHydrationWorkflow,
bool& bSystemUuidChanged,
bool& bHypervisorChanged,
bool& bIsAzureVm,
bool& bVmTypeChanged,
bool& bIsFailoverDetected,
QuitFunction_t qf)
{
DebugPrintf(SV_LOG_DEBUG, "Entering %s\n", FUNCTION_NAME);
bIsHydrationWorkflow = false;
bHypervisorChanged = false;
bSystemUuidChanged = false;
bIsAzureVm = false;
bVmTypeChanged = false;
LocalConfigurator lc;
// Recovery is only meaningful for mobility agent
if (!lc.isMobilityAgent()) {
DebugPrintf(SV_LOG_DEBUG, "Not running as mobility agent.. skipping recovery check\n");
return;
}
#ifdef SV_WINDOWS
//
// ### Hydration ###
///
// Check if it is hydration workflow.
//
bIsHydrationWorkflow = ::IsRecoveryInProgress();
if (bIsHydrationWorkflow)
{
DebugPrintf(SV_LOG_INFO,
"Hydration has happened. Recovery is in pogress.");
DebugPrintf(SV_LOG_DEBUG, "Exiting %s\n", FUNCTION_NAME);
return;
}
#endif
//
// ### No-Hydration / Clone ###
//
//
// Check if the Persisted VM info availability
//
std::string persistedHypervisorName;
std::string persistedSystemUUID;
bool persistedIsAzureVm;
if (GetPersistedVMInfo(persistedHypervisorName, persistedSystemUUID, persistedIsAzureVm))
{
DebugPrintf(SV_LOG_INFO,
"Persisted VM info available: Hypervisor: %s, System UUID: %s, IsAzureVm %d\n",
persistedHypervisorName.c_str(),
persistedSystemUUID.c_str(),
persistedIsAzureVm);
}
else
{
DebugPrintf(SV_LOG_INFO,
"Persisted VM info not available. It might not be a recovery.\n");
return;
}
//
// Discover the System UUID and Hypervisor
//
string systemUUID = GetSystemUUID();
// Skip recovery detection if System UUID is empty.
if (systemUUID.empty()) {
DebugPrintf(SV_LOG_ERROR, "IsRecoveryInProgress: Could not retrieve System UUID or got empty UUID.");
return;
}
if (boost::iequals(systemUUID, INVALID_UUID)) {
DebugPrintf(SV_LOG_ERROR, "IsRecoveryInProgress: Got Invalid UUID.");
return;
}
string hypervisor, hypervisorversion;
if (!IsVirtual(hypervisor, hypervisorversion))
{
hypervisor = PHYSICALMACHINE;
}
bSystemUuidChanged = !boost::iequals(systemUUID, persistedSystemUUID);
if (persistedHypervisorName.empty() ||
persistedSystemUUID.empty() ||
boost::iequals(persistedSystemUUID, INVALID_UUID) ||
!bSystemUuidChanged) {
DebugPrintf(SV_LOG_DEBUG, "Exiting %s\n", FUNCTION_NAME);
return;
}
//
// Compare discovered VM info with persisted values to detect the VM recovery.
// On Vmware if system UUID changes it is a clone
// On failover if system UUID changes
//
bIsAzureVm = IsAzureVirtualMachine();
// If hypervisor has not changed, it means it is a clone except when
// Hyper-v VM is migrated to Azure,
// Clone of Azure VM after failover from on-prem - [Migraton of Azure VM not supported using V2A,
// use A2A and such recovery is handled in AzureVmRecoveryManager ]
// Azure stack to Azure migration - [ this is not handled by this logic.
// it is detected as clone and that is fine as no failback is supported ]
// AVS scenario involved where the decision is made based on the FailoverVmBiosid received from rcm
// it is detected as failover if the rcm received biosid matches with the current system biosid
// Note that the only difference between clone and failover is to set the new hostId as BIOS-ID and the source control plane
// for the AVS scenario
// (see CompleteRecovery()). Except for the V2A Legacy there is no such requirement in other providers.
bHypervisorChanged = !boost::iequals(hypervisor, persistedHypervisorName);
bVmTypeChanged = (bIsAzureVm != persistedIsAzureVm);
DebugPrintf(SV_LOG_INFO,
"Current VM Info: Hypervisor: %s, System UUID: %s, IsAzureVm %d\n",
hypervisor.c_str(),
systemUUID.c_str(),
bIsAzureVm);
string failoverVmBiosId = lc.getFailoverVmBiosId();
if (!failoverVmBiosId.empty()){
DebugPrintf(SV_LOG_DEBUG, "Failover Vm BiosId is %s.\n",
failoverVmBiosId.c_str());
}
if ( bVmTypeChanged || (bHypervisorChanged ||
(!failoverVmBiosId.empty() && (boost::iequals(failoverVmBiosId, systemUUID) ||
boost::iequals(failoverVmBiosId, BiosID::GetByteswappedBiosID(systemUUID)))) ||
(IsAzureStackVirtualMachine() && HasAzureStackHubFailoverTag(qf)))) {
bIsFailoverDetected = true;
DebugPrintf(SV_LOG_ALWAYS, "Failover Detected Persisted UUID: %s CurrentUUID: %s\n", persistedSystemUUID.c_str(), systemUUID.c_str());
}
else
{
DebugPrintf(SV_LOG_ALWAYS, "Clone Detected Persisted UUID: %s CurrentUUID: %s\n", persistedSystemUUID.c_str(), systemUUID.c_str());
}
DebugPrintf(SV_LOG_DEBUG, "Exiting %s\n", FUNCTION_NAME);
return;
}