From 26a2e6eb7bbe3fd9438210153b17d85786754027 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Thu, 5 Sep 2019 17:54:03 -0700 Subject: [PATCH] libsnapshot: cancel ok if unverified and old slot Allow canceling an update if the update has been applied but not rebooted into it. Test: libsnapshot_test Change-Id: I694d74e200908ec622855074ab811e3029328f43 --- fs_mgr/libsnapshot/snapshot.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp index f00129ad9..c744fe4f9 100644 --- a/fs_mgr/libsnapshot/snapshot.cpp +++ b/fs_mgr/libsnapshot/snapshot.cpp @@ -136,11 +136,27 @@ bool SnapshotManager::CancelUpdate() { UpdateState state = ReadUpdateState(file.get()); if (state == UpdateState::None) return true; - if (state != UpdateState::Initiated) { - LOG(ERROR) << "Cannot cancel update after it has completed or started merging"; - return false; + + if (state == UpdateState::Initiated) { + LOG(INFO) << "Update has been initiated, now canceling"; + return RemoveAllUpdateState(file.get()); } - return RemoveAllUpdateState(file.get()); + + if (state == UpdateState::Unverified) { + // We completed an update, but it can still be canceled if we haven't booted into it. + auto boot_file = GetSnapshotBootIndicatorPath(); + std::string contents; + if (!android::base::ReadFileToString(boot_file, &contents)) { + PLOG(WARNING) << "Cannot read " << boot_file << ", proceed to canceling the update:"; + return RemoveAllUpdateState(file.get()); + } + if (device_->GetSlotSuffix() == contents) { + LOG(INFO) << "Canceling a previously completed update"; + return RemoveAllUpdateState(file.get()); + } + } + LOG(ERROR) << "Cannot cancel update after it has completed or started merging"; + return false; } bool SnapshotManager::RemoveAllUpdateState(LockedFile* lock) {