Add support for checkpointing

Checkpointing uses a combination of files on the meta partition
and the checkpoint= fs_mgr flag. Checkpointed partitions will
revert to their starting state on reboot unless checkpoint commit
is called.

Test: Run vdc commands, check file on metadata
Merged-In: Icba16578608a6cbf922472e9d4ae5b8cf5f016c6
Change-Id: Icba16578608a6cbf922472e9d4ae5b8cf5f016c6
diff --git a/vdc.cpp b/vdc.cpp
index f49d6b8..ff5073b 100644
--- a/vdc.cpp
+++ b/vdc.cpp
@@ -31,6 +31,7 @@
 #include "android/os/IVold.h"
 
 #include <android-base/logging.h>
+#include <android-base/parseint.h>
 #include <android-base/stringprintf.h>
 #include <binder/IServiceManager.h>
 #include <binder/Status.h>
@@ -104,6 +105,31 @@
         checkStatus(vold->mountFstab(args[2]));
     } else if (args[0] == "cryptfs" && args[1] == "encryptFstab" && args.size() == 3) {
         checkStatus(vold->encryptFstab(args[2]));
+    } else if (args[0] == "checkpoint" && args[1] == "startCheckpoint" && args.size() == 3) {
+        int retry;
+        bool success = false;
+        if (!android::base::ParseInt(args[2], &retry)) exit(EINVAL);
+        checkStatus(vold->startCheckpoint(retry, &success));
+        return success ? 1 : 0;
+    } else if (args[0] == "checkpoint" && args[1] == "needsCheckpoint" && args.size() == 2) {
+        bool enabled = false;
+        checkStatus(vold->needsCheckpoint(&enabled));
+        return enabled ? 1 : 0;
+    } else if (args[0] == "checkpoint" && args[1] == "commitChanges" && args.size() == 2) {
+        bool success = false;
+        checkStatus(vold->commitChanges(&success));
+        return success ? 1 : 0;
+    } else if (args[0] == "checkpoint" && args[1] == "prepareDriveForCheckpoint" &&
+               args.size() == 3) {
+        bool success = false;
+        checkStatus(vold->prepareDriveForCheckpoint(args[2], &success));
+        return success ? 1 : 0;
+    } else if (args[0] == "checkpoint" && args[1] == "markBootAttempt" && args.size() == 2) {
+        bool success = false;
+        checkStatus(vold->markBootAttempt(&success));
+        return success ? 1 : 0;
+    } else if (args[0] == "checkpoint" && args[1] == "abortChanges" && args.size() == 2) {
+        checkStatus(vold->abortChanges());
     } else {
         LOG(ERROR) << "Raw commands are no longer supported";
         exit(EINVAL);