in host/AzureRecoveryLib/win32/RecoveryHelpers.cpp [591:767]
int StartGenConversion()
{
using namespace AzureRecovery;
TRACE_FUNC_BEGIN;
int retcode = E_RECOVERY_SUCCESS;
std::stringstream errStream;
std::string errorMessage;
std::string curTaskDesc;
do
{
curTaskDesc = TASK_DESCRIPTIONS::PREPARE_DISKS;
if (!OnlineDisks(errorMessage))
{
// Ignore any error here. If OS disk online fails
// then the later logic will anyway result in failure.
TRACE_ERROR(
"Disk online failed for one of the disks. %s.\n",
errorMessage.c_str());
}
std::list<std::string> osVolumes;
curTaskDesc = TASK_DESCRIPTIONS::MOUNT_SYSTEM_PARTITIONS;
if (!DiscoverSourceOSVolumes(osVolumes, errorMessage))
{
retcode = E_RECOVERY_VOL_NOT_FOUND;
errStream << "Could not prepare Source OS install path on Hydration VM.( "
<< errorMessage
<< " )";
TRACE_ERROR("%s\n", errStream.str().c_str());
//
// OS volume is not identified, print all the partitions details.
//
PrintAllDiskPartitions();
RecoveryStatus::Instance().SetStatusErrorCode(
retcode,
"OS Volume");
break;
}
BOOST_ASSERT(osVolumes.size() > 0);
// Do update bcd recodrds for all the OS volumes discovered.
BOOST_FOREACH(const std::string& srcOsVol, osVolumes)
{
std::stringstream srcOsInstallPath;
srcOsInstallPath
<< boost::trim_right_copy_if(srcOsVol, boost::is_any_of(DIRECOTRY_SEPERATOR))
<< SysConstants::DEFAULT_SYSTEM32_DIR;
TRACE_INFO("Performing gen conversion on OS install path: %s.\n",
srcOsInstallPath.str().c_str());
SetOSVersionDetails(srcOsInstallPath.str());
// TODO: UEFI commands need not be run on every OS volume found.
if (AzureRecoveryConfig::Instance().IsUEFI())
{
std::string activePartitionDrive;
if (!PrepareActivePartitionDrive(
activePartitionDrive,
errorMessage))
{
retcode = E_RECOVERY_COULD_NOT_PREPARE_ACTIVE_PARTITION_DRIVE;
errStream << "Could not prepare active partition drive for BCD update. ( "
<< errorMessage
<< " )";
TRACE_ERROR("%s\n", errStream.str().c_str());
PrintAllDiskPartitions();
break;
}
// Enable serial console on BIOS BCD Path as the VM has been converted.
if (EnableSerialConsole(srcOsInstallPath.str()) != ERROR_SUCCESS)
{
// Log within HydrationLogs.
errStream << "Could not update serial console for the VM. ";
// Do not fail.
}
if (!UpdateBIOSBootRecordsOnOSDisk(
srcOsInstallPath.str(),
activePartitionDrive,
(std::string) "BIOS",
errorMessage))
{
retcode = E_RECOVERY_COULD_NOT_UPDATE_BCD;
errStream << "Could not update BIOS boot records on active partition. ( "
<< errorMessage
<< " )";
TRACE_ERROR("%s\n", errStream.str().c_str());
PrintAllDiskPartitions();
break;
}
bool isWin2k8 = false;
OSVersion osVersion;
if (GetOsVersion(osVersion)) {
isWin2k8 = ((osVersion.major == 6) && (osVersion.minor == 0));
}
// Since gen-conversion is a critical failure in protection service, using alternate retCode so hydration doesn't fail
// if any of the registry changes fail.
int regRetCode = 0;
std::stringstream regErrStr;
// Make registry changes, enable DHCP and install guest agent.
bool bSuccess = MakeRegistryChangesForMigration(srcOsInstallPath.str(),
srcOsVol,
regRetCode,
curTaskDesc,
regErrStr,
isWin2k8);
if (!IsDotNetFxVersionPresent(srcOsVol))
{
TRACE_INFO("No installation of version 4.0+ of Microsoft.NET found.\n");
if (retcode == 0)
{
errStream << "Windows VM Agent requires .NET version 4.0+ .";
retcode = E_RECOVERY_DOTNET_FRAMEWORK_INCOMPATIBLE;
}
}
if (!bSuccess)
{
// Log the error and ignore.
TRACE_ERROR("Couldn't modify the registry settings for Gen2 VM. %s\n", regErrStr.str().c_str());
}
errStream << "Successfully modified the OS installation: "
<< srcOsInstallPath.str()
<< ".";
}
else
{
TRACE_WARNING("Not a UEFI VM, nothing to update.");
errStream << "Not a Gen2 VM. Nothing to modify in the OS installation: "
<< srcOsInstallPath.str()
<< ".";
}
}
curTaskDesc = TASK_DESCRIPTIONS::UPLOAD_LOG;
} while (false);
// Set error details.
RecoveryStatus::Instance().UpdateErrorDetails(
retcode,
errStream.str());
// Update progress.
RecoveryStatus::Instance().UpdateProgress(100,
retcode == 0 ?
Recovery_Status::ExecutionSuccess :
Recovery_Status::ExecutionFailed,
curTaskDesc);
return retcode;
}