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
This commit is contained in:
Nikita Ioffe 2019-10-11 16:38:21 +01:00
parent 22d50012b0
commit a5798fc115
6 changed files with 26 additions and 6 deletions

View file

@ -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<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 @@ Status cp_markBootAttempt() {
return Status::ok();
}
void cp_resetCheckpoint() {
std::lock_guard<std::mutex> lock(isCheckpointingLock);
needsCheckpointWasCalled = false;
}
} // namespace vold
} // namespace android

View file

@ -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

View file

@ -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

View file

@ -140,6 +140,7 @@ class VoldNativeService : public BinderService<VoldNativeService>, 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

View file

@ -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,

View file

@ -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);