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
diff --git a/Checkpoint.cpp b/Checkpoint.cpp
index e5ef4a2..a4e8fc8 100644
--- a/Checkpoint.cpp
+++ b/Checkpoint.cpp
@@ -145,8 +145,10 @@
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_needsCheckpoint() {
+ std::lock_guard<std::mutex> 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<IBootControl> module = IBootControl::getService();
- std::lock_guard<std::mutex> lock(isCheckpointingLock);
if (isCheckpointing) return isCheckpointing;
if (module && module->isSlotMarkedSuccessful(module->getCurrentSlot()) == BoolResult::FALSE) {
@@ -727,5 +729,10 @@
return Status::ok();
}
+void cp_resetCheckpoint() {
+ std::lock_guard<std::mutex> 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_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 @@
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 @@
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 @@
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 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);