From ae2558d900d5eafe2a511f8debe72a8564f5f966 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Tue, 18 Feb 2020 14:19:14 -0800 Subject: [PATCH] libsnapshot: RemoveUpdateState on rollback. If rollback is detected in ProcessUpdateState, call RemoveUpdateState and return UpdateState::Cancelled. Now that update_engine is reponsible for initiating the merge, it can react to this state and clean up markers appropriately. Test: libsnapshot_test Test: apply OTA, manually rollback (by setting the active slot), then inspect /metadata/ota as well as /data/misc/update_engine/prefs. Bug: 147696014 Change-Id: Ibfee11fb50e4f4fb7c6cf02b4921b35e77b8f5a5 Merged-In: Ibfee11fb50e4f4fb7c6cf02b4921b35e77b8f5a5 --- fs_mgr/libsnapshot/snapshot.cpp | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp index 152ea9c3e..c51c977db 100644 --- a/fs_mgr/libsnapshot/snapshot.cpp +++ b/fs_mgr/libsnapshot/snapshot.cpp @@ -1185,15 +1185,32 @@ bool SnapshotManager::HandleCancelledUpdate(LockedFile* lock, // If all snapshots were reflashed, then cancel the entire update. if (AreAllSnapshotsCancelled(lock)) { + LOG(WARNING) << "Detected re-flashing, cancelling unverified update."; RemoveAllUpdateState(lock, before_cancel); return true; } - // This unverified update might be rolled back, or it might not (b/147347110 - // comment #77). Take no action, as update_engine is responsible for deciding - // whether to cancel. - LOG(ERROR) << "Update state is being processed before reboot, taking no action."; - return false; + // If update has been rolled back, then cancel the entire update. + // Client (update_engine) is responsible for doing additional cleanup work on its own states + // when ProcessUpdateState() returns UpdateState::Cancelled. + auto current_slot = GetCurrentSlot(); + if (current_slot != Slot::Source) { + LOG(INFO) << "Update state is being processed while booting at " << current_slot + << " slot, taking no action."; + return false; + } + + // current_slot == Source. Attempt to detect rollbacks. + if (access(GetRollbackIndicatorPath().c_str(), F_OK) != 0) { + // This unverified update is not attempted. Take no action. + PLOG(INFO) << "Rollback indicator not detected. " + << "Update state is being processed before reboot, taking no action."; + return false; + } + + LOG(WARNING) << "Detected rollback, cancelling unverified update."; + RemoveAllUpdateState(lock, before_cancel); + return true; } std::unique_ptr SnapshotManager::ReadCurrentMetadata() {