Skip to content

Commit

Permalink
After rolling back in a non-vital rollback boundary, skip to its end.
Browse files Browse the repository at this point in the history
Fixes #6309
  • Loading branch information
rseanhall committed Dec 13, 2021
1 parent e223ab3 commit 72b024f
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 57 deletions.
73 changes: 48 additions & 25 deletions src/burn/engine/apply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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)
{
Expand Down Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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
Expand All @@ -2226,7 +2248,7 @@ static HRESULT DoExecuteAction(

do
{
fInsideMsiTransaction = *ppRollbackBoundary && (*ppRollbackBoundary)->fActiveTransaction;
fInsideMsiTransaction = *ppCheckpoint && (*ppCheckpoint)->pActiveRollbackBoundary && (*ppCheckpoint)->pActiveRollbackBoundary->fActiveTransaction;

switch (pExecuteAction->type)
{
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
14 changes: 14 additions & 0 deletions src/burn/engine/engine.mc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 20 additions & 4 deletions src/burn/engine/plan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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:
Expand Down
3 changes: 2 additions & 1 deletion src/burn/engine/plan.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down

0 comments on commit 72b024f

Please sign in to comment.