Add a mount with metadata encryption service

Don't use the FDE flow to support metadata encryption; just provide a
vold service which directly mounts the volume and use that.

Bug: 63927601
Test: Boot Taimen to SUW with and without metadata encryption.
Change-Id: Ifc6a012c02c0ea66893020ed1d0da4cba6914aed
diff --git a/EncryptInplace.cpp b/EncryptInplace.cpp
index 45734a8..6462dbf 100644
--- a/EncryptInplace.cpp
+++ b/EncryptInplace.cpp
@@ -73,6 +73,7 @@
     int completed;
     time_t time_started;
     int remaining_time;
+    bool set_progress_properties;
 };
 
 static void update_progress(struct encryptGroupsData* data, int is_used)
@@ -88,6 +89,8 @@
         data->new_pct = data->blocks_already_done / data->one_pct;
     }
 
+    if (!data->set_progress_properties) return;
+
     if (data->new_pct > data->cur_pct) {
         char buf[8];
         data->cur_pct = data->new_pct;
@@ -253,7 +256,8 @@
 
 static int cryptfs_enable_inplace_ext4(char* crypto_blkdev, char* real_blkdev, off64_t size,
                                        off64_t* size_already_done, off64_t tot_size,
-                                       off64_t previously_encrypted_upto) {
+                                       off64_t previously_encrypted_upto,
+                                       bool set_progress_properties) {
     u32 i;
     struct encryptGroupsData data;
     int rc; // Can't initialize without causing warning -Wclobbered
@@ -268,13 +272,16 @@
     memset(&data, 0, sizeof(data));
     data.real_blkdev = real_blkdev;
     data.crypto_blkdev = crypto_blkdev;
+    data.set_progress_properties = set_progress_properties;
 
+    LOG(DEBUG) << "Opening" << real_blkdev;
     if ( (data.realfd = open(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
         PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
         rc = -1;
         goto errout;
     }
 
+    LOG(DEBUG) << "Opening" << crypto_blkdev;
     // Wait until the block device appears.  Re-use the mount retry values since it is reasonable.
     while ((data.cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) {
         if (--retries) {
@@ -390,7 +397,8 @@
 
 static int cryptfs_enable_inplace_f2fs(char* crypto_blkdev, char* real_blkdev, off64_t size,
                                        off64_t* size_already_done, off64_t tot_size,
-                                       off64_t previously_encrypted_upto) {
+                                       off64_t previously_encrypted_upto,
+                                       bool set_progress_properties) {
     struct encryptGroupsData data;
     struct f2fs_info *f2fs_info = NULL;
     int rc = ENABLE_INPLACE_ERR_OTHER;
@@ -401,6 +409,7 @@
     memset(&data, 0, sizeof(data));
     data.real_blkdev = real_blkdev;
     data.crypto_blkdev = crypto_blkdev;
+    data.set_progress_properties = set_progress_properties;
     data.realfd = -1;
     data.cryptofd = -1;
     if ( (data.realfd = open64(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
@@ -463,7 +472,8 @@
 
 static int cryptfs_enable_inplace_full(char* crypto_blkdev, char* real_blkdev, off64_t size,
                                        off64_t* size_already_done, off64_t tot_size,
-                                       off64_t previously_encrypted_upto) {
+                                       off64_t previously_encrypted_upto,
+                                       bool set_progress_properties) {
     int realfd, cryptofd;
     char *buf[CRYPT_INPLACE_BUFSIZE];
     int rc = ENABLE_INPLACE_ERR_OTHER;
@@ -526,7 +536,7 @@
     /* process the majority of the filesystem in blocks */
     for (i/=CRYPT_SECTORS_PER_BUFSIZE; i<numblocks; i++) {
         new_pct = (i + blocks_already_done) / one_pct;
-        if (new_pct > cur_pct) {
+        if (set_progress_properties && new_pct > cur_pct) {
             char buf[8];
 
             cur_pct = new_pct;
@@ -575,13 +585,17 @@
 /* returns on of the ENABLE_INPLACE_* return codes */
 int cryptfs_enable_inplace(char* crypto_blkdev, char* real_blkdev, off64_t size,
                            off64_t* size_already_done, off64_t tot_size,
-                           off64_t previously_encrypted_upto) {
+                           off64_t previously_encrypted_upto, bool set_progress_properties) {
     int rc_ext4, rc_f2fs, rc_full;
+    LOG(DEBUG) << "cryptfs_enable_inplace(" << crypto_blkdev << ", " << real_blkdev << ", " << size
+               << ", " << size_already_done << ", " << tot_size << ", " << previously_encrypted_upto
+               << ", " << set_progress_properties << ")";
     if (previously_encrypted_upto) {
         LOG(DEBUG) << "Continuing encryption from " << previously_encrypted_upto;
     }
 
     if (*size_already_done + size < previously_encrypted_upto) {
+        LOG(DEBUG) << "cryptfs_enable_inplace already done";
         *size_already_done += size;
         return 0;
     }
@@ -590,30 +604,33 @@
      * As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and
      * then we will drop down to cryptfs_enable_inplace_f2fs.
      * */
-    if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev,
-                                size, size_already_done,
-                                tot_size, previously_encrypted_upto)) == 0) {
-      return 0;
+    if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev, size, size_already_done,
+                                               tot_size, previously_encrypted_upto,
+                                               set_progress_properties)) == 0) {
+        LOG(DEBUG) << "cryptfs_enable_inplace_ext4 success";
+        return 0;
     }
     LOG(DEBUG) << "cryptfs_enable_inplace_ext4()=" << rc_ext4;
 
-    if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev,
-                                size, size_already_done,
-                                tot_size, previously_encrypted_upto)) == 0) {
-      return 0;
+    if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev, size, size_already_done,
+                                               tot_size, previously_encrypted_upto,
+                                               set_progress_properties)) == 0) {
+        LOG(DEBUG) << "cryptfs_enable_inplace_f2fs success";
+        return 0;
     }
     LOG(DEBUG) << "cryptfs_enable_inplace_f2fs()=" << rc_f2fs;
 
-    rc_full = cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev,
-                                       size, size_already_done, tot_size,
-                                       previously_encrypted_upto);
+    rc_full =
+        cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev, size, size_already_done, tot_size,
+                                    previously_encrypted_upto, set_progress_properties);
     LOG(DEBUG) << "cryptfs_enable_inplace_full()=" << rc_full;
 
     /* Hack for b/17898962, the following is the symptom... */
     if (rc_ext4 == ENABLE_INPLACE_ERR_DEV
         && rc_f2fs == ENABLE_INPLACE_ERR_DEV
         && rc_full == ENABLE_INPLACE_ERR_DEV) {
-            return ENABLE_INPLACE_ERR_DEV;
+        LOG(DEBUG) << "ENABLE_INPLACE_ERR_DEV";
+        return ENABLE_INPLACE_ERR_DEV;
     }
     return rc_full;
 }
diff --git a/EncryptInplace.h b/EncryptInplace.h
index de5a1c5..71644ac 100644
--- a/EncryptInplace.h
+++ b/EncryptInplace.h
@@ -24,9 +24,8 @@
 #define RETRY_MOUNT_ATTEMPTS 10
 #define RETRY_MOUNT_DELAY_SECONDS 1
 
-int cryptfs_enable_inplace(char *crypto_blkdev, char *real_blkdev,
-                           off64_t size, off64_t *size_already_done,
-                           off64_t tot_size,
-                           off64_t previously_encrypted_upto);
+int cryptfs_enable_inplace(char* crypto_blkdev, char* real_blkdev, off64_t size,
+                           off64_t* size_already_done, off64_t tot_size,
+                           off64_t previously_encrypted_upto, bool set_progress_properties);
 
 #endif
diff --git a/MetadataCrypt.cpp b/MetadataCrypt.cpp
index 24047f9..4a847e3 100644
--- a/MetadataCrypt.cpp
+++ b/MetadataCrypt.cpp
@@ -31,8 +31,9 @@
 #include <linux/dm-ioctl.h>
 
 #include <android-base/logging.h>
+#include <android-base/properties.h>
 #include <android-base/unique_fd.h>
-#include <cutils/properties.h>
+#include <cutils/fs.h>
 #include <fs_mgr.h>
 
 #include "EncryptInplace.h"
@@ -71,26 +72,17 @@
     return true;
 }
 
-static bool read_key(bool create_if_absent, KeyBuffer* key) {
-    auto data_rec = fs_mgr_get_crypt_entry(fstab_default);
-    if (!data_rec) {
-        LOG(ERROR) << "Failed to get data_rec";
-        return false;
-    }
+static bool read_key(struct fstab_rec const* data_rec, bool create_if_absent, KeyBuffer* key) {
     if (!data_rec->key_dir) {
         LOG(ERROR) << "Failed to get key_dir";
         return false;
     }
-    LOG(DEBUG) << "key_dir: " << data_rec->key_dir;
-    if (!android::vold::pathExists(data_rec->key_dir)) {
-        if (mkdir(data_rec->key_dir, 0777) != 0) {
-            PLOG(ERROR) << "Unable to create: " << data_rec->key_dir;
-            return false;
-        }
-        LOG(DEBUG) << "Created: " << data_rec->key_dir;
-    }
     std::string key_dir = data_rec->key_dir;
     auto dir = key_dir + "/key";
+    LOG(DEBUG) << "key_dir/key: " << key;
+    if (!fs_mkdirs(dir.c_str(), 0700)) {
+        PLOG(ERROR) << "Creating directories: " << dir;
+    }
     auto temp = key_dir + "/tmp";
     if (!android::vold::retrieveKey(create_if_absent, dir, temp, key)) return false;
     return true;
@@ -103,7 +95,6 @@
         return KeyBuffer();
     }
     auto res = KeyBuffer() + "AES-256-XTS " + hex_key + " " + real_blkdev.c_str() + " 0";
-    LOG(DEBUG) << "crypt_params: " << std::string(res.data(), res.size());
     return res;
 }
 
@@ -211,108 +202,45 @@
     return true;
 }
 
-#define DATA_PREP_TIMEOUT 1000
-static bool prep_data_fs(void)
-{
-    // NOTE: post_fs_data results in init calling back around to vold, so all
-    // callers to this method must be async
-
-    /* Do the prep of the /data filesystem */
-    property_set("vold.post_fs_data_done", "0");
-    property_set("vold.decrypt", "trigger_post_fs_data");
-    LOG(DEBUG) << "Waiting for post_fs_data_done";
-
-    /* Wait a max of 50 seconds, hopefully it takes much less */
-    for (int i = 0; ; i++) {
-        char p[PROPERTY_VALUE_MAX];
-
-        property_get("vold.post_fs_data_done", p, "0");
-        if (*p == '1') {
-            LOG(INFO) << "Successful data prep";
-            return true;
-        }
-        if (i + 1 == DATA_PREP_TIMEOUT) {
-            LOG(ERROR) << "post_fs_data timed out";
-            return false;
-        }
-        usleep(50000);
-    }
-}
-
-static void async_kick_off() {
-    LOG(DEBUG) << "Asynchronously restarting framework";
-    sleep(2); // TODO: this mirrors cryptfs, but can it be made shorter?
-    property_set("vold.decrypt", "trigger_load_persist_props");
-    if (!prep_data_fs()) return;
-    /* startup service classes main and late_start */
-    property_set("vold.decrypt", "trigger_restart_framework");
-}
-
-bool e4crypt_mount_metadata_encrypted() {
-    LOG(DEBUG) << "e4crypt_mount_default_encrypted";
-    KeyBuffer key;
-    if (!read_key(false, &key)) return false;
-    auto data_rec = fs_mgr_get_crypt_entry(fstab_default);
-    if (!data_rec) {
-        LOG(ERROR) << "Failed to get data_rec";
-        return false;
-    }
-    uint64_t nr_sec;
-    if (!get_number_of_sectors(data_rec->blk_device, &nr_sec)) return false;
-    std::string crypto_blkdev;
-    if (!create_crypto_blk_dev(kDmNameUserdata, nr_sec, DEFAULT_KEY_TARGET_TYPE,
-        default_key_params(data_rec->blk_device, key), &crypto_blkdev)) return false;
-    // FIXME handle the corrupt case
-
-    LOG(DEBUG) << "Restarting filesystem for metadata encryption";
-    mount_via_fs_mgr(data_rec->mount_point, crypto_blkdev.c_str());
-    std::thread(&async_kick_off).detach();
-    return true;
-}
-
-bool e4crypt_enable_crypto() {
-    LOG(DEBUG) << "e4crypt_enable_crypto";
-    char encrypted_state[PROPERTY_VALUE_MAX];
-    property_get("ro.crypto.state", encrypted_state, "");
-    if (strcmp(encrypted_state, "")) {
+bool e4crypt_mount_metadata_encrypted(const std::string& mount_point, bool needs_encrypt) {
+    LOG(DEBUG) << "e4crypt_mount_metadata_encrypted: " << mount_point << " " << needs_encrypt;
+    auto encrypted_state = android::base::GetProperty("ro.crypto.state", "");
+    if (encrypted_state != "") {
         LOG(DEBUG) << "e4crypt_enable_crypto got unexpected starting state: " << encrypted_state;
         return false;
     }
-
-    KeyBuffer key_ref;
-    if (!read_key(true, &key_ref)) return false;
-
-    auto data_rec = fs_mgr_get_crypt_entry(fstab_default);
+    auto data_rec = fs_mgr_get_entry_for_mount_point(fstab_default, mount_point);
     if (!data_rec) {
         LOG(ERROR) << "Failed to get data_rec";
         return false;
     }
+    KeyBuffer key;
+    if (!read_key(data_rec, needs_encrypt, &key)) return false;
     uint64_t nr_sec;
     if (!get_number_of_sectors(data_rec->blk_device, &nr_sec)) return false;
-
     std::string crypto_blkdev;
     if (!create_crypto_blk_dev(kDmNameUserdata, nr_sec, DEFAULT_KEY_TARGET_TYPE,
-        default_key_params(data_rec->blk_device, key_ref), &crypto_blkdev)) return false;
-
-    LOG(INFO) << "Beginning inplace encryption, nr_sec: " << nr_sec;
-    off64_t size_already_done = 0;
-    auto rc = cryptfs_enable_inplace(const_cast<char *>(crypto_blkdev.c_str()),
-                                     data_rec->blk_device, nr_sec, &size_already_done, nr_sec, 0);
-    if (rc != 0) {
-        LOG(ERROR) << "Inplace crypto failed with code: " << rc;
+                               default_key_params(data_rec->blk_device, key), &crypto_blkdev))
         return false;
+    // FIXME handle the corrupt case
+    if (needs_encrypt) {
+        LOG(INFO) << "Beginning inplace encryption, nr_sec: " << nr_sec;
+        off64_t size_already_done = 0;
+        auto rc =
+            cryptfs_enable_inplace(const_cast<char*>(crypto_blkdev.c_str()), data_rec->blk_device,
+                                   nr_sec, &size_already_done, nr_sec, 0, false);
+        if (rc != 0) {
+            LOG(ERROR) << "Inplace crypto failed with code: " << rc;
+            return false;
+        }
+        if (static_cast<uint64_t>(size_already_done) != nr_sec) {
+            LOG(ERROR) << "Inplace crypto only got up to sector: " << size_already_done;
+            return false;
+        }
+        LOG(INFO) << "Inplace encryption complete";
     }
-    if (static_cast<uint64_t>(size_already_done) != nr_sec) {
-        LOG(ERROR) << "Inplace crypto only got up to sector: " << size_already_done;
-        return false;
-    }
-    LOG(INFO) << "Inplace encryption complete";
 
-    property_set("ro.crypto.state", "encrypted");
-    property_set("ro.crypto.type", "file");
-
+    LOG(DEBUG) << "Mounting metadata-encrypted filesystem:" << mount_point;
     mount_via_fs_mgr(data_rec->mount_point, crypto_blkdev.c_str());
-    property_set("vold.decrypt", "trigger_reset_main");
-    std::thread(&async_kick_off).detach();
     return true;
 }
diff --git a/MetadataCrypt.h b/MetadataCrypt.h
index f6634ea..841dc97 100644
--- a/MetadataCrypt.h
+++ b/MetadataCrypt.h
@@ -17,7 +17,8 @@
 #ifndef _METADATA_CRYPT_H
 #define _METADATA_CRYPT_H
 
-bool e4crypt_mount_metadata_encrypted();
-bool e4crypt_enable_crypto();
+#include <string>
+
+bool e4crypt_mount_metadata_encrypted(const std::string& mount_point, bool needs_encrypt);
 
 #endif
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index f7637fd..f4961ce 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -247,16 +247,6 @@
     return translate(VolumeManager::Instance()->shutdown());
 }
 
-binder::Status VoldNativeService::mountAll() {
-    ENFORCE_UID(AID_SYSTEM);
-    ACQUIRE_LOCK;
-
-    struct fstab* fstab = fs_mgr_read_fstab_default();
-    int res = fs_mgr_mount_all(fstab, MOUNT_MODE_DEFAULT);
-    fs_mgr_free_fstab(fstab);
-    return translate(res);
-}
-
 binder::Status VoldNativeService::onUserAdded(int32_t userId, int32_t userSerial) {
     ENFORCE_UID(AID_SYSTEM);
     ACQUIRE_LOCK;
@@ -577,12 +567,12 @@
     ENFORCE_UID(AID_SYSTEM);
     ACQUIRE_CRYPT_LOCK;
 
+    LOG(DEBUG) << "fdeEnable(" << passwordType << ", *, " << encryptionFlags << ")";
     if (e4crypt_is_native()) {
-        if (passwordType != PASSWORD_TYPE_DEFAULT) {
-            return error("Unexpected password type");
-        }
-        return translateBool(e4crypt_enable_crypto());
+        LOG(ERROR) << "e4crypt_is_native, fdeEnable invalid";
+        return error("e4crypt_is_native, fdeEnable invalid");
     }
+    LOG(DEBUG) << "!e4crypt_is_native, spawning fdeEnableInternal";
 
     // Spawn as thread so init can issue commands back to vold without
     // causing deadlock, usually as a result of prep_data_fs.
@@ -665,14 +655,12 @@
     ENFORCE_UID(AID_SYSTEM);
     ACQUIRE_CRYPT_LOCK;
 
-    if (e4crypt_is_native()) {
-        return translateBool(e4crypt_mount_metadata_encrypted());
-    } else {
+    if (!e4crypt_is_native()) {
         // Spawn as thread so init can issue commands back to vold without
         // causing deadlock, usually as a result of prep_data_fs.
         std::thread(&cryptfs_mount_default_encrypted).detach();
-        return ok();
     }
+    return ok();
 }
 
 binder::Status VoldNativeService::initUser0() {
@@ -690,6 +678,20 @@
     return ok();
 }
 
+binder::Status VoldNativeService::mountFstab(const std::string& mountPoint) {
+    ENFORCE_UID(AID_SYSTEM);
+    ACQUIRE_LOCK;
+
+    return translateBool(e4crypt_mount_metadata_encrypted(mountPoint, false));
+}
+
+binder::Status VoldNativeService::encryptFstab(const std::string& mountPoint) {
+    ENFORCE_UID(AID_SYSTEM);
+    ACQUIRE_LOCK;
+
+    return translateBool(e4crypt_mount_metadata_encrypted(mountPoint, true));
+}
+
 binder::Status VoldNativeService::createUserKey(int32_t userId, int32_t userSerial,
         bool ephemeral) {
     ENFORCE_UID(AID_SYSTEM);
diff --git a/VoldNativeService.h b/VoldNativeService.h
index 1359d90..817f815 100644
--- a/VoldNativeService.h
+++ b/VoldNativeService.h
@@ -36,7 +36,6 @@
     binder::Status monitor();
     binder::Status reset();
     binder::Status shutdown();
-    binder::Status mountAll();
 
     binder::Status onUserAdded(int32_t userId, int32_t userSerial);
     binder::Status onUserRemoved(int32_t userId);
@@ -96,6 +95,8 @@
     binder::Status mountDefaultEncrypted();
     binder::Status initUser0();
     binder::Status isConvertibleToFbe(bool* _aidl_return);
+    binder::Status mountFstab(const std::string& mountPoint);
+    binder::Status encryptFstab(const std::string& mountPoint);
 
     binder::Status createUserKey(int32_t userId, int32_t userSerial, bool ephemeral);
     binder::Status destroyUserKey(int32_t userId);
diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl
index 9facaf7..a664dfa 100644
--- a/binder/android/os/IVold.aidl
+++ b/binder/android/os/IVold.aidl
@@ -26,7 +26,6 @@
     void monitor();
     void reset();
     void shutdown();
-    void mountAll();
 
     void onUserAdded(int userId, int userSerial);
     void onUserRemoved(int userId);
@@ -79,6 +78,8 @@
     void mountDefaultEncrypted();
     void initUser0();
     boolean isConvertibleToFbe();
+    void mountFstab(@utf8InCpp String mountPoint);
+    void encryptFstab(@utf8InCpp String mountPoint);
 
     void createUserKey(int userId, int userSerial, boolean ephemeral);
     void destroyUserKey(int userId);
diff --git a/cryptfs.cpp b/cryptfs.cpp
index aa60541..e363835 100644
--- a/cryptfs.cpp
+++ b/cryptfs.cpp
@@ -1974,7 +1974,7 @@
     tot_encryption_size = crypt_ftr->fs_size;
 
     rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev, crypt_ftr->fs_size, &cur_encryption_done,
-                                tot_encryption_size, previously_encrypted_upto);
+                                tot_encryption_size, previously_encrypted_upto, true);
 
     if (rc == ENABLE_INPLACE_ERR_DEV) {
         /* Hack for b/17898962 */
diff --git a/main.cpp b/main.cpp
index 62ea6b7..5525e85 100644
--- a/main.cpp
+++ b/main.cpp
@@ -51,12 +51,14 @@
 using android::base::StringPrintf;
 
 int main(int argc, char** argv) {
+    atrace_set_tracing_enabled(false);
     setenv("ANDROID_LOG_TAGS", "*:v", 1);
     android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
 
+    LOG(INFO) << "Vold 3.0 (the awakening) firing up";
+
     ATRACE_BEGIN("main");
 
-    LOG(INFO) << "Vold 3.0 (the awakening) firing up";
 
     LOG(VERBOSE) << "Detected support for:"
             << (android::vold::IsFilesystemSupported("ext4") ? " ext4" : "")
@@ -113,6 +115,8 @@
     }
     ATRACE_END();
 
+    LOG(DEBUG) << "VoldNativeService::start() completed OK";
+
     ATRACE_BEGIN("NetlinkManager::start");
     if (nm->start()) {
         PLOG(ERROR) << "Unable to start NetlinkManager";
diff --git a/vdc.cpp b/vdc.cpp
index 5ae4cd9..3c449ae 100644
--- a/vdc.cpp
+++ b/vdc.cpp
@@ -44,7 +44,7 @@
     android::sp<android::IBinder> res;
     auto sm = android::defaultServiceManager();
     auto name = android::String16("vold");
-    for (int i = 0; i < 500; i++) {
+    for (int i = 0; i < 5000; i++) {
         res = sm->checkService(name);
         if (res) {
             LOG(VERBOSE) << "Waited " << (i * 10) << "ms for vold";
@@ -101,6 +101,10 @@
         checkStatus(vold->shutdown());
     } else if (args[0] == "cryptfs" && args[1] == "checkEncryption" && args.size() == 3) {
         checkStatus(vold->checkEncryption(args[2]));
+    } else if (args[0] == "cryptfs" && args[1] == "mountFstab" && args.size() == 3) {
+        checkStatus(vold->mountFstab(args[2]));
+    } else if (args[0] == "cryptfs" && args[1] == "encryptFstab" && args.size() == 3) {
+        checkStatus(vold->encryptFstab(args[2]));
     } else {
         LOG(ERROR) << "Raw commands are no longer supported";
         exit(EINVAL);