From a5798fc1155c0af55048f83959c5f892ec2ccfa8 Mon Sep 17 00:00:00 2001 From: Nikita Ioffe Date: Fri, 11 Oct 2019 16:38:21 +0100 Subject: [PATCH] vold: implement resetCheckpoint It will be used by userspace reboot to reset checkpoint state, to make sure that when /data is remounted, it will be remounted in checkpointing if a checkpoint was requested beforee userspace reboot. Test: /system/bin/vdc startCheckpoint 1 /system/bin/vdc needsCheckpoint (returns 0) /system/bin/vdc resetCheckpoint /system/bin/vdc needsCheckpoint (returns 1) Bug: 135984674 Change-Id: Ia29238686289b4eed93e2fb936a8b3d894b94dc9 --- Checkpoint.cpp | 19 +++++++++++++------ Checkpoint.h | 1 + VoldNativeService.cpp | 8 ++++++++ VoldNativeService.h | 1 + binder/android/os/IVold.aidl | 1 + vdc.cpp | 2 ++ 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Checkpoint.cpp b/Checkpoint.cpp index e5ef4a2..a4e8fc8 100644 --- a/Checkpoint.cpp +++ b/Checkpoint.cpp @@ -145,8 +145,10 @@ namespace { volatile bool isCheckpointing = false; -// Protects isCheckpointing and code that makes decisions based on status of -// isCheckpointing +volatile bool needsCheckpointWasCalled = false; + +// Protects isCheckpointing, needsCheckpointWasCalled and code that makes decisions based on status +// of isCheckpointing std::mutex isCheckpointingLock; } @@ -263,16 +265,16 @@ bool cp_needsRollback() { } bool cp_needsCheckpoint() { + std::lock_guard lock(isCheckpointingLock); + // Make sure we only return true during boot. See b/138952436 for discussion - static bool called_once = false; - if (called_once) return isCheckpointing; - called_once = true; + if (needsCheckpointWasCalled) return isCheckpointing; + needsCheckpointWasCalled = true; bool ret; std::string content; sp module = IBootControl::getService(); - std::lock_guard lock(isCheckpointingLock); if (isCheckpointing) return isCheckpointing; if (module && module->isSlotMarkedSuccessful(module->getCurrentSlot()) == BoolResult::FALSE) { @@ -727,5 +729,10 @@ Status cp_markBootAttempt() { return Status::ok(); } +void cp_resetCheckpoint() { + std::lock_guard lock(isCheckpointingLock); + needsCheckpointWasCalled = false; +} + } // namespace vold } // namespace android diff --git a/Checkpoint.h b/Checkpoint.h index 63ead83..c1fb2b7 100644 --- a/Checkpoint.h +++ b/Checkpoint.h @@ -45,6 +45,7 @@ android::binder::Status cp_restoreCheckpoint(const std::string& mountPoint, int android::binder::Status cp_markBootAttempt(); +void cp_resetCheckpoint(); } // namespace vold } // namespace android diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp index 7f7f289..0afbab9 100644 --- a/VoldNativeService.cpp +++ b/VoldNativeService.cpp @@ -907,5 +907,13 @@ binder::Status VoldNativeService::supportsFileCheckpoint(bool* _aidl_return) { return cp_supportsFileCheckpoint(*_aidl_return); } +binder::Status VoldNativeService::resetCheckpoint() { + ENFORCE_UID(AID_SYSTEM); + ACQUIRE_LOCK; + + cp_resetCheckpoint(); + return ok(); +} + } // namespace vold } // namespace android diff --git a/VoldNativeService.h b/VoldNativeService.h index 07a0b9f..13137c5 100644 --- a/VoldNativeService.h +++ b/VoldNativeService.h @@ -140,6 +140,7 @@ class VoldNativeService : public BinderService, public os::Bn binder::Status supportsCheckpoint(bool* _aidl_return); binder::Status supportsBlockCheckpoint(bool* _aidl_return); binder::Status supportsFileCheckpoint(bool* _aidl_return); + binder::Status resetCheckpoint(); }; } // namespace vold diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl index 03fe258..8e5c53d 100644 --- a/binder/android/os/IVold.aidl +++ b/binder/android/os/IVold.aidl @@ -116,6 +116,7 @@ interface IVold { boolean supportsCheckpoint(); boolean supportsBlockCheckpoint(); boolean supportsFileCheckpoint(); + void resetCheckpoint(); @utf8InCpp String createStubVolume(@utf8InCpp String sourcePath, @utf8InCpp String mountPath, @utf8InCpp String fsType, diff --git a/vdc.cpp b/vdc.cpp index 839e70e..c1b7781 100644 --- a/vdc.cpp +++ b/vdc.cpp @@ -147,6 +147,8 @@ int main(int argc, char** argv) { int retry; if (!android::base::ParseInt(args[2], &retry)) exit(EINVAL); checkStatus(args, vold->abortChanges(args[2], retry != 0)); + } else if (args[0] == "checkpoint" && args[1] == "resetCheckpoint") { + checkStatus(args, vold->resetCheckpoint()); } else { LOG(ERROR) << "Raw commands are no longer supported"; exit(EINVAL);