in host/AzureRecoveryLib/win32/RecoveryHelpers.cpp [417:579]
int StartMigration()
{
using namespace AzureRecovery;
TRACE_FUNC_BEGIN;
int retcode = 0;
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 hydration 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 hydration on OS install path: %s.\n",
srcOsInstallPath.str().c_str());
SetOSVersionDetails(srcOsInstallPath.str());
std::string osVersion = RecoveryStatus::Instance().GetUpdate().OsDetails;
// Check if it is Win2k8, if so then AutoMount should be disabled.
bool isWin2k8 = boost::starts_with(osVersion,
RegistryConstants::WIN2K8_VERSION_PREFIX);
// TODO: UEFI commands need not to 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;
}
if (!UpdateBIOSBootRecordsOnOSDisk(
srcOsInstallPath.str(),
activePartitionDrive,
(std::string) "ALL",
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;
}
}
if (EnableSerialConsole(srcOsInstallPath.str()) != ERROR_SUCCESS)
{
// Log within HydrationLogs.
std::stringstream scErrStream;
scErrStream << "Could not update serial console for the VM. ";
TRACE_ERROR("%s\n", scErrStream.str().c_str());
// Do not fail.
}
bool bSuccess = MakeRegistryChangesForMigration(srcOsInstallPath.str(),
srcOsVol,
retcode,
curTaskDesc,
errStream,
isWin2k8);
if (!IsDotNetFxVersionPresent(srcOsVol))
{
TRACE_INFO("No installation of version 4.0+ of Microsoft.NET found.\n");
if (retcode == 0)
{
retcode = E_RECOVERY_DOTNET_FRAMEWORK_INCOMPATIBLE;
}
}
if (!errStream.str().empty())
{
// Formatting if errStream already exists.
errStream << ". ";
}
errStream << (bSuccess ? "Successfully modified" : "Could not modify")
<< " 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;
}