vold: use unified fstab format

Change vold to use the unified fstab.  This includes both
support for sdcards, and changes to the crypto code to work
with some changes to the fs_mgr library api.

Change-Id: Id5a8aa5b699afe151db6e31aa0d76105f9c95a80
diff --git a/main.cpp b/main.cpp
index 5924fe4..9c75980 100644
--- a/main.cpp
+++ b/main.cpp
@@ -23,10 +23,12 @@
 
 #include <fcntl.h>
 #include <dirent.h>
+#include <fs_mgr.h>
 
 #define LOG_TAG "Vold"
 
 #include "cutils/log.h"
+#include "cutils/properties.h"
 
 #include "VolumeManager.h"
 #include "CommandListener.h"
@@ -37,6 +39,9 @@
 static int process_config(VolumeManager *vm);
 static void coldboot(const char *path);
 
+#define FSTAB_PREFIX "/fstab."
+struct fstab *fstab;
+
 int main() {
 
     VolumeManager *vm;
@@ -142,111 +147,54 @@
     }
 }
 
-static int parse_mount_flags(char *mount_flags)
+static int process_config(VolumeManager *vm)
 {
-    char *save_ptr;
-    int flags = 0;
+    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
+    char propbuf[PROPERTY_VALUE_MAX];
+    int i;
+    int ret = -1;
+    int flags;
 
-    if (strcasestr(mount_flags, "encryptable")) {
-        flags |= VOL_ENCRYPTABLE;
-    }
+    property_get("ro.hardware", propbuf, "");
+    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
 
-    if (strcasestr(mount_flags, "nonremovable")) {
-        flags |= VOL_NONREMOVABLE;
-    }
-
-    return flags;
-}
-
-static int process_config(VolumeManager *vm) {
-    FILE *fp;
-    int n = 0;
-    char line[255];
-
-    if (!(fp = fopen("/etc/vold.fstab", "r"))) {
+    fstab = fs_mgr_read_fstab(fstab_filename);
+    if (!fstab) {
+        SLOGE("failed to open %s\n", fstab_filename);
         return -1;
     }
 
-    while(fgets(line, sizeof(line), fp)) {
-        const char *delim = " \t";
-        char *save_ptr;
-        char *type, *label, *mount_point, *mount_flags, *sysfs_path;
-        int flags;
-
-        n++;
-        line[strlen(line)-1] = '\0';
-
-        if (line[0] == '#' || line[0] == '\0')
-            continue;
-
-        if (!(type = strtok_r(line, delim, &save_ptr))) {
-            SLOGE("Error parsing type");
-            goto out_syntax;
-        }
-        if (!(label = strtok_r(NULL, delim, &save_ptr))) {
-            SLOGE("Error parsing label");
-            goto out_syntax;
-        }
-        if (!(mount_point = strtok_r(NULL, delim, &save_ptr))) {
-            SLOGE("Error parsing mount point");
-            goto out_syntax;
-        }
-
-        if (!strcmp(type, "dev_mount")) {
+    /* Loop through entries looking for ones that vold manages */
+    for (i = 0; i < fstab->num_entries; i++) {
+        if (fs_mgr_is_voldmanaged(&fstab->recs[i])) {
             DirectVolume *dv = NULL;
-            char *part;
+            flags = 0;
 
-            if (!(part = strtok_r(NULL, delim, &save_ptr))) {
-                SLOGE("Error parsing partition");
-                goto out_syntax;
-            }
-            if (strcmp(part, "auto") && atoi(part) == 0) {
-                SLOGE("Partition must either be 'auto' or 1 based index instead of '%s'", part);
-                goto out_syntax;
+            dv = new DirectVolume(vm, fstab->recs[i].label,
+                                  fstab->recs[i].mount_point,
+                                  fstab->recs[i].partnum);
+
+            if (dv->addPath(fstab->recs[i].blk_device)) {
+                SLOGE("Failed to add devpath %s to volume %s",
+                      fstab->recs[i].blk_device, fstab->recs[i].label);
+                goto out_fail;
             }
 
-            if (!strcmp(part, "auto")) {
-                dv = new DirectVolume(vm, label, mount_point, -1);
-            } else {
-                dv = new DirectVolume(vm, label, mount_point, atoi(part));
+            /* Set any flags that might be set for this volume */
+            if (fs_mgr_is_nonremovable(&fstab->recs[i])) {
+                flags |= VOL_NONREMOVABLE;
             }
-
-            while ((sysfs_path = strtok_r(NULL, delim, &save_ptr))) {
-                if (*sysfs_path != '/') {
-                    /* If the first character is not a '/', it must be flags */
-                    break;
-                }
-                if (dv->addPath(sysfs_path)) {
-                    SLOGE("Failed to add devpath %s to volume %s", sysfs_path,
-                         label);
-                    goto out_fail;
-                }
+            if (fs_mgr_is_encryptable(&fstab->recs[i])) {
+                flags |= VOL_ENCRYPTABLE;
             }
-
-            /* If sysfs_path is non-null at this point, then it contains
-             * the optional flags for this volume
-             */
-            if (sysfs_path)
-                flags = parse_mount_flags(sysfs_path);
-            else
-                flags = 0;
             dv->setFlags(flags);
 
             vm->addVolume(dv);
-        } else if (!strcmp(type, "map_mount")) {
-        } else {
-            SLOGE("Unknown type '%s'", type);
-            goto out_syntax;
         }
     }
 
-    fclose(fp);
-    return 0;
+    ret = 0;
 
-out_syntax:
-    SLOGE("Syntax error on config line %d", n);
-    errno = -EINVAL;
 out_fail:
-    fclose(fp);
-    return -1;   
+    return ret;
 }