in LCM/dsc/engine/ConfigurationManager/LocalConfigManagerHelper.c [6033:6250]
MI_Result MI_CALL LCM_Pull_Execute(
_In_ LCMProviderContext *lcmContext,
_In_ MI_Instance *metaConfigInstance,
_Outptr_result_maybenull_ MI_Instance **cimErrorDetails)
{
//get the meta config instance.
MI_Char* resultStatus = NULL;
MI_Result result = MI_RESULT_OK;
ModuleManager *moduleManager = NULL;
MI_Boolean bComplianceStatus;
MI_Uint32 getActionStatusCode;
MI_Uint32 lcmStatusCode;
MI_Uint32 resultExecutionStatus = 0;
MI_Char *checkSumValue = NULL;
MI_Char *partialConfigName = NULL;
MI_InstanceA partialConfigurations = { 0 };
MI_Boolean complianceStatus = MI_FALSE;
MI_Boolean bFullConfiguration = MI_FALSE;
MI_Boolean bGotNewConfiguration = MI_FALSE;
MI_Result updateResult = MI_RESULT_OK;
MI_Instance* updateErrorDetails = NULL;
MI_Uint32 xCount;
MI_Uint32 numModulesInstalled = 0;
int retval;
OverAllGetActionResponse* serverAssignedConfigurations = NULL;
SetLCMProviderContext( lcmContext, (LCM_EXECUTIONMODE_OFFLINE | LCM_EXECUTIONMODE_ONLINE) , NULL);
result = InitializeModuleManager(0, cimErrorDetails, &moduleManager);
if (result != MI_RESULT_OK)
{
return result;
}
if (moduleManager == NULL)
{
return GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_ENGINEHELPER_MEMORY_ERROR);
}
result = RegisterWithPullServers(lcmContext, metaConfigInstance, cimErrorDetails);
if (result != MI_RESULT_OK)
{
moduleManager->ft->Close(moduleManager, NULL);
return result;
}
GetLatestStatus(&bComplianceStatus, &getActionStatusCode, &lcmStatusCode);
/* Now we need to figure out if we have to download partial configurations.*/
// r = GetPartialConfigurationPath(value.string, configFileName, cimErrorDetails);
if (ShouldUsePartialConfigurations(metaConfigInstance, MI_FALSE)) //Don't need to check if there are files in the partial config directory
{
result = GetPartialConfigurations((MI_Instance*) metaConfigInstance, &partialConfigurations, cimErrorDetails);
if (result != MI_RESULT_OK)
{
moduleManager->ft->Close(moduleManager, NULL);
return result;
}
}
else
{
// We have exactly 1 element to process, GetPartialConfigurationName handles NULL and return
// appropriately for full configurations for rest of the system to work properly
partialConfigurations.size = 1;
bFullConfiguration = MI_TRUE;
}
for (xCount = 0; xCount < partialConfigurations.size && result == MI_RESULT_OK; xCount++)
{
result = GetPartialConfigurationName(bFullConfiguration ? NULL : partialConfigurations.data[xCount], (const MI_Char**)&partialConfigName, cimErrorDetails);
if (partialConfigName != NULL)
{
DSC_EventWriteLCMPullingPartial(partialConfigName);//Log that we're pulling this partial configuration
}
if (result != MI_RESULT_OK)
{
moduleManager->ft->Close(moduleManager, NULL);
return result;
}
result = GetMofChecksum(&checkSumValue, partialConfigName, cimErrorDetails);
if (result != MI_RESULT_OK)
{
moduleManager->ft->Close(moduleManager, NULL);
return result;
}
result = LCM_Pull_ExecuteActionPerConfiguration(lcmContext, metaConfigInstance, partialConfigName,
checkSumValue, bComplianceStatus, getActionStatusCode,
&numModulesInstalled, &resultStatus, &getActionStatusCode, &serverAssignedConfigurations,
moduleManager, cimErrorDetails);
DSC_free(checkSumValue);
if (serverAssignedConfigurations)
{
// Release the memory block assigned to each configuration status and then release the overall configurationstatus (serverAssignedConfigurations)
// Please refer to the struct definition of 'OverAllGetActionResponse' to understand the logic below easily.
if (serverAssignedConfigurations != NULL)
{
MI_Uint32 totalConfigCounts = (serverAssignedConfigurations)->NumberOfConfiguration;
MI_Uint32 memoryOffset;
for (memoryOffset = 0; memoryOffset < totalConfigCounts; memoryOffset++)
{
ConfigurationStatus* currentMemoryBlock = (serverAssignedConfigurations)->Details + memoryOffset;
if (currentMemoryBlock != NULL)
{
DSC_free(currentMemoryBlock);
currentMemoryBlock = NULL;
}
}
DSC_free(serverAssignedConfigurations);
}
serverAssignedConfigurations = NULL;
}
if (result == MI_RESULT_OK)
{
// If GetAction required us to get the configuraiton then only we have to apply the new configuration.
if (resultStatus && Tcscasecmp(resultStatus, PULL_STATUSCODE_GETCONFIG) == 0)
{
bGotNewConfiguration = MI_TRUE;
}
else if (resultStatus && Tcscasecmp(resultStatus, PULL_STATUSCODE_RETRY) == 0)
{
// Pull server didn't have configuration file, ignore the failure, it will be handled later.
DSC_EventWritePartialConfigurationNotAvailable(partialConfigName);
}
if (resultStatus)
{
DSC_free(resultStatus);
}
}
}
if (result == MI_RESULT_OK && bGotNewConfiguration)
{
if (!bFullConfiguration)
{
//If the partial configurations directory contains partial files, combine them and save into pending.mof
result = MergePartialConfigurations(lcmContext, moduleManager, GetPendingConfigFileName(), GetPartialConfigBaseDocumentInstanceFileName(), cimErrorDetails);
EH_CheckResult(result);
}
// If everything is good we will apply the configuration here.
if (result == MI_RESULT_OK)
{
// If Current.mof exists, move Current.mof to Previous.mof
if (File_ExistT(GetCurrentConfigFileName()) == 0)
{
result = CopyConfigAndRemoveSource(CONFIGURATION_LOCATION_CURRENT, CONFIGURATION_LOCATION_PREVIOUS, cimErrorDetails);
EH_CheckResult(result);
}
if (numModulesInstalled > 0)
{
result = ModuleManager_Update(moduleManager, cimErrorDetails);
if (result != MI_RESULT_OK)
{
return result;
}
#if defined(BUILD_OMS)
if (g_DscHost == MI_FALSE)
{
system(OMI_RELOAD_COMMAND);
}
#else
system(OMI_RELOAD_COMMAND);
#endif
}
result = ApplyPendingConfig(lcmContext, moduleManager, 0, &resultExecutionStatus, cimErrorDetails);
if (result == MI_RESULT_OK && (resultExecutionStatus & DSC_RESTART_SYSTEM_FLAG))
{
SetLCMStatusReboot(lcmContext);
}
if (result == MI_RESULT_OK)
{
// update compliance result.
complianceStatus = MI_TRUE;
result = UpdateCurrentStatus(&complianceStatus, NULL, NULL, NULL, cimErrorDetails);
if (result == MI_RESULT_OK)
{
// result = CopyConfigurationChecksum(mofFileName, cimErrorDetails);
}
}
}
}
if (result != MI_RESULT_OK)
{
// log it here.
DSC_EventWriteLCMPullEngineError(CA_ACTIVITY_NAME,
GetDownloadManagerName(metaConfigInstance),
result,
GetErrorDetail(*cimErrorDetails));
}
updateResult = UpdateCurrentStatus(NULL, &getActionStatusCode, NULL, NULL, &updateErrorDetails);
if (updateResult != MI_RESULT_OK)
{
if (result == MI_RESULT_OK)
{
// update the error with it.
result = updateResult;
*cimErrorDetails = updateErrorDetails;
}
else
{
// retain original error and delete error instance.
if (updateErrorDetails)
{
MI_Instance_Delete(updateErrorDetails);
}
}
}
EH_UNWIND;
moduleManager->ft->Close(moduleManager, NULL);
return result;
}