From 72b024f33d9630432e8aad2bf8261051a0df1e41 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Sun, 12 Dec 2021 21:52:29 -0600 Subject: After rolling back in a non-vital rollback boundary, skip to its end. Fixes #6309 --- src/burn/engine/apply.cpp | 73 +++++++++++++++++++++++++++++++---------------- src/burn/engine/engine.mc | 14 +++++++++ src/burn/engine/plan.cpp | 24 +++++++++++++--- src/burn/engine/plan.h | 3 +- 4 files changed, 84 insertions(+), 30 deletions(-) (limited to 'src/burn/engine') diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp index 283c0ada..0467132e 100644 --- a/src/burn/engine/apply.cpp +++ b/src/burn/engine/apply.cpp @@ -191,7 +191,6 @@ static HRESULT DoExecuteAction( __in BURN_ENGINE_STATE* pEngineState, __in BURN_EXECUTE_ACTION* pExecuteAction, __in BURN_EXECUTE_CONTEXT* pContext, - __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary, __inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint, __out BOOL* pfSuspend, __out BOOTSTRAPPER_APPLY_RESTART* pRestart @@ -657,8 +656,7 @@ extern "C" HRESULT ApplyExecute( HRESULT hrRollback = S_OK; BURN_EXECUTE_ACTION_CHECKPOINT* pCheckpoint = NULL; BURN_EXECUTE_CONTEXT context = { }; - BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; - BOOL fSeekNextRollbackBoundary = FALSE; + BOOL fSeekRollbackBoundaryEnd = FALSE; context.pCache = pEngineState->plan.pCache; context.pUX = &pEngineState->userExperience; @@ -680,21 +678,41 @@ extern "C" HRESULT ApplyExecute( continue; } - // If we are seeking the next rollback boundary, skip if this action wasn't it. - if (fSeekNextRollbackBoundary) + // If we are seeking the end of the rollback boundary, skip if this action wasn't it. + if (fSeekRollbackBoundaryEnd) { - if (BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY == pExecuteAction->type) + if (BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_END != pExecuteAction->type) { + LPCWSTR wzId = NULL; + switch (pExecuteAction->type) + { + case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: + wzId = pExecuteAction->exePackage.pPackage->sczId; + break; + case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: + wzId = pExecuteAction->msiPackage.pPackage->sczId; + break; + case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: + wzId = pExecuteAction->mspTarget.pPackage->sczId; + break; + case BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE: + wzId = pExecuteAction->msuPackage.pPackage->sczId; + break; + } + + if (wzId) + { + LogId(REPORT_WARNING, MSG_APPLY_SKIPPING_NONVITAL_ROLLBACK_BOUNDARY_PACKAGE, wzId); + } + continue; } - else - { - fSeekNextRollbackBoundary = FALSE; - } + + fSeekRollbackBoundaryEnd = FALSE; } // Execute the action. - hr = DoExecuteAction(pEngineState, pExecuteAction, &context, &pRollbackBoundary, &pCheckpoint, pfSuspend, pRestart); + hr = DoExecuteAction(pEngineState, pExecuteAction, &context, &pCheckpoint, pfSuspend, pRestart); if (*pfSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == *pRestart) { @@ -737,19 +755,24 @@ extern "C" HRESULT ApplyExecute( hrRollback = DoRollbackActions(pEngineState, &context, pCheckpoint->dwId, pRestart); IgnoreRollbackError(hrRollback, "Failed rollback actions"); - } - // If the rollback boundary is vital, end execution here. - if (pRollbackBoundary && pRollbackBoundary->fVital) - { - break; + if (pCheckpoint->pActiveRollbackBoundary) + { + if (pCheckpoint->pActiveRollbackBoundary->fVital) + { + // If the rollback boundary is vital, end execution here. + break; + } + + // Move forward to the end of this rollback boundary. + fSeekRollbackBoundaryEnd = TRUE; + + LogId(REPORT_WARNING, MSG_APPLY_SKIPPING_REST_OF_NONVITAL_ROLLBACK_BOUNDARY, pCheckpoint->pActiveRollbackBoundary->sczId); + } } - // Ignore failure inside of a non-vital rollback boundary. + // Ignore failure outside of a vital rollback boundary. hr = S_OK; - - // Move forward to next rollback boundary. - fSeekNextRollbackBoundary = TRUE; } } @@ -2207,7 +2230,6 @@ static HRESULT DoExecuteAction( __in BURN_ENGINE_STATE* pEngineState, __in BURN_EXECUTE_ACTION* pExecuteAction, __in BURN_EXECUTE_CONTEXT* pContext, - __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary, __inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint, __out BOOL* pfSuspend, __out BOOTSTRAPPER_APPLY_RESTART* pRestart @@ -2226,7 +2248,7 @@ static HRESULT DoExecuteAction( do { - fInsideMsiTransaction = *ppRollbackBoundary && (*ppRollbackBoundary)->fActiveTransaction; + fInsideMsiTransaction = *ppCheckpoint && (*ppCheckpoint)->pActiveRollbackBoundary && (*ppCheckpoint)->pActiveRollbackBoundary->fActiveTransaction; switch (pExecuteAction->type) { @@ -2296,8 +2318,9 @@ static HRESULT DoExecuteAction( break; - case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY: - *ppRollbackBoundary = pExecuteAction->rollbackBoundary.pRollbackBoundary; + case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_START: __fallthrough; + case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_END: + *ppCheckpoint = NULL; break; case BURN_EXECUTE_ACTION_TYPE_BEGIN_MSI_TRANSACTION: @@ -2406,7 +2429,7 @@ static HRESULT DoRollbackActions( IgnoreRollbackError(hr, "Failed to rollback dependency action."); break; - case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY: + case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_START: ExitFunction1(hr = S_OK); case BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE: diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc index dcd18074..b9267593 100644 --- a/src/burn/engine/engine.mc +++ b/src/burn/engine/engine.mc @@ -991,6 +991,20 @@ Language=English Illegal state: Reboot requested within an MSI transaction, id: %1!ls! . +MessageId=388 +Severity=Warning +SymbolicName=MSG_APPLY_SKIPPING_NONVITAL_ROLLBACK_BOUNDARY_PACKAGE +Language=English +Skipping package inside non-vital rollback boundary, id: %1!ls! +. + +MessageId=389 +Severity=Warning +SymbolicName=MSG_APPLY_SKIPPING_REST_OF_NONVITAL_ROLLBACK_BOUNDARY +Language=English +Skipping the rest of non-vital rollback boundary, id: %1!ls! +. + MessageId=399 Severity=Success SymbolicName=MSG_APPLY_COMPLETE diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index 5aad8c9b..0f63a945 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp @@ -1724,14 +1724,14 @@ extern "C" HRESULT PlanRollbackBoundaryBegin( hr = PlanAppendExecuteAction(pPlan, &pExecuteAction); ExitOnFailure(hr, "Failed to append rollback boundary begin action."); - pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY; + pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_START; pExecuteAction->rollbackBoundary.pRollbackBoundary = pRollbackBoundary; // Add begin rollback boundary to rollback plan. hr = PlanAppendRollbackAction(pPlan, &pExecuteAction); ExitOnFailure(hr, "Failed to append rollback boundary begin action."); - pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY; + pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_START; pExecuteAction->rollbackBoundary.pRollbackBoundary = pRollbackBoundary; hr = UserExperienceOnPlanRollbackBoundary(pUX, pRollbackBoundary->sczId, &pRollbackBoundary->fTransaction); @@ -1786,6 +1786,18 @@ extern "C" HRESULT PlanRollbackBoundaryComplete( // Add checkpoints. hr = PlanExecuteCheckpoint(pPlan); + // Add complete rollback boundary to execute plan. + hr = PlanAppendExecuteAction(pPlan, &pExecuteAction); + ExitOnFailure(hr, "Failed to append rollback boundary complete action."); + + pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_END; + + // Add begin rollback boundary to rollback plan. + hr = PlanAppendRollbackAction(pPlan, &pExecuteAction); + ExitOnFailure(hr, "Failed to append rollback boundary complete action."); + + pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_END; + LExit: return hr; } @@ -2616,8 +2628,12 @@ static void ExecuteActionLog( LogStringLine(PlanDumpLevel, "%ls action[%u]: MSU_PACKAGE package id: %ls, action: %hs, log path: %ls", wzBase, iAction, pAction->msuPackage.pPackage->sczId, LoggingActionStateToString(pAction->msuPackage.action), pAction->msuPackage.sczLogPath); break; - case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY: - LogStringLine(PlanDumpLevel, "%ls action[%u]: ROLLBACK_BOUNDARY id: %ls, vital: %ls", wzBase, iAction, pAction->rollbackBoundary.pRollbackBoundary->sczId, pAction->rollbackBoundary.pRollbackBoundary->fVital ? L"yes" : L"no"); + case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_START: + LogStringLine(PlanDumpLevel, "%ls action[%u]: ROLLBACK_BOUNDARY_START id: %ls, vital: %ls", wzBase, iAction, pAction->rollbackBoundary.pRollbackBoundary->sczId, pAction->rollbackBoundary.pRollbackBoundary->fVital ? L"yes" : L"no"); + break; + + case BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_END: + LogStringLine(PlanDumpLevel, "%ls action[%u]: ROLLBACK_BOUNDARY_END", wzBase, iAction); break; case BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE: diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h index b4348cc4..f0560e6e 100644 --- a/src/burn/engine/plan.h +++ b/src/burn/engine/plan.h @@ -56,7 +56,8 @@ enum BURN_EXECUTE_ACTION_TYPE BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE, BURN_EXECUTE_ACTION_TYPE_PACKAGE_PROVIDER, BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY, - BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY, + BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_START, + BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_END, BURN_EXECUTE_ACTION_TYPE_BEGIN_MSI_TRANSACTION, BURN_EXECUTE_ACTION_TYPE_COMMIT_MSI_TRANSACTION, }; -- cgit v1.2.3-55-g6feb