diff --git a/Android.mk b/Android.mk
index c913a1e..cc667ee 100644
--- a/Android.mk
+++ b/Android.mk
@@ -6,8 +6,6 @@
 	VoldCommand.cpp \
 	NetlinkManager.cpp \
 	NetlinkHandler.cpp \
-	Volume.cpp \
-	DirectVolume.cpp \
 	Process.cpp \
 	Ext4.cpp \
 	Fat.cpp \
@@ -17,7 +15,14 @@
 	CheckBattery.cpp \
 	VoldUtil.c \
 	fstrim.c \
-	cryptfs.c
+	cryptfs.c \
+	Disk.cpp \
+	VolumeBase.cpp \
+	PublicVolume.cpp \
+	PrivateVolume.cpp \
+	EmulatedVolume.cpp \
+	Utils.cpp \
+	MoveTask.cpp \
 
 common_c_includes := \
 	system/extras/ext4_utils \
@@ -42,7 +47,8 @@
 	libselinux \
 	libutils \
 	libhardware \
-	libsoftkeymaster
+	libsoftkeymaster \
+	libbase \
 
 common_static_libraries := \
 	libfs_mgr \
@@ -52,7 +58,7 @@
 	libbatteryservice
 
 vold_conlyflags := -std=c11
-vold_cflags := -Werror -Wall -Wno-missing-field-initializers
+vold_cflags := -Werror -Wall -Wno-missing-field-initializers -Wno-unused-variable -Wno-unused-parameter
 
 include $(CLEAR_VARS)
 
diff --git a/CommandListener.cpp b/CommandListener.cpp
index c66b9d2..5021fb1 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -34,12 +34,14 @@
 
 #include "CommandListener.h"
 #include "VolumeManager.h"
+#include "VolumeBase.h"
 #include "ResponseCode.h"
 #include "Process.h"
 #include "Loop.h"
 #include "Devmapper.h"
 #include "cryptfs.h"
 #include "fstrim.h"
+#include "MoveTask.h"
 
 #define DUMP_ARGS 0
 
@@ -86,6 +88,14 @@
 void CommandListener::dumpArgs(int /*argc*/, char ** /*argv*/, int /*argObscure*/) { }
 #endif
 
+int CommandListener::sendGenericOkFail(SocketClient *cli, int cond) {
+    if (!cond) {
+        return cli->sendMsg(ResponseCode::CommandOkay, "Command succeeded", false);
+    } else {
+        return cli->sendMsg(ResponseCode::OperationFailed, "Command failed", false);
+    }
+}
+
 CommandListener::DumpCmd::DumpCmd() :
                  VoldCommand("dump") {
 }
@@ -129,99 +139,108 @@
     }
 
     VolumeManager *vm = VolumeManager::Instance();
-    int rc = 0;
+    std::lock_guard<std::mutex> lock(vm->getLock());
 
-    if (!strcmp(argv[1], "list")) {
-        bool broadcast = argc >= 3 && !strcmp(argv[2], "broadcast");
-        return vm->listVolumes(cli, broadcast);
-    } else if (!strcmp(argv[1], "debug")) {
-        if (argc != 3 || (argc == 3 && (strcmp(argv[2], "off") && strcmp(argv[2], "on")))) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume debug <off/on>", false);
-            return 0;
-        }
-        vm->setDebug(!strcmp(argv[2], "on") ? true : false);
-    } else if (!strcmp(argv[1], "mount")) {
-        if (argc != 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume mount <path>", false);
-            return 0;
-        }
-        rc = vm->mountVolume(argv[2]);
-    } else if (!strcmp(argv[1], "unmount")) {
-        if (argc < 3 || argc > 4 ||
-           ((argc == 4 && strcmp(argv[3], "force")) &&
-            (argc == 4 && strcmp(argv[3], "force_and_revert")))) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume unmount <path> [force|force_and_revert]", false);
-            return 0;
+    // TODO: tease out methods not directly related to volumes
+
+    std::string cmd(argv[1]);
+    if (cmd == "reset") {
+        return sendGenericOkFail(cli, vm->reset());
+
+    } else if (cmd == "shutdown") {
+        return sendGenericOkFail(cli, vm->shutdown());
+
+    } else if (cmd == "debug") {
+        return sendGenericOkFail(cli, vm->setDebug(true));
+
+    } else if (cmd == "partition" && argc > 3) {
+        // partition [diskId] [public|private|mixed] [ratio]
+        std::string id(argv[2]);
+        auto disk = vm->findDisk(id);
+        if (disk == nullptr) {
+            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown disk", false);
         }
 
-        bool force = false;
-        bool revert = false;
-        if (argc >= 4 && !strcmp(argv[3], "force")) {
-            force = true;
-        } else if (argc >= 4 && !strcmp(argv[3], "force_and_revert")) {
-            force = true;
-            revert = true;
-        }
-        rc = vm->unmountVolume(argv[2], force, revert);
-    } else if (!strcmp(argv[1], "format")) {
-        if (argc < 3 || argc > 4 ||
-            (argc == 4 && strcmp(argv[3], "wipe"))) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume format <path> [wipe]", false);
-            return 0;
-        }
-        bool wipe = false;
-        if (argc >= 4 && !strcmp(argv[3], "wipe")) {
-            wipe = true;
-        }
-        rc = vm->formatVolume(argv[2], wipe);
-    } else if (!strcmp(argv[1], "share")) {
-        if (argc != 4) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError,
-                    "Usage: volume share <path> <method>", false);
-            return 0;
-        }
-        rc = vm->shareVolume(argv[2], argv[3]);
-    } else if (!strcmp(argv[1], "unshare")) {
-        if (argc != 4) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError,
-                    "Usage: volume unshare <path> <method>", false);
-            return 0;
-        }
-        rc = vm->unshareVolume(argv[2], argv[3]);
-    } else if (!strcmp(argv[1], "shared")) {
-        bool enabled = false;
-        if (argc != 4) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError,
-                    "Usage: volume shared <path> <method>", false);
-            return 0;
-        }
-
-        if (vm->shareEnabled(argv[2], argv[3], &enabled)) {
-            cli->sendMsg(
-                    ResponseCode::OperationFailed, "Failed to determine share enable state", true);
+        std::string type(argv[3]);
+        if (type == "public") {
+            return sendGenericOkFail(cli, disk->partitionPublic());
+        } else if (type == "private") {
+            return sendGenericOkFail(cli, disk->partitionPrivate());
+        } else if (type == "mixed") {
+            if (argc < 4) {
+                return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);
+            }
+            int frac = atoi(argv[4]);
+            return sendGenericOkFail(cli, disk->partitionMixed(frac));
         } else {
-            cli->sendMsg(ResponseCode::ShareEnabledResult,
-                    (enabled ? "Share enabled" : "Share disabled"), false);
+            return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);
         }
-        return 0;
-    } else if (!strcmp(argv[1], "mkdirs")) {
-        if (argc != 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume mkdirs <path>", false);
-            return 0;
+
+    } else if (cmd == "mkdirs" && argc > 2) {
+        // mkdirs [path]
+        return sendGenericOkFail(cli, vm->mkdirs(argv[2]));
+
+    } else if (cmd == "start_user" && argc > 2) {
+        // start_user [user]
+        return sendGenericOkFail(cli, vm->startUser(atoi(argv[2])));
+
+    } else if (cmd == "cleanup_user" && argc > 2) {
+        // cleanup_user [user]
+        return sendGenericOkFail(cli, vm->cleanupUser(atoi(argv[2])));
+
+    } else if (cmd == "mount" && argc > 2) {
+        // mount [volId] [flags] [user]
+        std::string id(argv[2]);
+        auto vol = vm->findVolume(id);
+        if (vol == nullptr) {
+            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
         }
-        rc = vm->mkdirs(argv[2]);
-    } else {
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume cmd", false);
+
+        int mountFlags = (argc > 3) ? atoi(argv[3]) : 0;
+        userid_t mountUserId = (argc > 4) ? atoi(argv[4]) : -1;
+
+        if (mountFlags & android::vold::VolumeBase::MountFlags::kPrimary) {
+            vm->setPrimary(vol);
+        }
+
+        vol->setMountFlags(mountFlags);
+        vol->setMountUserId(mountUserId);
+
+        return sendGenericOkFail(cli, vol->mount());
+
+    } else if (cmd == "unmount" && argc > 2) {
+        // unmount [volId]
+        std::string id(argv[2]);
+        auto vol = vm->findVolume(id);
+        if (vol == nullptr) {
+            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
+        }
+
+        return sendGenericOkFail(cli, vol->unmount());
+
+    } else if (cmd == "format" && argc > 2) {
+        // format [volId]
+        std::string id(argv[2]);
+        auto vol = vm->findVolume(id);
+        if (vol == nullptr) {
+            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
+        }
+
+        return sendGenericOkFail(cli, vol->format());
+
+    } else if (cmd == "move_storage" && argc > 3) {
+        // move_storage [fromVolId] [toVolId]
+        auto fromVol = vm->findVolume(std::string(argv[2]));
+        auto toVol = vm->findVolume(std::string(argv[3]));
+        if (fromVol == nullptr || toVol == nullptr) {
+            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
+        }
+
+        (new android::vold::MoveTask(fromVol, toVol))->start();
+        return sendGenericOkFail(cli, 0);
     }
 
-    if (!rc) {
-        cli->sendMsg(ResponseCode::CommandOkay, "volume operation succeeded", false);
-    } else {
-        rc = ResponseCode::convertFromErrno();
-        cli->sendMsg(rc, "volume operation failed", true);
-    }
-
-    return 0;
+    return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);
 }
 
 CommandListener::StorageCmd::StorageCmd() :
@@ -346,8 +365,8 @@
     if (!strcmp(argv[1], "list")) {
         dumpArgs(argc, argv, -1);
 
-        listAsecsInDirectory(cli, Volume::SEC_ASECDIR_EXT);
-        listAsecsInDirectory(cli, Volume::SEC_ASECDIR_INT);
+        listAsecsInDirectory(cli, VolumeManager::SEC_ASECDIR_EXT);
+        listAsecsInDirectory(cli, VolumeManager::SEC_ASECDIR_INT);
     } else if (!strcmp(argv[1], "create")) {
         dumpArgs(argc, argv, 5);
         if (argc != 8) {
@@ -616,7 +635,7 @@
             if (rc == 0) {
                 break;
             } else if (tries == 0) {
-                Process::killProcessesWithOpenFiles(DATA_MNT_POINT, 2);
+                Process::killProcessesWithOpenFiles(DATA_MNT_POINT, SIGKILL);
             }
         }
     } else if (!strcmp(argv[1], "changepw")) {
diff --git a/CommandListener.h b/CommandListener.h
index 0bd51d2..8cc1a04 100644
--- a/CommandListener.h
+++ b/CommandListener.h
@@ -18,6 +18,7 @@
 #define _COMMANDLISTENER_H__
 
 #include <sysutils/FrameworkListener.h>
+#include <utils/Errors.h>
 #include "VoldCommand.h"
 
 class CommandListener : public FrameworkListener {
@@ -27,6 +28,7 @@
 
 private:
     static void dumpArgs(int argc, char **argv, int argObscure);
+    static int sendGenericOkFail(SocketClient *cli, int cond);
 
     class DumpCmd : public VoldCommand {
     public:
diff --git a/Devmapper.cpp b/Devmapper.cpp
index 703902f..703eade 100644
--- a/Devmapper.cpp
+++ b/Devmapper.cpp
@@ -55,7 +55,7 @@
     }
 
     int fd;
-    if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
+    if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
         SLOGE("Error opening devmapper (%s)", strerror(errno));
         free(buffer);
         free(buffer2);
@@ -138,7 +138,7 @@
     }
 
     int fd;
-    if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
+    if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
         SLOGE("Error opening devmapper (%s)", strerror(errno));
         free(buffer);
         return -1;
@@ -172,7 +172,7 @@
     }
 
     int fd;
-    if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
+    if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
         SLOGE("Error opening devmapper (%s)", strerror(errno));
         free(buffer);
         return -1;
@@ -269,7 +269,7 @@
     }
 
     int fd;
-    if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
+    if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
         SLOGE("Error opening devmapper (%s)", strerror(errno));
         free(buffer);
         return -1;
diff --git a/DirectVolume.cpp b/DirectVolume.cpp
deleted file mode 100644
index 64d7744..0000000
--- a/DirectVolume.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fnmatch.h>
-
-#include <linux/kdev_t.h>
-
-#define LOG_TAG "DirectVolume"
-
-#include <cutils/log.h>
-#include <sysutils/NetlinkEvent.h>
-
-#include "DirectVolume.h"
-#include "VolumeManager.h"
-#include "ResponseCode.h"
-#include "cryptfs.h"
-
-// #define PARTITION_DEBUG
-
-PathInfo::PathInfo(const char *p)
-{
-    warned = false;
-    pattern = strdup(p);
-
-    if (!strchr(pattern, '*')) {
-        patternType = prefix;
-    } else {
-        patternType = wildcard;
-    }
-}
-
-PathInfo::~PathInfo()
-{
-    free(pattern);
-}
-
-bool PathInfo::match(const char *path)
-{
-    switch (patternType) {
-    case prefix:
-    {
-        bool ret = (strncmp(path, pattern, strlen(pattern)) == 0);
-        if (!warned && ret && (strlen(pattern) != strlen(path))) {
-            SLOGW("Deprecated implied prefix pattern detected, please use '%s*' instead", pattern);
-            warned = true;
-        }
-        return ret;
-    }
-    case wildcard:
-        return fnmatch(pattern, path, 0) == 0;
-    }
-    SLOGE("Bad matching type");
-    return false;
-}
-
-DirectVolume::DirectVolume(VolumeManager *vm, const fstab_rec* rec, int flags) :
-        Volume(vm, rec, flags) {
-    mPaths = new PathCollection();
-    for (int i = 0; i < MAX_PARTITIONS; i++)
-        mPartMinors[i] = -1;
-    mPendingPartCount = 0;
-    mDiskMajor = -1;
-    mDiskMinor = -1;
-    mDiskNumParts = 0;
-    mIsDecrypted = 0;
-
-    if (strcmp(rec->mount_point, "auto") != 0) {
-        ALOGE("Vold managed volumes must have auto mount point; ignoring %s",
-              rec->mount_point);
-    }
-
-    char mount[PATH_MAX];
-
-    snprintf(mount, PATH_MAX, "%s/%s", Volume::MEDIA_DIR, rec->label);
-    mMountpoint = strdup(mount);
-    snprintf(mount, PATH_MAX, "%s/%s", Volume::FUSE_DIR, rec->label);
-    mFuseMountpoint = strdup(mount);
-
-    setState(Volume::State_NoMedia);
-}
-
-DirectVolume::~DirectVolume() {
-    PathCollection::iterator it;
-
-    for (it = mPaths->begin(); it != mPaths->end(); ++it)
-        delete *it;
-    delete mPaths;
-}
-
-int DirectVolume::addPath(const char *path) {
-    mPaths->push_back(new PathInfo(path));
-    return 0;
-}
-
-dev_t DirectVolume::getDiskDevice() {
-    return MKDEV(mDiskMajor, mDiskMinor);
-}
-
-dev_t DirectVolume::getShareDevice() {
-    if (mPartIdx != -1) {
-        return MKDEV(mDiskMajor, mPartIdx);
-    } else {
-        return MKDEV(mDiskMajor, mDiskMinor);
-    }
-}
-
-void DirectVolume::handleVolumeShared() {
-    setState(Volume::State_Shared);
-}
-
-void DirectVolume::handleVolumeUnshared() {
-    setState(Volume::State_Idle);
-}
-
-int DirectVolume::handleBlockEvent(NetlinkEvent *evt) {
-    const char *dp = evt->findParam("DEVPATH");
-
-    PathCollection::iterator  it;
-    for (it = mPaths->begin(); it != mPaths->end(); ++it) {
-        if ((*it)->match(dp)) {
-            /* We can handle this disk */
-            int action = evt->getAction();
-            const char *devtype = evt->findParam("DEVTYPE");
-
-            if (action == NetlinkEvent::NlActionAdd) {
-                int major = atoi(evt->findParam("MAJOR"));
-                int minor = atoi(evt->findParam("MINOR"));
-                char nodepath[255];
-
-                snprintf(nodepath,
-                         sizeof(nodepath), "/dev/block/vold/%d:%d",
-                         major, minor);
-                if (createDeviceNode(nodepath, major, minor)) {
-                    SLOGE("Error making device node '%s' (%s)", nodepath,
-                                                               strerror(errno));
-                }
-                if (!strcmp(devtype, "disk")) {
-                    handleDiskAdded(dp, evt);
-                } else {
-                    handlePartitionAdded(dp, evt);
-                }
-                /* Send notification iff disk is ready (ie all partitions found) */
-                if (getState() == Volume::State_Idle) {
-                    char msg[255];
-
-                    snprintf(msg, sizeof(msg),
-                             "Volume %s %s disk inserted (%d:%d)", getLabel(),
-                             getFuseMountpoint(), mDiskMajor, mDiskMinor);
-                    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeDiskInserted,
-                                                         msg, false);
-                }
-            } else if (action == NetlinkEvent::NlActionRemove) {
-                if (!strcmp(devtype, "disk")) {
-                    handleDiskRemoved(dp, evt);
-                } else {
-                    handlePartitionRemoved(dp, evt);
-                }
-            } else if (action == NetlinkEvent::NlActionChange) {
-                if (!strcmp(devtype, "disk")) {
-                    handleDiskChanged(dp, evt);
-                } else {
-                    handlePartitionChanged(dp, evt);
-                }
-            } else {
-                    SLOGW("Ignoring non add/remove/change event");
-            }
-
-            return 0;
-        }
-    }
-    errno = ENODEV;
-    return -1;
-}
-
-void DirectVolume::handleDiskAdded(const char * /*devpath*/,
-                                   NetlinkEvent *evt) {
-    mDiskMajor = atoi(evt->findParam("MAJOR"));
-    mDiskMinor = atoi(evt->findParam("MINOR"));
-
-    const char *tmp = evt->findParam("NPARTS");
-    if (tmp) {
-        mDiskNumParts = atoi(tmp);
-    } else {
-        SLOGW("Kernel block uevent missing 'NPARTS'");
-        mDiskNumParts = 1;
-    }
-
-    mPendingPartCount = mDiskNumParts;
-    for (int i = 0; i < MAX_PARTITIONS; i++)
-        mPartMinors[i] = -1;
-
-    if (mDiskNumParts == 0) {
-#ifdef PARTITION_DEBUG
-        SLOGD("Dv::diskIns - No partitions - good to go son!");
-#endif
-        setState(Volume::State_Idle);
-    } else {
-#ifdef PARTITION_DEBUG
-        SLOGD("Dv::diskIns - waiting for %d pending partitions", mPendingPartCount);
-#endif
-        setState(Volume::State_Pending);
-    }
-}
-
-void DirectVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
-
-    int part_num;
-
-    const char *tmp = evt->findParam("PARTN");
-
-    if (tmp) {
-        part_num = atoi(tmp);
-    } else {
-        SLOGW("Kernel block uevent missing 'PARTN'");
-        part_num = 1;
-    }
-
-    if (part_num > MAX_PARTITIONS || part_num < 1) {
-        SLOGE("Invalid 'PARTN' value");
-        return;
-    }
-
-    if (part_num > mDiskNumParts) {
-        mDiskNumParts = part_num;
-    }
-
-    if (major != mDiskMajor) {
-        SLOGE("Partition '%s' has a different major than its disk!", devpath);
-        return;
-    }
-#ifdef PARTITION_DEBUG
-    SLOGD("Dv:partAdd: part_num = %d, minor = %d\n", part_num, minor);
-#endif
-    if (part_num >= MAX_PARTITIONS) {
-        SLOGE("Dv:partAdd: ignoring part_num = %d (max: %d)\n", part_num, MAX_PARTITIONS-1);
-    } else {
-        if ((mPartMinors[part_num - 1] == -1) && mPendingPartCount)
-            mPendingPartCount--;
-        mPartMinors[part_num -1] = minor;
-    }
-
-    if (!mPendingPartCount) {
-#ifdef PARTITION_DEBUG
-        SLOGD("Dv:partAdd: Got all partitions - ready to rock!");
-#endif
-        if (getState() != Volume::State_Formatting) {
-            setState(Volume::State_Idle);
-            if (mRetryMount == true) {
-                mRetryMount = false;
-                mountVol();
-            }
-        }
-    } else {
-#ifdef PARTITION_DEBUG
-        SLOGD("Dv:partAdd: pending %d disk", mPendingPartCount);
-#endif
-    }
-}
-
-void DirectVolume::handleDiskChanged(const char * /*devpath*/,
-                                     NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
-
-    if ((major != mDiskMajor) || (minor != mDiskMinor)) {
-        return;
-    }
-
-    SLOGI("Volume %s disk has changed", getLabel());
-    const char *tmp = evt->findParam("NPARTS");
-    if (tmp) {
-        mDiskNumParts = atoi(tmp);
-    } else {
-        SLOGW("Kernel block uevent missing 'NPARTS'");
-        mDiskNumParts = 1;
-    }
-
-    mPendingPartCount = mDiskNumParts;
-    for (int i = 0; i < MAX_PARTITIONS; i++)
-        mPartMinors[i] = -1;
-
-    if (getState() != Volume::State_Formatting) {
-        if (mDiskNumParts == 0) {
-            setState(Volume::State_Idle);
-        } else {
-            setState(Volume::State_Pending);
-        }
-    }
-}
-
-void DirectVolume::handlePartitionChanged(const char * /*devpath*/,
-                                          NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
-    SLOGD("Volume %s %s partition %d:%d changed\n", getLabel(), getMountpoint(), major, minor);
-}
-
-void DirectVolume::handleDiskRemoved(const char * /*devpath*/,
-                                     NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
-    char msg[255];
-    bool enabled;
-
-    SLOGD("Volume %s %s disk %d:%d removed\n", getLabel(), getMountpoint(), major, minor);
-    if ((dev_t) MKDEV(major, minor) == mCurrentlyMountedKdev) {
-        /*
-         * Yikes, our mounted disk is going away!
-         */
-
-        doUnmount(major, minor);
-    } else if (mVm->shareEnabled(getLabel(), "ums", &enabled) == 0 && enabled) {
-        mVm->unshareVolume(getLabel(), "ums");
-    }
-
-    snprintf(msg, sizeof(msg), "Volume %s %s disk removed (%d:%d)",
-             getLabel(), getFuseMountpoint(), major, minor);
-    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeDiskRemoved,
-                                             msg, false);
-    setState(Volume::State_NoMedia);
-}
-
-void DirectVolume::handlePartitionRemoved(const char * /*devpath*/,
-                                          NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
-    char msg[255];
-    int state;
-
-    SLOGD("Volume %s %s partition %d:%d removed\n", getLabel(), getMountpoint(), major, minor);
-
-    /*
-     * The framework doesn't need to get notified of
-     * partition removal unless it's mounted. Otherwise
-     * the removal notification will be sent on the Disk
-     * itself
-     */
-    state = getState();
-    if (state != Volume::State_Mounted && state != Volume::State_Shared) {
-        return;
-    }
-
-    if ((dev_t) MKDEV(major, minor) == mCurrentlyMountedKdev) {
-        /*
-         * Yikes, our mounted partition is going away!
-         */
-        doUnmount(major, minor);
-    } else if (state == Volume::State_Shared) {
-        /* removed during mass storage */
-        snprintf(msg, sizeof(msg), "Volume %s bad removal (%d:%d)",
-                 getLabel(), major, minor);
-        mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeBadRemoval,
-                                             msg, false);
-
-        if (mVm->unshareVolume(getLabel(), "ums")) {
-            SLOGE("Failed to unshare volume on bad removal (%s)",
-                strerror(errno));
-        } else {
-            SLOGD("Crisis averted");
-        }
-    }
-}
-
-void DirectVolume::doUnmount(int major, int minor) {
-    char msg[255];
-    bool providesAsec = (getFlags() & VOL_PROVIDES_ASEC) != 0;
-    if (providesAsec && mVm->cleanupAsec(this, true)) {
-        SLOGE("Failed to cleanup ASEC - unmount will probably fail!");
-    }
-
-    snprintf(msg, sizeof(msg), "Volume %s %s bad removal (%d:%d)",
-                getLabel(), getFuseMountpoint(), major, minor);
-    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeBadRemoval,
-                                            msg, false);
-
-    if (Volume::unmountVol(true, false)) {
-        SLOGE("Failed to unmount volume on bad removal (%s)",
-                strerror(errno));
-        // XXX: At this point we're screwed for now
-    } else {
-        SLOGD("Crisis averted");
-    }
-}
-
-/*
- * Called from base to get a list of devicenodes for mounting
- */
-int DirectVolume::getDeviceNodes(dev_t *devs, int max) {
-
-    if (mPartIdx == -1) {
-        // If the disk has no partitions, try the disk itself
-        if (!mDiskNumParts) {
-            devs[0] = MKDEV(mDiskMajor, mDiskMinor);
-            return 1;
-        }
-
-        int i;
-        for (i = 0; i < mDiskNumParts; i++) {
-            if (i == max)
-                break;
-            devs[i] = MKDEV(mDiskMajor, mPartMinors[i]);
-        }
-        return mDiskNumParts;
-    }
-    devs[0] = MKDEV(mDiskMajor, mPartMinors[mPartIdx -1]);
-    return 1;
-}
-
-/*
- * Called from base to update device info,
- * e.g. When setting up an dm-crypt mapping for the sd card.
- */
-int DirectVolume::updateDeviceInfo(char *new_path, int new_major, int new_minor)
-{
-    PathCollection::iterator it;
-
-    if (mPartIdx == -1) {
-        SLOGE("Can only change device info on a partition\n");
-        return -1;
-    }
-
-    /*
-     * This is to change the sysfs path associated with a partition, in particular,
-     * for an internal SD card partition that is encrypted.  Thus, the list is
-     * expected to be only 1 entry long.  Check that and bail if not.
-     */
-    if (mPaths->size() != 1) {
-        SLOGE("Cannot change path if there are more than one for a volume\n");
-        return -1;
-    }
-
-    it = mPaths->begin();
-    delete *it; /* Free the string storage */
-    mPaths->erase(it); /* Remove it from the list */
-    addPath(new_path); /* Put the new path on the list */
-
-    /* Save away original info so we can restore it when doing factory reset.
-     * Then, when doing the format, it will format the original device in the
-     * clear, otherwise it just formats the encrypted device which is not
-     * readable when the device boots unencrypted after the reset.
-     */
-    mOrigDiskMajor = mDiskMajor;
-    mOrigDiskMinor = mDiskMinor;
-    mOrigPartIdx = mPartIdx;
-    memcpy(mOrigPartMinors, mPartMinors, sizeof(mPartMinors));
-
-    mDiskMajor = new_major;
-    mDiskMinor = new_minor;
-    /* Ugh, virual block devices don't use minor 0 for whole disk and minor > 0 for
-     * partition number.  They don't have partitions, they are just virtual block
-     * devices, and minor number 0 is the first dm-crypt device.  Luckily the first
-     * dm-crypt device is for the userdata partition, which gets minor number 0, and
-     * it is not managed by vold.  So the next device is minor number one, which we
-     * will call partition one.
-     */
-    mPartIdx = new_minor;
-    mPartMinors[new_minor-1] = new_minor;
-
-    mIsDecrypted = 1;
-
-    return 0;
-}
-
-/*
- * Called from base to revert device info to the way it was before a
- * crypto mapping was created for it.
- */
-void DirectVolume::revertDeviceInfo(void)
-{
-    if (mIsDecrypted) {
-        mDiskMajor = mOrigDiskMajor;
-        mDiskMinor = mOrigDiskMinor;
-        mPartIdx = mOrigPartIdx;
-        memcpy(mPartMinors, mOrigPartMinors, sizeof(mPartMinors));
-
-        mIsDecrypted = 0;
-    }
-
-    return;
-}
-
-/*
- * Called from base to give cryptfs all the info it needs to encrypt eligible volumes
- */
-int DirectVolume::getVolInfo(struct volume_info *v)
-{
-    strcpy(v->label, mLabel);
-    strcpy(v->mnt_point, mMountpoint);
-    v->flags = getFlags();
-    /* Other fields of struct volume_info are filled in by the caller or cryptfs.c */
-
-    return 0;
-}
diff --git a/DirectVolume.h b/DirectVolume.h
deleted file mode 100644
index 96f46af..0000000
--- a/DirectVolume.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _DEVICEVOLUME_H
-#define _DEVICEVOLUME_H
-
-#include <utils/List.h>
-
-#include "Volume.h"
-
-class PathInfo {
-public:
-	PathInfo(const char *pattern);
-	~PathInfo();
-	bool match(const char *path);
-private:
-	bool warned;
-	char *pattern;
-	enum PatternType { prefix, wildcard };
-	PatternType patternType;
-};
-
-typedef android::List<PathInfo *> PathCollection;
-
-class DirectVolume : public Volume {
-public:
-    static const int MAX_PARTITIONS = 32;
-protected:
-    const char* mMountpoint;
-    const char* mFuseMountpoint;
-
-    PathCollection *mPaths;
-    int            mDiskMajor;
-    int            mDiskMinor;
-    int            mPartMinors[MAX_PARTITIONS];
-    int            mOrigDiskMajor;
-    int            mOrigDiskMinor;
-    int            mOrigPartMinors[MAX_PARTITIONS];
-    int            mDiskNumParts;
-    int            mPendingPartCount;
-    int            mIsDecrypted;
-
-public:
-    DirectVolume(VolumeManager *vm, const fstab_rec* rec, int flags);
-    virtual ~DirectVolume();
-
-    int addPath(const char *path);
-
-    const char *getMountpoint() { return mMountpoint; }
-    const char *getFuseMountpoint() { return mFuseMountpoint; }
-
-    int handleBlockEvent(NetlinkEvent *evt);
-    dev_t getDiskDevice();
-    dev_t getShareDevice();
-    void handleVolumeShared();
-    void handleVolumeUnshared();
-    int getVolInfo(struct volume_info *v);
-
-protected:
-    int getDeviceNodes(dev_t *devs, int max);
-    int updateDeviceInfo(char *new_path, int new_major, int new_minor);
-    virtual void revertDeviceInfo(void);
-    int isDecrypted() { return mIsDecrypted; }
-
-private:
-    void handleDiskAdded(const char *devpath, NetlinkEvent *evt);
-    void handleDiskRemoved(const char *devpath, NetlinkEvent *evt);
-    void handleDiskChanged(const char *devpath, NetlinkEvent *evt);
-    void handlePartitionAdded(const char *devpath, NetlinkEvent *evt);
-    void handlePartitionRemoved(const char *devpath, NetlinkEvent *evt);
-    void handlePartitionChanged(const char *devpath, NetlinkEvent *evt);
-
-    int doMountVfat(const char *deviceNode, const char *mountPoint);
-    void doUnmount(int major, int minor);
-
-};
-
-typedef android::List<DirectVolume *> DirectVolumeCollection;
-
-#endif
diff --git a/Disk.cpp b/Disk.cpp
new file mode 100644
index 0000000..218c251
--- /dev/null
+++ b/Disk.cpp
@@ -0,0 +1,498 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Disk.h"
+#include "PublicVolume.h"
+#include "PrivateVolume.h"
+#include "Utils.h"
+#include "VolumeBase.h"
+#include "VolumeManager.h"
+#include "ResponseCode.h"
+
+#include <base/file.h>
+#include <base/stringprintf.h>
+#include <base/logging.h>
+#include <diskconfig/diskconfig.h>
+
+#include <vector>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+
+#define ENTIRE_DEVICE_FALLBACK 0
+
+using android::base::ReadFileToString;
+using android::base::WriteStringToFile;
+using android::base::StringPrintf;
+
+namespace android {
+namespace vold {
+
+static const char* kSgdiskPath = "/system/bin/sgdisk";
+static const char* kSgdiskToken = " \t\n";
+
+static const char* kSysfsMmcMaxMinors = "/sys/module/mmcblk/parameters/perdev_minors";
+
+static const unsigned int kMajorBlockScsiA = 8;
+static const unsigned int kMajorBlockScsiB = 65;
+static const unsigned int kMajorBlockScsiC = 66;
+static const unsigned int kMajorBlockScsiD = 67;
+static const unsigned int kMajorBlockScsiE = 68;
+static const unsigned int kMajorBlockScsiF = 69;
+static const unsigned int kMajorBlockScsiG = 70;
+static const unsigned int kMajorBlockScsiH = 71;
+static const unsigned int kMajorBlockScsiI = 128;
+static const unsigned int kMajorBlockScsiJ = 129;
+static const unsigned int kMajorBlockScsiK = 130;
+static const unsigned int kMajorBlockScsiL = 131;
+static const unsigned int kMajorBlockScsiM = 132;
+static const unsigned int kMajorBlockScsiN = 133;
+static const unsigned int kMajorBlockScsiO = 134;
+static const unsigned int kMajorBlockScsiP = 135;
+static const unsigned int kMajorBlockMmc = 179;
+
+static const char* kGptBasicData = "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7";
+static const char* kGptAndroidMeta = "19A710A2-B3CA-11E4-B026-10604B889DCF";
+static const char* kGptAndroidExpand = "193D1EA4-B3CA-11E4-B075-10604B889DCF";
+
+static const char* kKeyPath = "/data/misc/vold";
+
+enum class Table {
+    kUnknown,
+    kMbr,
+    kGpt,
+};
+
+Disk::Disk(const std::string& eventPath, dev_t device,
+        const std::string& nickname, int flags) :
+        mDevice(device), mSize(-1), mNickname(nickname), mFlags(flags), mCreated(
+                false), mJustPartitioned(false) {
+    mId = StringPrintf("disk:%u,%u", major(device), minor(device));
+    mEventPath = eventPath;
+    mSysPath = StringPrintf("/sys/%s", eventPath.c_str());
+    mDevPath = StringPrintf("/dev/block/vold/%s", mId.c_str());
+    CreateDeviceNode(mDevPath, mDevice);
+}
+
+Disk::~Disk() {
+    CHECK(!mCreated);
+    DestroyDeviceNode(mDevPath);
+}
+
+std::shared_ptr<VolumeBase> Disk::findVolume(const std::string& id) {
+    for (auto vol : mVolumes) {
+        if (vol->getId() == id) {
+            return vol;
+        }
+        auto stackedVol = vol->findVolume(id);
+        if (stackedVol != nullptr) {
+            return stackedVol;
+        }
+    }
+    return nullptr;
+}
+
+status_t Disk::create() {
+    CHECK(!mCreated);
+    mCreated = true;
+    notifyEvent(ResponseCode::DiskCreated, StringPrintf("%d", mFlags));
+    readMetadata();
+    readPartitions();
+    return OK;
+}
+
+status_t Disk::destroy() {
+    CHECK(mCreated);
+    destroyAllVolumes();
+    mCreated = false;
+    notifyEvent(ResponseCode::DiskDestroyed);
+    return OK;
+}
+
+static std::string BuildKeyPath(const std::string& partGuid) {
+    return StringPrintf("%s/expand_%s.key", kKeyPath, partGuid.c_str());
+}
+
+void Disk::createPublicVolume(dev_t device) {
+    auto vol = std::shared_ptr<VolumeBase>(new PublicVolume(device));
+    if (mJustPartitioned) {
+        LOG(DEBUG) << "Device just partitioned; silently formatting";
+        vol->setSilent(true);
+        vol->create();
+        vol->format();
+        vol->destroy();
+        vol->setSilent(false);
+    }
+
+    mVolumes.push_back(vol);
+    vol->setDiskId(getId());
+    vol->create();
+}
+
+void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) {
+    std::string tmp;
+    std::string normalizedGuid;
+    if (HexToStr(partGuid, tmp)) {
+        LOG(WARNING) << "Invalid GUID " << partGuid;
+        return;
+    }
+    StrToHex(tmp, normalizedGuid);
+
+    std::string keyRaw;
+    if (!ReadFileToString(BuildKeyPath(normalizedGuid), &keyRaw)) {
+        PLOG(ERROR) << "Failed to load key for GUID " << normalizedGuid;
+        return;
+    }
+
+    LOG(DEBUG) << "Found key for GUID " << normalizedGuid;
+
+    auto vol = std::shared_ptr<VolumeBase>(new PrivateVolume(device, keyRaw));
+    if (mJustPartitioned) {
+        LOG(DEBUG) << "Device just partitioned; silently formatting";
+        vol->setSilent(true);
+        vol->create();
+        vol->format();
+        vol->destroy();
+        vol->setSilent(false);
+    }
+
+    mVolumes.push_back(vol);
+    vol->setDiskId(getId());
+    vol->create();
+}
+
+void Disk::destroyAllVolumes() {
+    for (auto vol : mVolumes) {
+        vol->destroy();
+    }
+    mVolumes.clear();
+}
+
+status_t Disk::readMetadata() {
+    mSize = -1;
+    mLabel.clear();
+
+    int fd = open(mDevPath.c_str(), O_RDONLY | O_CLOEXEC);
+    if (fd != -1) {
+        if (ioctl(fd, BLKGETSIZE64, &mSize)) {
+            mSize = -1;
+        }
+        close(fd);
+    }
+
+    switch (major(mDevice)) {
+    case kMajorBlockScsiA: case kMajorBlockScsiB: case kMajorBlockScsiC: case kMajorBlockScsiD:
+    case kMajorBlockScsiE: case kMajorBlockScsiF: case kMajorBlockScsiG: case kMajorBlockScsiH:
+    case kMajorBlockScsiI: case kMajorBlockScsiJ: case kMajorBlockScsiK: case kMajorBlockScsiL:
+    case kMajorBlockScsiM: case kMajorBlockScsiN: case kMajorBlockScsiO: case kMajorBlockScsiP: {
+        std::string path(mSysPath + "/device/vendor");
+        std::string tmp;
+        if (!ReadFileToString(path, &tmp)) {
+            PLOG(WARNING) << "Failed to read vendor from " << path;
+            return -errno;
+        }
+        mLabel = tmp;
+        break;
+    }
+    case kMajorBlockMmc: {
+        std::string path(mSysPath + "/device/manfid");
+        std::string tmp;
+        if (!ReadFileToString(path, &tmp)) {
+            PLOG(WARNING) << "Failed to read manufacturer from " << path;
+            return -errno;
+        }
+        uint64_t manfid = strtoll(tmp.c_str(), nullptr, 16);
+        // Our goal here is to give the user a meaningful label, ideally
+        // matching whatever is silk-screened on the card.  To reduce
+        // user confusion, this list doesn't contain white-label manfid.
+        switch (manfid) {
+        case 0x000003: mLabel = "SanDisk"; break;
+        case 0x00001b: mLabel = "Samsung"; break;
+        case 0x000028: mLabel = "Lexar"; break;
+        case 0x000074: mLabel = "Transcend"; break;
+        }
+        break;
+    }
+    default: {
+        LOG(WARNING) << "Unsupported block major type" << major(mDevice);
+        return -ENOTSUP;
+    }
+    }
+
+    notifyEvent(ResponseCode::DiskSizeChanged, StringPrintf("%" PRId64, mSize));
+    notifyEvent(ResponseCode::DiskLabelChanged, mLabel);
+    return OK;
+}
+
+status_t Disk::readPartitions() {
+    int8_t maxMinors = getMaxMinors();
+    if (maxMinors < 0) {
+        return -ENOTSUP;
+    }
+
+    destroyAllVolumes();
+
+    // Parse partition table
+
+    std::vector<std::string> cmd;
+    cmd.push_back(kSgdiskPath);
+    cmd.push_back("--android-dump");
+    cmd.push_back(mDevPath);
+
+    std::vector<std::string> output;
+    status_t res = ForkExecvp(cmd, output);
+    if (res != OK) {
+        LOG(WARNING) << "sgdisk failed to scan " << mDevPath;
+        mJustPartitioned = false;
+        return res;
+    }
+
+    Table table = Table::kUnknown;
+    bool foundParts = false;
+    for (auto line : output) {
+        char* cline = (char*) line.c_str();
+        char* token = strtok(cline, kSgdiskToken);
+        if (token == nullptr) continue;
+
+        if (!strcmp(token, "DISK")) {
+            const char* type = strtok(nullptr, kSgdiskToken);
+            if (!strcmp(type, "mbr")) {
+                table = Table::kMbr;
+            } else if (!strcmp(type, "gpt")) {
+                table = Table::kGpt;
+            }
+        } else if (!strcmp(token, "PART")) {
+            foundParts = true;
+            int i = strtol(strtok(nullptr, kSgdiskToken), nullptr, 10);
+            if (i <= 0 || i > maxMinors) {
+                LOG(WARNING) << mId << " is ignoring partition " << i
+                        << " beyond max supported devices";
+                continue;
+            }
+            dev_t partDevice = makedev(major(mDevice), minor(mDevice) + i);
+
+            if (table == Table::kMbr) {
+                const char* type = strtok(nullptr, kSgdiskToken);
+
+                switch (strtol(type, nullptr, 16)) {
+                case 0x06: // FAT16
+                case 0x0b: // W95 FAT32 (LBA)
+                case 0x0c: // W95 FAT32 (LBA)
+                case 0x0e: // W95 FAT16 (LBA)
+                    createPublicVolume(partDevice);
+                    break;
+                }
+            } else if (table == Table::kGpt) {
+                const char* typeGuid = strtok(nullptr, kSgdiskToken);
+                const char* partGuid = strtok(nullptr, kSgdiskToken);
+
+                if (!strcasecmp(typeGuid, kGptBasicData)) {
+                    createPublicVolume(partDevice);
+                } else if (!strcasecmp(typeGuid, kGptAndroidExpand)) {
+                    createPrivateVolume(partDevice, partGuid);
+                }
+            }
+        }
+    }
+
+#if ENTIRE_DEVICE_FALLBACK
+    // Ugly last ditch effort, treat entire disk as partition
+    if (table == Table::kUnknown || !foundParts) {
+        // TODO: use blkid to confirm filesystem before doing this
+        LOG(WARNING) << mId << " has unknown partition table; trying entire device";
+        createPublicVolume(mDevice);
+    }
+#endif
+
+    notifyEvent(ResponseCode::DiskScanned);
+
+    mJustPartitioned = false;
+    return OK;
+}
+
+status_t Disk::unmountAll() {
+    for (auto vol : mVolumes) {
+        vol->unmount();
+    }
+    return OK;
+}
+
+status_t Disk::partitionPublic() {
+    // TODO: improve this code
+    destroyAllVolumes();
+    mJustPartitioned = true;
+
+    struct disk_info dinfo;
+    memset(&dinfo, 0, sizeof(dinfo));
+
+    if (!(dinfo.part_lst = (struct part_info *) malloc(
+            MAX_NUM_PARTS * sizeof(struct part_info)))) {
+        return -1;
+    }
+
+    memset(dinfo.part_lst, 0, MAX_NUM_PARTS * sizeof(struct part_info));
+    dinfo.device = strdup(mDevPath.c_str());
+    dinfo.scheme = PART_SCHEME_MBR;
+    dinfo.sect_size = 512;
+    dinfo.skip_lba = 2048;
+    dinfo.num_lba = 0;
+    dinfo.num_parts = 1;
+
+    struct part_info *pinfo = &dinfo.part_lst[0];
+
+    pinfo->name = strdup("android_sdcard");
+    pinfo->flags |= PART_ACTIVE_FLAG;
+    pinfo->type = PC_PART_TYPE_FAT32;
+    pinfo->len_kb = -1;
+
+    int rc = apply_disk_config(&dinfo, 0);
+    if (rc) {
+        LOG(ERROR) << "Failed to apply disk configuration: " << rc;
+        goto out;
+    }
+
+out:
+    free(pinfo->name);
+    free(dinfo.device);
+    free(dinfo.part_lst);
+
+    return rc;
+}
+
+status_t Disk::partitionPrivate() {
+    return partitionMixed(0);
+}
+
+status_t Disk::partitionMixed(int8_t ratio) {
+    int res;
+
+    destroyAllVolumes();
+    mJustPartitioned = true;
+
+    // First nuke any existing partition table
+    std::vector<std::string> cmd;
+    cmd.push_back(kSgdiskPath);
+    cmd.push_back("--zap-all");
+    cmd.push_back(mDevPath);
+
+    // Zap sometimes returns an error when it actually succeeded, so
+    // just log as warning and keep rolling forward.
+    if ((res = ForkExecvp(cmd)) != 0) {
+        LOG(WARNING) << "Failed to zap; status " << res;
+    }
+
+    // We've had some success above, so generate both the private partition
+    // GUID and encryption key and persist them.
+    std::string partGuidRaw;
+    std::string keyRaw;
+    if (ReadRandomBytes(16, partGuidRaw) || ReadRandomBytes(16, keyRaw)) {
+        LOG(ERROR) << "Failed to generate GUID or key";
+        return -EIO;
+    }
+
+    std::string partGuid;
+    StrToHex(partGuidRaw, partGuid);
+
+    if (!WriteStringToFile(keyRaw, BuildKeyPath(partGuid))) {
+        LOG(ERROR) << "Failed to persist key";
+        return -EIO;
+    } else {
+        LOG(DEBUG) << "Persisted key for GUID " << partGuid;
+    }
+
+    // Now let's build the new GPT table. We heavily rely on sgdisk to
+    // force optimal alignment on the created partitions.
+    cmd.clear();
+    cmd.push_back(kSgdiskPath);
+
+    // If requested, create a public partition first. Mixed-mode partitioning
+    // like this is an experimental feature.
+    if (ratio > 0) {
+        if (ratio < 10 || ratio > 90) {
+            LOG(ERROR) << "Mixed partition ratio must be between 10-90%";
+            return -EINVAL;
+        }
+
+        uint64_t splitMb = ((mSize / 100) * ratio) / 1024 / 1024;
+        cmd.push_back(StringPrintf("--new=0:0:+%" PRId64 "M", splitMb));
+        cmd.push_back(StringPrintf("--typecode=0:%s", kGptBasicData));
+        cmd.push_back("--change-name=0:shared");
+    }
+
+    // Define a metadata partition which is designed for future use; there
+    // should only be one of these per physical device, even if there are
+    // multiple private volumes.
+    cmd.push_back("--new=0:0:+16M");
+    cmd.push_back(StringPrintf("--typecode=0:%s", kGptAndroidMeta));
+    cmd.push_back("--change-name=0:android_meta");
+
+    // Define a single private partition filling the rest of disk.
+    cmd.push_back("--new=0:0:-0");
+    cmd.push_back(StringPrintf("--typecode=0:%s", kGptAndroidExpand));
+    cmd.push_back(StringPrintf("--partition-guid=0:%s", partGuid.c_str()));
+    cmd.push_back("--change-name=0:android_expand");
+
+    cmd.push_back(mDevPath);
+
+    if ((res = ForkExecvp(cmd)) != 0) {
+        LOG(ERROR) << "Failed to partition; status " << res;
+        return res;
+    }
+
+    return OK;
+}
+
+void Disk::notifyEvent(int event) {
+    VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
+            getId().c_str(), false);
+}
+
+void Disk::notifyEvent(int event, const std::string& value) {
+    VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
+            StringPrintf("%s %s", getId().c_str(), value.c_str()).c_str(), false);
+}
+
+int Disk::getMaxMinors() {
+    // Figure out maximum partition devices supported
+    switch (major(mDevice)) {
+    case kMajorBlockScsiA: case kMajorBlockScsiB: case kMajorBlockScsiC: case kMajorBlockScsiD:
+    case kMajorBlockScsiE: case kMajorBlockScsiF: case kMajorBlockScsiG: case kMajorBlockScsiH:
+    case kMajorBlockScsiI: case kMajorBlockScsiJ: case kMajorBlockScsiK: case kMajorBlockScsiL:
+    case kMajorBlockScsiM: case kMajorBlockScsiN: case kMajorBlockScsiO: case kMajorBlockScsiP: {
+        // Per Documentation/devices.txt this is static
+        return 15;
+    }
+    case kMajorBlockMmc: {
+        // Per Documentation/devices.txt this is dynamic
+        std::string tmp;
+        if (!ReadFileToString(kSysfsMmcMaxMinors, &tmp)) {
+            LOG(ERROR) << "Failed to read max minors";
+            return -errno;
+        }
+        return atoi(tmp.c_str());
+    }
+    }
+
+    LOG(ERROR) << "Unsupported block major type " << major(mDevice);
+    return -ENOTSUP;
+}
+
+}  // namespace vold
+}  // namespace android
diff --git a/Disk.h b/Disk.h
new file mode 100644
index 0000000..a8461fb
--- /dev/null
+++ b/Disk.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VOLD_DISK_H
+#define ANDROID_VOLD_DISK_H
+
+#include "Utils.h"
+
+#include <utils/Errors.h>
+
+#include <vector>
+
+namespace android {
+namespace vold {
+
+class VolumeBase;
+
+/*
+ * Representation of detected physical media.
+ *
+ * Knows how to create volumes based on the partition tables found, and also
+ * how to repartition itself.
+ */
+class Disk {
+public:
+    Disk(const std::string& eventPath, dev_t device, const std::string& nickname, int flags);
+    virtual ~Disk();
+
+    enum Flags {
+        /* Flag that disk is adoptable */
+        kAdoptable = 1 << 0,
+        /* Flag that disk is considered primary when the user hasn't
+         * explicitly picked a primary storage location */
+        kDefaultPrimary = 1 << 1,
+        /* Flag that disk is SD card */
+        kSd = 1 << 2,
+        /* Flag that disk is USB disk */
+        kUsb = 1 << 3,
+    };
+
+    const std::string& getId() { return mId; }
+    const std::string& getEventPath() { return mEventPath; }
+    const std::string& getSysPath() { return mSysPath; }
+    const std::string& getDevPath() { return mDevPath; }
+    dev_t getDevice() { return mDevice; }
+    uint64_t getSize() { return mSize; }
+    const std::string& getLabel() { return mLabel; }
+    int getFlags() { return mFlags; }
+
+    std::shared_ptr<VolumeBase> findVolume(const std::string& id);
+
+    status_t create();
+    status_t destroy();
+
+    status_t readMetadata();
+    status_t readPartitions();
+
+    status_t unmountAll();
+
+    status_t partitionPublic();
+    status_t partitionPrivate();
+    status_t partitionMixed(int8_t ratio);
+
+    void notifyEvent(int msg);
+    void notifyEvent(int msg, const std::string& value);
+
+private:
+    /* ID that uniquely references this disk */
+    std::string mId;
+    /* Original event path */
+    std::string mEventPath;
+    /* Device path under sysfs */
+    std::string mSysPath;
+    /* Device path under dev */
+    std::string mDevPath;
+    /* Kernel device representing disk */
+    dev_t mDevice;
+    /* Size of disk, in bytes */
+    uint64_t mSize;
+    /* User-visible label, such as manufacturer */
+    std::string mLabel;
+    /* Current partitions on disk */
+    std::vector<std::shared_ptr<VolumeBase>> mVolumes;
+    /* Nickname for this disk */
+    std::string mNickname;
+    /* Flags applicable to this disk */
+    int mFlags;
+    /* Flag indicating object is created */
+    bool mCreated;
+    /* Flag that we just partitioned and should format all volumes */
+    bool mJustPartitioned;
+
+    void createPublicVolume(dev_t device);
+    void createPrivateVolume(dev_t device, const std::string& partGuid);
+
+    void destroyAllVolumes();
+
+    int getMaxMinors();
+
+    DISALLOW_COPY_AND_ASSIGN(Disk);
+};
+
+}  // namespace vold
+}  // namespace android
+
+#endif
diff --git a/EmulatedVolume.cpp b/EmulatedVolume.cpp
new file mode 100644
index 0000000..7098872
--- /dev/null
+++ b/EmulatedVolume.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "EmulatedVolume.h"
+#include "Utils.h"
+
+#include <base/stringprintf.h>
+#include <base/logging.h>
+#include <cutils/fs.h>
+#include <private/android_filesystem_config.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+using android::base::StringPrintf;
+
+namespace android {
+namespace vold {
+
+static const char* kFusePath = "/system/bin/sdcard";
+
+EmulatedVolume::EmulatedVolume(const std::string& rawPath) :
+        VolumeBase(Type::kEmulated), mFusePid(0) {
+    setId("emulated");
+    mFusePath = "/storage/emulated";
+    mRawPath = rawPath;
+}
+
+EmulatedVolume::EmulatedVolume(const std::string& rawPath, dev_t device,
+        const std::string& fsUuid) : VolumeBase(Type::kEmulated), mFusePid(0) {
+    setId(StringPrintf("emulated:%u,%u", major(device), minor(device)));
+    mFusePath = StringPrintf("/storage/%s", fsUuid.c_str());
+    mRawPath = rawPath;
+}
+
+EmulatedVolume::~EmulatedVolume() {
+}
+
+status_t EmulatedVolume::doMount() {
+    if (fs_prepare_dir(mFusePath.c_str(), 0700, AID_ROOT, AID_ROOT)) {
+        PLOG(ERROR) << getId() << " failed to create mount point " << mFusePath;
+        return -errno;
+    }
+
+    setPath(mFusePath);
+    setInternalPath(mRawPath);
+
+    if (!(mFusePid = fork())) {
+        // TODO: protect when not mounted as visible
+        if (execl(kFusePath, kFusePath,
+                "-u", "1023", // AID_MEDIA_RW
+                "-g", "1023", // AID_MEDIA_RW
+                "-l",
+                mRawPath.c_str(),
+                mFusePath.c_str(),
+                NULL)) {
+            PLOG(ERROR) << "Failed to exec";
+        }
+
+        PLOG(DEBUG) << "FUSE exiting";
+        _exit(1);
+    }
+
+    if (mFusePid == -1) {
+        PLOG(ERROR) << getId() << " failed to fork";
+        return -errno;
+    }
+
+    return OK;
+}
+
+status_t EmulatedVolume::doUnmount() {
+    if (mFusePid > 0) {
+        kill(mFusePid, SIGTERM);
+        TEMP_FAILURE_RETRY(waitpid(mFusePid, nullptr, 0));
+        mFusePid = 0;
+    }
+
+    ForceUnmount(mFusePath);
+    ForceUnmount(mRawPath);
+
+    if (TEMP_FAILURE_RETRY(rmdir(mFusePath.c_str()))) {
+        PLOG(ERROR) << getId() << " failed to rmdir mount point " << mFusePath;
+        return -errno;
+    }
+
+    return OK;
+}
+
+}  // namespace vold
+}  // namespace android
diff --git a/EmulatedVolume.h b/EmulatedVolume.h
new file mode 100644
index 0000000..04d4508
--- /dev/null
+++ b/EmulatedVolume.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VOLD_EMULATED_VOLUME_H
+#define ANDROID_VOLD_EMULATED_VOLUME_H
+
+#include "VolumeBase.h"
+
+#include <cutils/multiuser.h>
+
+namespace android {
+namespace vold {
+
+/*
+ * Shared storage emulated on top of private storage.
+ *
+ * Knows how to spawn a FUSE daemon to synthesize permissions.  ObbVolume
+ * can be stacked above it.
+ *
+ * This volume is always multi-user aware, but is only binds itself to
+ * users when its primary storage.  This volume should never be presented
+ * as secondary storage, since we're strongly encouraging developers to
+ * store data local to their app.
+ */
+class EmulatedVolume : public VolumeBase {
+public:
+    EmulatedVolume(const std::string& rawPath);
+    EmulatedVolume(const std::string& rawPath, dev_t device, const std::string& fsUuid);
+    virtual ~EmulatedVolume();
+
+protected:
+    status_t doMount() override;
+    status_t doUnmount() override;
+
+private:
+    /* Mount point of raw storage */
+    std::string mRawPath;
+    /* Mount point of visible storage */
+    std::string mFusePath;
+    /* PID of FUSE wrapper */
+    pid_t mFusePid;
+
+    DISALLOW_COPY_AND_ASSIGN(EmulatedVolume);
+};
+
+}  // namespace vold
+}  // namespace android
+
+#endif
diff --git a/Ext4.cpp b/Ext4.cpp
index f5a964a..a208eb5 100644
--- a/Ext4.cpp
+++ b/Ext4.cpp
@@ -23,6 +23,8 @@
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <vector>
+#include <string>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -35,16 +37,84 @@
 
 #define LOG_TAG "Vold"
 
+#include <base/logging.h>
+#include <base/stringprintf.h>
 #include <cutils/log.h>
 #include <cutils/properties.h>
-
 #include <logwrap/logwrap.h>
+#include <selinux/selinux.h>
 
 #include "Ext4.h"
+#include "Utils.h"
 #include "VoldUtil.h"
 
-#define MKEXT4FS_PATH "/system/bin/make_ext4fs"
-#define RESIZE2FS_PATH "/system/bin/resize2fs"
+using android::base::StringPrintf;
+
+static const char* kResizefsPath = "/system/bin/resize2fs";
+static const char* kMkfsPath = "/system/bin/make_ext4fs";
+static const char* kFsckPath = "/system/bin/e2fsck";
+
+int Ext4::check(const char *fsPath, const char *mountPoint) {
+    // The following is shamelessly borrowed from fs_mgr.c, so it should be
+    // kept in sync with any changes over there.
+
+    char* blk_device = (char*) fsPath;
+    char* target = (char*) mountPoint;
+
+    int status;
+    int ret;
+    long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
+    char *tmpmnt_opts = (char*) "nomblk_io_submit,errors=remount-ro";
+
+    /*
+     * First try to mount and unmount the filesystem.  We do this because
+     * the kernel is more efficient than e2fsck in running the journal and
+     * processing orphaned inodes, and on at least one device with a
+     * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes
+     * to do what the kernel does in about a second.
+     *
+     * After mounting and unmounting the filesystem, run e2fsck, and if an
+     * error is recorded in the filesystem superblock, e2fsck will do a full
+     * check.  Otherwise, it does nothing.  If the kernel cannot mount the
+     * filesytsem due to an error, e2fsck is still run to do a full check
+     * fix the filesystem.
+     */
+    ret = mount(blk_device, target, "ext4", tmpmnt_flags, tmpmnt_opts);
+    if (!ret) {
+        int i;
+        for (i = 0; i < 5; i++) {
+            // Try to umount 5 times before continuing on.
+            // Should we try rebooting if all attempts fail?
+            int result = umount(target);
+            if (result == 0) {
+                break;
+            }
+            ALOGW("%s(): umount(%s)=%d: %s\n", __func__, target, result, strerror(errno));
+            sleep(1);
+        }
+    }
+
+    /*
+     * Some system images do not have e2fsck for licensing reasons
+     * (e.g. recent SDK system images). Detect these and skip the check.
+     */
+    if (access(kFsckPath, X_OK)) {
+        ALOGD("Not running %s on %s (executable not in system image)\n",
+                kFsckPath, blk_device);
+    } else {
+        ALOGD("Running %s on %s\n", kFsckPath, blk_device);
+
+        std::vector<std::string> cmd;
+        cmd.push_back(kFsckPath);
+        cmd.push_back("-y");
+        cmd.push_back(blk_device);
+
+        // Ext4 devices are currently always trusted
+        return android::vold::ForkExecvp(cmd, android::vold::sFsckContext);
+    }
+
+    return 0;
+}
 
 int Ext4::doMount(const char *fsPath, const char *mountPoint, bool ro, bool remount,
         bool executable) {
@@ -69,92 +139,31 @@
 }
 
 int Ext4::resize(const char *fspath, unsigned int numSectors) {
-    const char *args[4];
-    char* size_str;
-    int rc;
-    int status;
+    std::vector<std::string> cmd;
+    cmd.push_back(kResizefsPath);
+    cmd.push_back("-f");
+    cmd.push_back(fspath);
+    cmd.push_back(StringPrintf("%u", numSectors));
 
-    args[0] = RESIZE2FS_PATH;
-    args[1] = "-f";
-    args[2] = fspath;
-    if (asprintf(&size_str, "%ds", numSectors) < 0)
-    {
-      SLOGE("Filesystem (ext4) resize failed to set size");
-      return -1;
-    }
-    args[3] = size_str;
-    rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
-            true);
-    free(size_str);
-    if (rc != 0) {
-        SLOGE("Filesystem (ext4) resize failed due to logwrap error");
-        errno = EIO;
-        return -1;
-    }
-
-    if (!WIFEXITED(status)) {
-        SLOGE("Filesystem (ext4) resize did not exit properly");
-        errno = EIO;
-        return -1;
-    }
-
-    status = WEXITSTATUS(status);
-
-    if (status == 0) {
-        SLOGI("Filesystem (ext4) resized OK");
-        return 0;
-    } else {
-        SLOGE("Resize (ext4) failed (unknown exit code %d)", status);
-        errno = EIO;
-        return -1;
-    }
-    return 0;
+    return android::vold::ForkExecvp(cmd);
 }
 
 int Ext4::format(const char *fsPath, unsigned int numSectors, const char *mountpoint) {
-    const char *args[7];
-    int rc;
-    int status;
+    std::vector<std::string> cmd;
+    cmd.push_back(kMkfsPath);
+    cmd.push_back("-J");
 
-    args[0] = MKEXT4FS_PATH;
-    args[1] = "-J";
-    args[2] = "-a";
-    args[3] = mountpoint;
+    cmd.push_back("-a");
+    cmd.push_back(mountpoint);
+
     if (numSectors) {
-        char tmp[32];
-        snprintf(tmp, sizeof(tmp), "%u", numSectors * 512);
-        const char *size = tmp;
-        args[4] = "-l";
-        args[5] = size;
-        args[6] = fsPath;
-        rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false, true);
-    } else {
-        args[4] = fsPath;
-        rc = android_fork_execvp(5, (char **)args, &status, false, true);
-    }
-    rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
-            true);
-    if (rc != 0) {
-        SLOGE("Filesystem (ext4) format failed due to logwrap error");
-        errno = EIO;
-        return -1;
+        cmd.push_back("-l");
+        cmd.push_back(StringPrintf("%u", numSectors * 512));
     }
 
-    if (!WIFEXITED(status)) {
-        SLOGE("Filesystem (ext4) format did not exit properly");
-        errno = EIO;
-        return -1;
-    }
+    // Always generate a real UUID
+    cmd.push_back("-u");
+    cmd.push_back(fsPath);
 
-    status = WEXITSTATUS(status);
-
-    if (status == 0) {
-        SLOGI("Filesystem (ext4) formatted OK");
-        return 0;
-    } else {
-        SLOGE("Format (ext4) failed (unknown exit code %d)", status);
-        errno = EIO;
-        return -1;
-    }
-    return 0;
+    return android::vold::ForkExecvp(cmd);
 }
diff --git a/Ext4.h b/Ext4.h
index c768f5a..55672af 100644
--- a/Ext4.h
+++ b/Ext4.h
@@ -21,6 +21,7 @@
 
 class Ext4 {
 public:
+    static int check(const char *fsPath, const char *mountPoint);
     static int doMount(const char *fsPath, const char *mountPoint, bool ro, bool remount,
             bool executable);
     static int format(const char *fsPath, unsigned int numSectors, const char *mountpoint);
diff --git a/Fat.cpp b/Fat.cpp
index 018fbeb..873088d 100644
--- a/Fat.cpp
+++ b/Fat.cpp
@@ -37,20 +37,25 @@
 
 #define LOG_TAG "Vold"
 
+#include <base/logging.h>
+#include <base/stringprintf.h>
 #include <cutils/log.h>
 #include <cutils/properties.h>
+#include <selinux/selinux.h>
 
 #include <logwrap/logwrap.h>
 
 #include "Fat.h"
+#include "Utils.h"
 #include "VoldUtil.h"
 
-static char FSCK_MSDOS_PATH[] = "/system/bin/fsck_msdos";
-static char MKDOSFS_PATH[] = "/system/bin/newfs_msdos";
-extern "C" int mount(const char *, const char *, const char *, unsigned long, const void *);
+using android::base::StringPrintf;
+
+static const char* kMkfsPath = "/system/bin/newfs_msdos";
+static const char* kFsckPath = "/system/bin/fsck_msdos";
 
 int Fat::check(const char *fsPath) {
-    if (access(FSCK_MSDOS_PATH, X_OK)) {
+    if (access(kFsckPath, X_OK)) {
         SLOGW("Skipping fs checks\n");
         return 0;
     }
@@ -58,30 +63,22 @@
     int pass = 1;
     int rc = 0;
     do {
-        const char *args[4];
-        int status;
-        args[0] = FSCK_MSDOS_PATH;
-        args[1] = "-p";
-        args[2] = "-f";
-        args[3] = fsPath;
+        std::vector<std::string> cmd;
+        cmd.push_back(kFsckPath);
+        cmd.push_back("-p");
+        cmd.push_back("-f");
+        cmd.push_back(fsPath);
 
-        rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status,
-                false, true);
-        if (rc != 0) {
+        // Fat devices are currently always untrusted
+        rc = android::vold::ForkExecvp(cmd, android::vold::sFsckUntrustedContext);
+
+        if (rc < 0) {
             SLOGE("Filesystem check failed due to logwrap error");
             errno = EIO;
             return -1;
         }
 
-        if (!WIFEXITED(status)) {
-            SLOGE("Filesystem check did not exit properly");
-            errno = EIO;
-            return -1;
-        }
-
-        status = WEXITSTATUS(status);
-
-        switch(status) {
+        switch(rc) {
         case 0:
             SLOGI("Filesystem check completed OK");
             return 0;
@@ -102,7 +99,7 @@
             return -1;
 
         default:
-            SLOGE("Filesystem check failed (unknown exit code %d)", status);
+            SLOGE("Filesystem check failed (unknown exit code %d)", rc);
             errno = EIO;
             return -1;
         }
@@ -169,57 +166,39 @@
 }
 
 int Fat::format(const char *fsPath, unsigned int numSectors, bool wipe) {
-    const char *args[11];
-    int rc;
-    int status;
-
     if (wipe) {
         Fat::wipe(fsPath, numSectors);
     }
 
-    args[0] = MKDOSFS_PATH;
-    args[1] = "-F";
-    args[2] = "32";
-    args[3] = "-O";
-    args[4] = "android";
-    args[5] = "-c";
-    args[6] = "64";
-    args[7] = "-A";
+    std::vector<std::string> cmd;
+    cmd.push_back(kMkfsPath);
+    cmd.push_back("-F");
+    cmd.push_back("32");
+    cmd.push_back("-O");
+    cmd.push_back("android");
+    cmd.push_back("-c");
+    cmd.push_back("64");
+    cmd.push_back("-A");
 
     if (numSectors) {
-        char tmp[32];
-        snprintf(tmp, sizeof(tmp), "%u", numSectors);
-        const char *size = tmp;
-        args[8] = "-s";
-        args[9] = size;
-        args[10] = fsPath;
-        rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status,
-                false, true);
-    } else {
-        args[8] = fsPath;
-        rc = android_fork_execvp(9, (char **)args, &status, false,
-                true);
+        cmd.push_back("-s");
+        cmd.push_back(StringPrintf("%u", numSectors));
     }
 
-    if (rc != 0) {
+    cmd.push_back(fsPath);
+
+    int rc = android::vold::ForkExecvp(cmd);
+    if (rc < 0) {
         SLOGE("Filesystem format failed due to logwrap error");
         errno = EIO;
         return -1;
     }
 
-    if (!WIFEXITED(status)) {
-        SLOGE("Filesystem format did not exit properly");
-        errno = EIO;
-        return -1;
-    }
-
-    status = WEXITSTATUS(status);
-
-    if (status == 0) {
+    if (rc == 0) {
         SLOGI("Filesystem formatted OK");
         return 0;
     } else {
-        SLOGE("Format failed (unknown exit code %d)", status);
+        SLOGE("Format failed (unknown exit code %d)", rc);
         errno = EIO;
         return -1;
     }
@@ -229,7 +208,7 @@
 void Fat::wipe(const char *fsPath, unsigned int numSectors) {
     unsigned long long range[2];
 
-    int fd = open(fsPath, O_RDWR);
+    int fd = open(fsPath, O_RDWR | O_CLOEXEC);
     if (fd == -1) {
         SLOGE("Fat wipe failed to open device %s", fsPath);
         return;
diff --git a/Loop.cpp b/Loop.cpp
index b1e9f6a..8872d7a 100644
--- a/Loop.cpp
+++ b/Loop.cpp
@@ -49,7 +49,7 @@
 
         sprintf(filename, "/dev/block/loop%d", i);
 
-        if ((fd = open(filename, O_RDWR)) < 0) {
+        if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) {
             if (errno != ENOENT) {
                 SLOGE("Unable to open %s (%s)", filename, strerror(errno));
             } else {
@@ -93,7 +93,7 @@
 
         sprintf(filename, "/dev/block/loop%d", i);
 
-        if ((fd = open(filename, O_RDWR)) < 0) {
+        if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) {
             if (errno != ENOENT) {
                 SLOGE("Unable to open %s (%s)", filename, strerror(errno));
             } else {
@@ -168,7 +168,7 @@
             setfscreatecon(NULL);
         }
 
-        if ((fd = open(filename, O_RDWR)) < 0) {
+        if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) {
             SLOGE("Unable to open %s (%s)", filename, strerror(errno));
             return -1;
         }
@@ -196,7 +196,7 @@
 
     int file_fd;
 
-    if ((file_fd = open(loopFile, O_RDWR)) < 0) {
+    if ((file_fd = open(loopFile, O_RDWR | O_CLOEXEC)) < 0) {
         SLOGE("Unable to open %s (%s)", loopFile, strerror(errno));
         close(fd);
         return -1;
@@ -231,7 +231,7 @@
 int Loop::destroyByDevice(const char *loopDevice) {
     int device_fd;
 
-    device_fd = open(loopDevice, O_RDONLY);
+    device_fd = open(loopDevice, O_RDONLY | O_CLOEXEC);
     if (device_fd < 0) {
         SLOGE("Failed to open loop (%d)", errno);
         return -1;
@@ -272,7 +272,7 @@
 int Loop::resizeImageFile(const char *file, unsigned int numSectors) {
     int fd;
 
-    if ((fd = open(file, O_RDWR)) < 0) {
+    if ((fd = open(file, O_RDWR | O_CLOEXEC)) < 0) {
         SLOGE("Error opening imagefile (%s)", strerror(errno));
         return -1;
     }
@@ -301,7 +301,7 @@
     int fd;
     struct asec_superblock buffer;
 
-    if ((fd = open(loopDevice, O_RDONLY)) < 0) {
+    if ((fd = open(loopDevice, O_RDONLY | O_CLOEXEC)) < 0) {
         SLOGE("Failed to open loopdevice (%s)", strerror(errno));
         destroyByDevice(loopDevice);
         return -1;
diff --git a/MoveTask.cpp b/MoveTask.cpp
new file mode 100644
index 0000000..e0eec12
--- /dev/null
+++ b/MoveTask.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MoveTask.h"
+#include "Utils.h"
+#include "VolumeManager.h"
+#include "ResponseCode.h"
+
+#include <base/stringprintf.h>
+#include <base/logging.h>
+#include <private/android_filesystem_config.h>
+
+#include <dirent.h>
+#include <sys/wait.h>
+
+#define CONSTRAIN(amount, low, high) (amount < low ? low : (amount > high ? high : amount))
+
+using android::base::StringPrintf;
+
+namespace android {
+namespace vold {
+
+// TODO: keep in sync with PackageManager
+static const int kMoveSucceeded = -100;
+static const int kMoveFailedInternalError = -6;
+
+static const char* kCpPath = "/system/bin/cp";
+static const char* kRmPath = "/system/bin/rm";
+
+MoveTask::MoveTask(const std::shared_ptr<VolumeBase>& from,
+        const std::shared_ptr<VolumeBase>& to) :
+        mFrom(from), mTo(to) {
+}
+
+MoveTask::~MoveTask() {
+}
+
+void MoveTask::start() {
+    mThread = std::thread(&MoveTask::run, this);
+}
+
+static void notifyProgress(int progress) {
+    VolumeManager::Instance()->getBroadcaster()->sendBroadcast(ResponseCode::MoveStatus,
+            StringPrintf("%d", progress).c_str(), false);
+}
+
+static status_t pushBackContents(const std::string& path, std::vector<std::string>& cmd) {
+    DIR* dir = opendir(path.c_str());
+    if (dir == NULL) {
+        return -1;
+    }
+    bool found = false;
+    struct dirent* ent;
+    while ((ent = readdir(dir)) != NULL) {
+        if ((!strcmp(ent->d_name, ".")) || (!strcmp(ent->d_name, ".."))) {
+            continue;
+        }
+        cmd.push_back(StringPrintf("%s/%s", path.c_str(), ent->d_name));
+        found = true;
+    }
+    closedir(dir);
+    return found ? OK : -1;
+}
+
+static status_t execRm(const std::string& path, int startProgress, int stepProgress) {
+    notifyProgress(startProgress);
+
+    uint64_t expectedBytes = GetTreeBytes(path);
+    uint64_t startFreeBytes = GetFreeBytes(path);
+
+    std::vector<std::string> cmd;
+    cmd.push_back(kRmPath);
+    cmd.push_back("-f"); /* force: remove without confirmation, no error if it doesn't exist */
+    cmd.push_back("-R"); /* recursive: remove directory contents */
+    if (pushBackContents(path, cmd) != OK) {
+        LOG(WARNING) << "No contents in " << path;
+        return OK;
+    }
+
+    pid_t pid = ForkExecvpAsync(cmd);
+    if (pid == -1) return -1;
+
+    int status;
+    while (true) {
+        if (waitpid(pid, &status, WNOHANG) == pid) {
+            if (WIFEXITED(status)) {
+                LOG(DEBUG) << "Finished rm with status " << WEXITSTATUS(status);
+                return (WEXITSTATUS(status) == 0) ? OK : -1;
+            } else {
+                break;
+            }
+        }
+
+        sleep(1);
+        uint64_t deltaFreeBytes = GetFreeBytes(path) - startFreeBytes;
+        notifyProgress(startProgress + CONSTRAIN((int)
+                ((deltaFreeBytes * stepProgress) / expectedBytes), 0, stepProgress));
+    }
+    return -1;
+}
+
+static status_t execCp(const std::string& fromPath, const std::string& toPath,
+        int startProgress, int stepProgress) {
+    notifyProgress(startProgress);
+
+    uint64_t expectedBytes = GetTreeBytes(fromPath);
+    uint64_t startFreeBytes = GetFreeBytes(toPath);
+
+    std::vector<std::string> cmd;
+    cmd.push_back(kCpPath);
+    cmd.push_back("-p"); /* preserve timestamps, ownership, and permissions */
+    cmd.push_back("-R"); /* recurse into subdirectories (DEST must be a directory) */
+    cmd.push_back("-P"); /* Do not follow symlinks [default] */
+    cmd.push_back("-d"); /* don't dereference symlinks */
+    if (pushBackContents(fromPath, cmd) != OK) {
+        LOG(WARNING) << "No contents in " << fromPath;
+        return OK;
+    }
+    cmd.push_back(toPath.c_str());
+
+    pid_t pid = ForkExecvpAsync(cmd);
+    if (pid == -1) return -1;
+
+    int status;
+    while (true) {
+        if (waitpid(pid, &status, WNOHANG) == pid) {
+            if (WIFEXITED(status)) {
+                LOG(DEBUG) << "Finished cp with status " << WEXITSTATUS(status);
+                return (WEXITSTATUS(status) == 0) ? OK : -1;
+            } else {
+                break;
+            }
+        }
+
+        sleep(1);
+        uint64_t deltaFreeBytes = startFreeBytes - GetFreeBytes(toPath);
+        notifyProgress(startProgress + CONSTRAIN((int)
+                ((deltaFreeBytes * stepProgress) / expectedBytes), 0, stepProgress));
+    }
+    return -1;
+}
+
+static void bringOffline(const std::shared_ptr<VolumeBase>& vol) {
+    vol->destroy();
+    vol->setSilent(true);
+    vol->create();
+    vol->setMountFlags(0);
+    vol->mount();
+}
+
+static void bringOnline(const std::shared_ptr<VolumeBase>& vol) {
+    vol->destroy();
+    vol->setSilent(false);
+    vol->create();
+}
+
+void MoveTask::run() {
+    std::string fromPath;
+    std::string toPath;
+
+    // TODO: add support for public volumes
+    if (mFrom->getType() != VolumeBase::Type::kEmulated) goto fail;
+    if (mTo->getType() != VolumeBase::Type::kEmulated) goto fail;
+
+    // Step 1: tear down volumes and mount silently without making
+    // visible to userspace apps
+    bringOffline(mFrom);
+    bringOffline(mTo);
+
+    fromPath = mFrom->getInternalPath();
+    toPath = mTo->getInternalPath();
+
+    // Step 2: clean up any stale data
+    if (execRm(toPath, 10, 10) != OK) {
+        goto fail;
+    }
+
+    // Step 3: perform actual copy
+    if (execCp(fromPath, toPath, 20, 60) != OK) {
+        goto fail;
+    }
+
+    // NOTE: MountService watches for this magic value to know
+    // that move was successful
+    notifyProgress(82);
+    bringOnline(mFrom);
+    bringOnline(mTo);
+
+    // Step 4: clean up old data
+    if (execRm(fromPath, 85, 15) != OK) {
+        goto fail;
+    }
+
+    notifyProgress(kMoveSucceeded);
+    return;
+fail:
+    bringOnline(mFrom);
+    bringOnline(mTo);
+    notifyProgress(kMoveFailedInternalError);
+    return;
+}
+
+}  // namespace vold
+}  // namespace android
diff --git a/MoveTask.h b/MoveTask.h
new file mode 100644
index 0000000..b1777c0
--- /dev/null
+++ b/MoveTask.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VOLD_MOVE_TASK_H
+#define ANDROID_VOLD_MOVE_TASK_H
+
+#include "Utils.h"
+#include "VolumeBase.h"
+
+#include <thread>
+
+namespace android {
+namespace vold {
+
+class MoveTask {
+public:
+    MoveTask(const std::shared_ptr<VolumeBase>& from, const std::shared_ptr<VolumeBase>& to);
+    virtual ~MoveTask();
+
+    void start();
+
+private:
+    std::shared_ptr<VolumeBase> mFrom;
+    std::shared_ptr<VolumeBase> mTo;
+    std::thread mThread;
+
+    void run();
+
+    DISALLOW_COPY_AND_ASSIGN(MoveTask);
+};
+
+}  // namespace vold
+}  // namespace android
+
+#endif
diff --git a/NetlinkManager.cpp b/NetlinkManager.cpp
index d2e16b2..b5069a6 100644
--- a/NetlinkManager.cpp
+++ b/NetlinkManager.cpp
@@ -58,8 +58,8 @@
     nladdr.nl_pid = getpid();
     nladdr.nl_groups = 0xffffffff;
 
-    if ((mSock = socket(PF_NETLINK,
-                        SOCK_DGRAM,NETLINK_KOBJECT_UEVENT)) < 0) {
+    if ((mSock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC,
+            NETLINK_KOBJECT_UEVENT)) < 0) {
         SLOGE("Unable to create uevent socket: %s", strerror(errno));
         return -1;
     }
diff --git a/PrivateVolume.cpp b/PrivateVolume.cpp
new file mode 100644
index 0000000..ff2c7b3
--- /dev/null
+++ b/PrivateVolume.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Ext4.h"
+#include "PrivateVolume.h"
+#include "EmulatedVolume.h"
+#include "Utils.h"
+#include "VolumeManager.h"
+#include "ResponseCode.h"
+#include "cryptfs.h"
+
+#include <base/stringprintf.h>
+#include <base/logging.h>
+#include <cutils/fs.h>
+#include <private/android_filesystem_config.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+
+using android::base::StringPrintf;
+
+namespace android {
+namespace vold {
+
+PrivateVolume::PrivateVolume(dev_t device, const std::string& keyRaw) :
+        VolumeBase(Type::kPrivate), mRawDevice(device), mKeyRaw(keyRaw) {
+    setId(StringPrintf("private:%u,%u", major(device), minor(device)));
+    mRawDevPath = StringPrintf("/dev/block/vold/%s", getId().c_str());
+}
+
+PrivateVolume::~PrivateVolume() {
+}
+
+status_t PrivateVolume::readMetadata() {
+    status_t res = ReadMetadata(mDmDevPath, mFsType, mFsUuid, mFsLabel);
+    notifyEvent(ResponseCode::VolumeFsTypeChanged, mFsType);
+    notifyEvent(ResponseCode::VolumeFsUuidChanged, mFsUuid);
+    notifyEvent(ResponseCode::VolumeFsLabelChanged, mFsLabel);
+    return res;
+}
+
+status_t PrivateVolume::doCreate() {
+    if (CreateDeviceNode(mRawDevPath, mRawDevice)) {
+        return -EIO;
+    }
+
+    // Recover from stale vold by tearing down any old mappings
+    cryptfs_revert_ext_volume(getId().c_str());
+
+    // TODO: figure out better SELinux labels for private volumes
+
+    unsigned char* key = (unsigned char*) mKeyRaw.data();
+    char crypto_blkdev[MAXPATHLEN];
+    int res = cryptfs_setup_ext_volume(getId().c_str(), mRawDevPath.c_str(),
+            key, mKeyRaw.size(), crypto_blkdev);
+    mDmDevPath = crypto_blkdev;
+    if (res != 0) {
+        PLOG(ERROR) << getId() << " failed to setup cryptfs";
+        return -EIO;
+    }
+
+    return OK;
+}
+
+status_t PrivateVolume::doDestroy() {
+    if (cryptfs_revert_ext_volume(getId().c_str())) {
+        LOG(ERROR) << getId() << " failed to revert cryptfs";
+    }
+    return DestroyDeviceNode(mRawDevPath);
+}
+
+status_t PrivateVolume::doMount() {
+    if (readMetadata()) {
+        LOG(ERROR) << getId() << " failed to read metadata";
+        return -EIO;
+    }
+
+    mPath = StringPrintf("/mnt/expand/%s", mFsUuid.c_str());
+    setPath(mPath);
+
+    if (PrepareDir(mPath, 0700, AID_ROOT, AID_ROOT)) {
+        PLOG(ERROR) << getId() << " failed to create mount point " << mPath;
+        return -EIO;
+    }
+
+    int res = Ext4::check(mDmDevPath.c_str(), mPath.c_str());
+    if (res == 0 || res == 1) {
+        LOG(DEBUG) << getId() << " passed filesystem check";
+    } else {
+        PLOG(ERROR) << getId() << " failed filesystem check";
+        return -EIO;
+    }
+
+    if (Ext4::doMount(mDmDevPath.c_str(), mPath.c_str(), false, false, true)) {
+        PLOG(ERROR) << getId() << " failed to mount";
+        return -EIO;
+    }
+
+    // Verify that common directories are ready to roll
+    if (PrepareDir(mPath + "/app", 0771, AID_SYSTEM, AID_SYSTEM) ||
+            PrepareDir(mPath + "/user", 0711, AID_SYSTEM, AID_SYSTEM) ||
+            PrepareDir(mPath + "/media", 0770, AID_MEDIA_RW, AID_MEDIA_RW) ||
+            PrepareDir(mPath + "/local", 0751, AID_ROOT, AID_ROOT) ||
+            PrepareDir(mPath + "/local/tmp", 0771, AID_SHELL, AID_SHELL)) {
+        PLOG(ERROR) << getId() << " failed to prepare";
+        return -EIO;
+    }
+
+    // Create a new emulated volume stacked above us, it will automatically
+    // be destroyed during unmount
+    std::string mediaPath(mPath + "/media");
+    auto vol = std::shared_ptr<VolumeBase>(
+            new EmulatedVolume(mediaPath, mRawDevice, mFsUuid));
+    addVolume(vol);
+    vol->create();
+
+    return OK;
+}
+
+status_t PrivateVolume::doUnmount() {
+    ForceUnmount(mPath);
+
+    if (TEMP_FAILURE_RETRY(rmdir(mPath.c_str()))) {
+        PLOG(ERROR) << getId() << " failed to rmdir mount point " << mPath;
+    }
+
+    return OK;
+}
+
+status_t PrivateVolume::doFormat() {
+    // TODO: change mountpoint once we have selinux labels
+    if (Ext4::format(mDmDevPath.c_str(), 0, "/data")) {
+        PLOG(ERROR) << getId() << " failed to format";
+        return -EIO;
+    }
+
+    return OK;
+}
+
+}  // namespace vold
+}  // namespace android
diff --git a/PrivateVolume.h b/PrivateVolume.h
new file mode 100644
index 0000000..bd464e6
--- /dev/null
+++ b/PrivateVolume.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VOLD_PRIVATE_VOLUME_H
+#define ANDROID_VOLD_PRIVATE_VOLUME_H
+
+#include "VolumeBase.h"
+
+#include <cutils/multiuser.h>
+
+namespace android {
+namespace vold {
+
+/*
+ * Private storage provided by an encrypted partition.
+ *
+ * Given a raw block device, it knows how to wrap it in dm-crypt and
+ * format as ext4/f2fs.  EmulatedVolume can be stacked above it.
+ *
+ * This volume is designed to behave much like the internal /data
+ * partition, both in layout and function.  For example, apps and
+ * private app data can be safely stored on this volume because the
+ * keys are tightly tied to this device.
+ */
+class PrivateVolume : public VolumeBase {
+public:
+    PrivateVolume(dev_t device, const std::string& keyRaw);
+    virtual ~PrivateVolume();
+
+protected:
+    status_t doCreate() override;
+    status_t doDestroy() override;
+    status_t doMount() override;
+    status_t doUnmount() override;
+    status_t doFormat() override;
+
+    status_t readMetadata();
+
+private:
+    /* Kernel device of raw, encrypted partition */
+    dev_t mRawDevice;
+    /* Path to raw, encrypted block device */
+    std::string mRawDevPath;
+    /* Path to decrypted block device */
+    std::string mDmDevPath;
+    /* Path where decrypted device is mounted */
+    std::string mPath;
+
+    /* Encryption key as raw bytes */
+    std::string mKeyRaw;
+
+    /* Filesystem type */
+    std::string mFsType;
+    /* Filesystem UUID */
+    std::string mFsUuid;
+    /* User-visible filesystem label */
+    std::string mFsLabel;
+
+    DISALLOW_COPY_AND_ASSIGN(PrivateVolume);
+};
+
+}  // namespace vold
+}  // namespace android
+
+#endif
diff --git a/Process.cpp b/Process.cpp
index cc06998..a6f0cc6 100644
--- a/Process.cpp
+++ b/Process.cpp
@@ -66,7 +66,7 @@
 void Process::getProcessName(int pid, char *buffer, size_t max) {
     int fd;
     snprintf(buffer, max, "/proc/%d/cmdline", pid);
-    fd = open(buffer, O_RDONLY);
+    fd = open(buffer, O_RDONLY | O_CLOEXEC);
     if (fd < 0) {
         strcpy(buffer, "???");
     } else {
@@ -170,18 +170,14 @@
     return result;
 }
 
-extern "C" void vold_killProcessesWithOpenFiles(const char *path, int action) {
-	Process::killProcessesWithOpenFiles(path, action);
+extern "C" void vold_killProcessesWithOpenFiles(const char *path, int signal) {
+	Process::killProcessesWithOpenFiles(path, signal);
 }
 
 /*
  * Hunt down processes that have files open at the given mount point.
- * action = 0 to just warn,
- * action = 1 to SIGHUP,
- * action = 2 to SIGKILL
  */
-// hunt down and kill processes that have files open on the given mount point
-void Process::killProcessesWithOpenFiles(const char *path, int action) {
+void Process::killProcessesWithOpenFiles(const char *path, int signal) {
     DIR*    dir;
     struct dirent* de;
 
@@ -213,12 +209,10 @@
         } else {
             continue;
         }
-        if (action == 1) {
-            SLOGW("Sending SIGHUP to process %d", pid);
-            kill(pid, SIGTERM);
-        } else if (action == 2) {
-            SLOGE("Sending SIGKILL to process %d", pid);
-            kill(pid, SIGKILL);
+
+        if (signal != 0) {
+            SLOGW("Sending %s to process %d", strsignal(signal), pid);
+            kill(pid, signal);
         }
     }
     closedir(dir);
diff --git a/Process.h b/Process.h
index e745ca4..81b5f18 100644
--- a/Process.h
+++ b/Process.h
@@ -21,7 +21,7 @@
 
 class Process {
 public:
-    static void killProcessesWithOpenFiles(const char *path, int action);
+    static void killProcessesWithOpenFiles(const char *path, int signal);
     static int getPid(const char *s);
     static int checkSymLink(int pid, const char *path, const char *name);
     static int checkFileMaps(int pid, const char *path);
@@ -36,7 +36,7 @@
 
 extern "C" {
 #endif /* __cplusplus */
-	void vold_killProcessesWithOpenFiles(const char *path, int action);
+	void vold_killProcessesWithOpenFiles(const char *path, int signal);
 #ifdef __cplusplus
 }
 #endif
diff --git a/PublicVolume.cpp b/PublicVolume.cpp
new file mode 100644
index 0000000..025d2eb
--- /dev/null
+++ b/PublicVolume.cpp
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Fat.h"
+#include "PublicVolume.h"
+#include "Utils.h"
+#include "VolumeManager.h"
+#include "ResponseCode.h"
+
+#include <base/stringprintf.h>
+#include <base/logging.h>
+#include <cutils/fs.h>
+#include <private/android_filesystem_config.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+using android::base::StringPrintf;
+
+namespace android {
+namespace vold {
+
+static const char* kFusePath = "/system/bin/sdcard";
+
+static const char* kAsecPath = "/mnt/secure/asec";
+
+PublicVolume::PublicVolume(dev_t device) :
+        VolumeBase(Type::kPublic), mDevice(device), mFusePid(0) {
+    setId(StringPrintf("public:%u,%u", major(device), minor(device)));
+    mDevPath = StringPrintf("/dev/block/vold/%s", getId().c_str());
+}
+
+PublicVolume::~PublicVolume() {
+}
+
+status_t PublicVolume::readMetadata() {
+    status_t res = ReadMetadataUntrusted(mDevPath, mFsType, mFsUuid, mFsLabel);
+    notifyEvent(ResponseCode::VolumeFsTypeChanged, mFsType);
+    notifyEvent(ResponseCode::VolumeFsUuidChanged, mFsUuid);
+    notifyEvent(ResponseCode::VolumeFsLabelChanged, mFsLabel);
+    return res;
+}
+
+status_t PublicVolume::initAsecStage() {
+    std::string legacyPath(mRawPath + "/android_secure");
+    std::string securePath(mRawPath + "/.android_secure");
+
+    // Recover legacy secure path
+    if (!access(legacyPath.c_str(), R_OK | X_OK)
+            && access(securePath.c_str(), R_OK | X_OK)) {
+        if (rename(legacyPath.c_str(), securePath.c_str())) {
+            PLOG(WARNING) << getId() << " failed to rename legacy ASEC dir";
+        }
+    }
+
+    if (TEMP_FAILURE_RETRY(mkdir(securePath.c_str(), 0700))) {
+        if (errno != EEXIST) {
+            PLOG(WARNING) << getId() << " creating ASEC stage failed";
+            return -errno;
+        }
+    }
+
+    BindMount(securePath, kAsecPath);
+
+    return OK;
+}
+
+status_t PublicVolume::doCreate() {
+    return CreateDeviceNode(mDevPath, mDevice);
+}
+
+status_t PublicVolume::doDestroy() {
+    return DestroyDeviceNode(mDevPath);
+}
+
+status_t PublicVolume::doMount() {
+    // TODO: expand to support mounting other filesystems
+    readMetadata();
+
+    if (Fat::check(mDevPath.c_str())) {
+        LOG(ERROR) << getId() << " failed filesystem check";
+        return -EIO;
+    }
+
+    // Use UUID as stable name, if available
+    std::string stableName = getId();
+    if (!mFsUuid.empty()) {
+        stableName = mFsUuid;
+    }
+
+    mRawPath = StringPrintf("/mnt/media_rw/%s", stableName.c_str());
+    mFusePath = StringPrintf("/storage/%s", stableName.c_str());
+    setPath(mFusePath);
+
+    if (fs_prepare_dir(mRawPath.c_str(), 0700, AID_ROOT, AID_ROOT)) {
+        PLOG(ERROR) << getId() << " failed to create mount point " << mRawPath;
+        return -errno;
+    }
+    if (fs_prepare_dir(mFusePath.c_str(), 0700, AID_ROOT, AID_ROOT)) {
+        PLOG(ERROR) << getId() << " failed to create mount point " << mFusePath;
+        return -errno;
+    }
+
+    if (Fat::doMount(mDevPath.c_str(), mRawPath.c_str(), false, false, false,
+            AID_MEDIA_RW, AID_MEDIA_RW, 0007, true)) {
+        PLOG(ERROR) << getId() << " failed to mount " << mDevPath;
+        return -EIO;
+    }
+
+    if (getMountFlags() & MountFlags::kPrimary) {
+        initAsecStage();
+    }
+
+    // TODO: teach FUSE daemon to protect itself with user-specific GID
+    if (!(mFusePid = fork())) {
+        if (!(getMountFlags() & MountFlags::kVisible)) {
+            // TODO: mount so that only system apps can access
+            if (execl(kFusePath, kFusePath,
+                    "-u", "1023", // AID_MEDIA_RW
+                    "-g", "1023", // AID_MEDIA_RW
+                    mRawPath.c_str(),
+                    mFusePath.c_str(),
+                    NULL)) {
+                PLOG(ERROR) << "Failed to exec";
+            }
+        } else if (getMountFlags() & MountFlags::kPrimary) {
+            if (execl(kFusePath, kFusePath,
+                    "-u", "1023", // AID_MEDIA_RW
+                    "-g", "1023", // AID_MEDIA_RW
+                    "-d",
+                    mRawPath.c_str(),
+                    mFusePath.c_str(),
+                    NULL)) {
+                PLOG(ERROR) << "Failed to exec";
+            }
+        } else {
+            if (execl(kFusePath, kFusePath,
+                    "-u", "1023", // AID_MEDIA_RW
+                    "-g", "1023", // AID_MEDIA_RW
+                    "-w", "1023", // AID_MEDIA_RW
+                    "-d",
+                    mRawPath.c_str(),
+                    mFusePath.c_str(),
+                    NULL)) {
+                PLOG(ERROR) << "Failed to exec";
+            }
+        }
+
+        PLOG(DEBUG) << "FUSE exiting";
+        _exit(1);
+    }
+
+    if (mFusePid == -1) {
+        PLOG(ERROR) << getId() << " failed to fork";
+        return -errno;
+    }
+
+    return OK;
+}
+
+status_t PublicVolume::doUnmount() {
+    if (mFusePid > 0) {
+        kill(mFusePid, SIGTERM);
+        TEMP_FAILURE_RETRY(waitpid(mFusePid, nullptr, 0));
+        mFusePid = 0;
+    }
+
+    ForceUnmount(kAsecPath);
+    ForceUnmount(mFusePath);
+    ForceUnmount(mRawPath);
+
+    if (TEMP_FAILURE_RETRY(rmdir(mRawPath.c_str()))) {
+        PLOG(ERROR) << getId() << " failed to rmdir mount point " << mRawPath;
+    }
+    if (TEMP_FAILURE_RETRY(rmdir(mFusePath.c_str()))) {
+        PLOG(ERROR) << getId() << " failed to rmdir mount point " << mFusePath;
+    }
+
+    mFusePath.clear();
+    mRawPath.clear();
+
+    return OK;
+}
+
+status_t PublicVolume::doFormat() {
+    if (Fat::format(mDevPath.c_str(), 0, true)) {
+        LOG(ERROR) << getId() << " failed to format";
+        return -errno;
+    }
+    return OK;
+}
+
+}  // namespace vold
+}  // namespace android
diff --git a/PublicVolume.h b/PublicVolume.h
new file mode 100644
index 0000000..45313ec
--- /dev/null
+++ b/PublicVolume.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VOLD_PUBLIC_VOLUME_H
+#define ANDROID_VOLD_PUBLIC_VOLUME_H
+
+#include "VolumeBase.h"
+
+#include <cutils/multiuser.h>
+
+namespace android {
+namespace vold {
+
+/*
+ * Shared storage provided by public (vfat) partition.
+ *
+ * Knows how to mount itself and then spawn a FUSE daemon to synthesize
+ * permissions.  AsecVolume and ObbVolume can be stacked above it.
+ *
+ * This volume is not inherently multi-user aware, so it has two possible
+ * modes of operation:
+ * 1. If primary storage for the device, it only binds itself to the
+ * owner user.
+ * 2. If secondary storage, it binds itself for all users, but masks
+ * away the Android directory for secondary users.
+ */
+class PublicVolume : public VolumeBase {
+public:
+    explicit PublicVolume(dev_t device);
+    virtual ~PublicVolume();
+
+protected:
+    status_t doCreate() override;
+    status_t doDestroy() override;
+    status_t doMount() override;
+    status_t doUnmount() override;
+    status_t doFormat() override;
+
+    status_t readMetadata();
+    status_t initAsecStage();
+
+private:
+    /* Kernel device representing partition */
+    dev_t mDevice;
+    /* Block device path */
+    std::string mDevPath;
+    /* Mount point of raw partition */
+    std::string mRawPath;
+    /* Mount point of FUSE wrapper */
+    std::string mFusePath;
+    /* PID of FUSE wrapper */
+    pid_t mFusePid;
+
+    /* Filesystem type */
+    std::string mFsType;
+    /* Filesystem UUID */
+    std::string mFsUuid;
+    /* User-visible filesystem label */
+    std::string mFsLabel;
+
+    DISALLOW_COPY_AND_ASSIGN(PublicVolume);
+};
+
+}  // namespace vold
+}  // namespace android
+
+#endif
diff --git a/ResponseCode.h b/ResponseCode.h
index 0dc0500..a975982 100644
--- a/ResponseCode.h
+++ b/ResponseCode.h
@@ -66,6 +66,23 @@
     static const int VolumeDiskRemoved             = 631;
     static const int VolumeBadRemoval              = 632;
 
+    static const int DiskCreated = 640;
+    static const int DiskSizeChanged = 641;
+    static const int DiskLabelChanged = 642;
+    static const int DiskScanned = 643;
+    static const int DiskDestroyed = 649;
+
+    static const int VolumeCreated = 650;
+    static const int VolumeStateChanged = 651;
+    static const int VolumeFsTypeChanged = 652;
+    static const int VolumeFsUuidChanged = 653;
+    static const int VolumeFsLabelChanged = 654;
+    static const int VolumePathChanged = 655;
+    static const int VolumeInternalPathChanged = 656;
+    static const int VolumeDestroyed = 659;
+
+    static const int MoveStatus = 660;
+
     static int convertFromErrno();
 };
 #endif
diff --git a/Utils.cpp b/Utils.cpp
new file mode 100644
index 0000000..158a61e
--- /dev/null
+++ b/Utils.cpp
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sehandle.h"
+#include "Utils.h"
+#include "Process.h"
+
+#include <base/logging.h>
+#include <base/stringprintf.h>
+#include <cutils/fs.h>
+#include <private/android_filesystem_config.h>
+#include <logwrap/logwrap.h>
+
+#include <mutex>
+#include <dirent.h>
+#include <fcntl.h>
+#include <linux/fs.h>
+#include <stdlib.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/statvfs.h>
+
+#ifndef UMOUNT_NOFOLLOW
+#define UMOUNT_NOFOLLOW    0x00000008  /* Don't follow symlink on umount */
+#endif
+
+using android::base::StringPrintf;
+
+namespace android {
+namespace vold {
+
+security_context_t sBlkidContext = nullptr;
+security_context_t sBlkidUntrustedContext = nullptr;
+security_context_t sFsckContext = nullptr;
+security_context_t sFsckUntrustedContext = nullptr;
+
+static const char* kBlkidPath = "/system/bin/blkid";
+
+status_t CreateDeviceNode(const std::string& path, dev_t dev) {
+    const char* cpath = path.c_str();
+    status_t res = 0;
+
+    char* secontext = nullptr;
+    if (sehandle) {
+        if (!selabel_lookup(sehandle, &secontext, cpath, S_IFBLK)) {
+            setfscreatecon(secontext);
+        }
+    }
+
+    mode_t mode = 0660 | S_IFBLK;
+    if (mknod(cpath, mode, dev) < 0) {
+        if (errno != EEXIST) {
+            PLOG(ERROR) << "Failed to create device node for " << major(dev)
+                    << ":" << minor(dev) << " at " << path;
+            res = -errno;
+        }
+    }
+
+    if (secontext) {
+        setfscreatecon(nullptr);
+        freecon(secontext);
+    }
+
+    return res;
+}
+
+status_t DestroyDeviceNode(const std::string& path) {
+    const char* cpath = path.c_str();
+    if (TEMP_FAILURE_RETRY(unlink(cpath))) {
+        return -errno;
+    } else {
+        return OK;
+    }
+}
+
+status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid) {
+    const char* cpath = path.c_str();
+
+    char* secontext = nullptr;
+    if (sehandle) {
+        if (!selabel_lookup(sehandle, &secontext, cpath, S_IFDIR)) {
+            setfscreatecon(secontext);
+        }
+    }
+
+    int res = fs_prepare_dir(cpath, mode, uid, gid);
+
+    if (secontext) {
+        setfscreatecon(nullptr);
+        freecon(secontext);
+    }
+
+    if (res == 0) {
+        return OK;
+    } else {
+        return -errno;
+    }
+}
+
+status_t ForceUnmount(const std::string& path) {
+    const char* cpath = path.c_str();
+    if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
+        return OK;
+    }
+    PLOG(WARNING) << "Failed to unmount " << path;
+
+    sleep(5);
+    Process::killProcessesWithOpenFiles(cpath, SIGINT);
+
+    if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
+        return OK;
+    }
+    PLOG(WARNING) << "Failed to unmount " << path;
+
+    sleep(5);
+    Process::killProcessesWithOpenFiles(cpath, SIGTERM);
+
+    if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
+        return OK;
+    }
+    PLOG(WARNING) << "Failed to unmount " << path;
+
+    sleep(5);
+    Process::killProcessesWithOpenFiles(cpath, SIGKILL);
+
+    if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
+        return OK;
+    }
+    PLOG(ERROR) << "Failed to unmount " << path;
+
+    return -errno;
+}
+
+status_t BindMount(const std::string& source, const std::string& target) {
+    if (::mount(source.c_str(), target.c_str(), "", MS_BIND, NULL)) {
+        PLOG(ERROR) << "Failed to bind mount " << source << " to " << target;
+        return -errno;
+    }
+    return OK;
+}
+
+static status_t readMetadata(const std::string& path, std::string& fsType,
+        std::string& fsUuid, std::string& fsLabel, bool untrusted) {
+    fsType.clear();
+    fsUuid.clear();
+    fsLabel.clear();
+
+    std::vector<std::string> cmd;
+    cmd.push_back(kBlkidPath);
+    cmd.push_back("-c");
+    cmd.push_back("/dev/null");
+    cmd.push_back(path);
+
+    std::vector<std::string> output;
+    status_t res = ForkExecvp(cmd, output, untrusted ? sBlkidUntrustedContext : sBlkidContext);
+    if (res != OK) {
+        LOG(WARNING) << "blkid failed to identify " << path;
+        return res;
+    }
+
+    char value[128];
+    for (auto line : output) {
+        // Extract values from blkid output, if defined
+        const char* cline = line.c_str();
+        char* start = strstr(cline, "TYPE=");
+        if (start != nullptr && sscanf(start + 5, "\"%127[^\"]\"", value) == 1) {
+            fsType = value;
+        }
+
+        start = strstr(cline, "UUID=");
+        if (start != nullptr && sscanf(start + 5, "\"%127[^\"]\"", value) == 1) {
+            fsUuid = value;
+        }
+
+        start = strstr(cline, "LABEL=");
+        if (start != nullptr && sscanf(start + 6, "\"%127[^\"]\"", value) == 1) {
+            fsLabel = value;
+        }
+    }
+
+    return OK;
+}
+
+status_t ReadMetadata(const std::string& path, std::string& fsType,
+        std::string& fsUuid, std::string& fsLabel) {
+    return readMetadata(path, fsType, fsUuid, fsLabel, false);
+}
+
+status_t ReadMetadataUntrusted(const std::string& path, std::string& fsType,
+        std::string& fsUuid, std::string& fsLabel) {
+    return readMetadata(path, fsType, fsUuid, fsLabel, true);
+}
+
+status_t ForkExecvp(const std::vector<std::string>& args) {
+    return ForkExecvp(args, nullptr);
+}
+
+status_t ForkExecvp(const std::vector<std::string>& args, security_context_t context) {
+    size_t argc = args.size();
+    char** argv = (char**) calloc(argc, sizeof(char*));
+    for (size_t i = 0; i < argc; i++) {
+        argv[i] = (char*) args[i].c_str();
+        if (i == 0) {
+            LOG(VERBOSE) << args[i];
+        } else {
+            LOG(VERBOSE) << "    " << args[i];
+        }
+    }
+
+    if (setexeccon(context)) {
+        LOG(ERROR) << "Failed to setexeccon";
+        abort();
+    }
+    status_t res = android_fork_execvp(argc, argv, NULL, false, true);
+    if (setexeccon(nullptr)) {
+        LOG(ERROR) << "Failed to setexeccon";
+        abort();
+    }
+
+    free(argv);
+    return res;
+}
+
+status_t ForkExecvp(const std::vector<std::string>& args,
+        std::vector<std::string>& output) {
+    return ForkExecvp(args, output, nullptr);
+}
+
+status_t ForkExecvp(const std::vector<std::string>& args,
+        std::vector<std::string>& output, security_context_t context) {
+    std::string cmd;
+    for (size_t i = 0; i < args.size(); i++) {
+        cmd += args[i] + " ";
+        if (i == 0) {
+            LOG(VERBOSE) << args[i];
+        } else {
+            LOG(VERBOSE) << "    " << args[i];
+        }
+    }
+    output.clear();
+
+    if (setexeccon(context)) {
+        LOG(ERROR) << "Failed to setexeccon";
+        abort();
+    }
+    FILE* fp = popen(cmd.c_str(), "r");
+    if (setexeccon(nullptr)) {
+        LOG(ERROR) << "Failed to setexeccon";
+        abort();
+    }
+
+    if (!fp) {
+        PLOG(ERROR) << "Failed to popen " << cmd;
+        return -errno;
+    }
+    char line[1024];
+    while (fgets(line, sizeof(line), fp) != nullptr) {
+        LOG(VERBOSE) << line;
+        output.push_back(std::string(line));
+    }
+    if (pclose(fp) != 0) {
+        PLOG(ERROR) << "Failed to pclose " << cmd;
+        return -errno;
+    }
+
+    return OK;
+}
+
+pid_t ForkExecvpAsync(const std::vector<std::string>& args) {
+    size_t argc = args.size();
+    char** argv = (char**) calloc(argc + 1, sizeof(char*));
+    for (size_t i = 0; i < argc; i++) {
+        argv[i] = (char*) args[i].c_str();
+        if (i == 0) {
+            LOG(VERBOSE) << args[i];
+        } else {
+            LOG(VERBOSE) << "    " << args[i];
+        }
+    }
+
+    pid_t pid = fork();
+    if (pid == 0) {
+        close(STDIN_FILENO);
+        close(STDOUT_FILENO);
+        close(STDERR_FILENO);
+
+        if (execvp(argv[0], argv)) {
+            PLOG(ERROR) << "Failed to exec";
+        }
+
+        _exit(1);
+    }
+
+    if (pid == -1) {
+        PLOG(ERROR) << "Failed to exec";
+    }
+
+    free(argv);
+    return pid;
+}
+
+status_t ReadRandomBytes(size_t bytes, std::string& out) {
+    out.clear();
+
+    int fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
+    if (fd == -1) {
+        return -errno;
+    }
+
+    char buf[BUFSIZ];
+    size_t n;
+    while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], std::min(sizeof(buf), bytes)))) > 0) {
+        out.append(buf, n);
+        bytes -= n;
+    }
+    TEMP_FAILURE_RETRY(close(fd));
+
+    if (bytes == 0) {
+        return OK;
+    } else {
+        return -EIO;
+    }
+}
+
+status_t HexToStr(const std::string& hex, std::string& str) {
+    str.clear();
+    bool even = true;
+    char cur = 0;
+    for (size_t i = 0; i < hex.size(); i++) {
+        int val = 0;
+        switch (hex[i]) {
+        case ' ': case '-': case ':': continue;
+        case 'f': case 'F': val = 15; break;
+        case 'e': case 'E': val = 14; break;
+        case 'd': case 'D': val = 13; break;
+        case 'c': case 'C': val = 12; break;
+        case 'b': case 'B': val = 11; break;
+        case 'a': case 'A': val = 10; break;
+        case '9': val = 9; break;
+        case '8': val = 8; break;
+        case '7': val = 7; break;
+        case '6': val = 6; break;
+        case '5': val = 5; break;
+        case '4': val = 4; break;
+        case '3': val = 3; break;
+        case '2': val = 2; break;
+        case '1': val = 1; break;
+        case '0': val = 0; break;
+        default: return -EINVAL;
+        }
+
+        if (even) {
+            cur = val << 4;
+        } else {
+            cur += val;
+            str.push_back(cur);
+            cur = 0;
+        }
+        even = !even;
+    }
+    return even ? OK : -EINVAL;
+}
+
+static const char* kLookup = "0123456789abcdef";
+
+status_t StrToHex(const std::string& str, std::string& hex) {
+    hex.clear();
+    for (size_t i = 0; i < str.size(); i++) {
+        hex.push_back(kLookup[str[i] >> 4]);
+        hex.push_back(kLookup[str[i] & 0x0F]);
+    }
+    return OK;
+}
+
+uint64_t GetFreeBytes(const std::string& path) {
+    struct statvfs sb;
+    if (statvfs(path.c_str(), &sb) == 0) {
+        return sb.f_bfree * sb.f_bsize;
+    } else {
+        return -1;
+    }
+}
+
+// TODO: borrowed from frameworks/native/libs/diskusage/ which should
+// eventually be migrated into system/
+static int64_t stat_size(struct stat *s) {
+    int64_t blksize = s->st_blksize;
+    // count actual blocks used instead of nominal file size
+    int64_t size = s->st_blocks * 512;
+
+    if (blksize) {
+        /* round up to filesystem block size */
+        size = (size + blksize - 1) & (~(blksize - 1));
+    }
+
+    return size;
+}
+
+// TODO: borrowed from frameworks/native/libs/diskusage/ which should
+// eventually be migrated into system/
+int64_t calculate_dir_size(int dfd) {
+    int64_t size = 0;
+    struct stat s;
+    DIR *d;
+    struct dirent *de;
+
+    d = fdopendir(dfd);
+    if (d == NULL) {
+        close(dfd);
+        return 0;
+    }
+
+    while ((de = readdir(d))) {
+        const char *name = de->d_name;
+        if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) {
+            size += stat_size(&s);
+        }
+        if (de->d_type == DT_DIR) {
+            int subfd;
+
+            /* always skip "." and ".." */
+            if (name[0] == '.') {
+                if (name[1] == 0)
+                    continue;
+                if ((name[1] == '.') && (name[2] == 0))
+                    continue;
+            }
+
+            subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY);
+            if (subfd >= 0) {
+                size += calculate_dir_size(subfd);
+            }
+        }
+    }
+    closedir(d);
+    return size;
+}
+
+uint64_t GetTreeBytes(const std::string& path) {
+    int dirfd = open(path.c_str(), O_DIRECTORY, O_RDONLY);
+    if (dirfd < 0) {
+        PLOG(WARNING) << "Failed to open " << path;
+        return -1;
+    } else {
+        uint64_t res = calculate_dir_size(dirfd);
+        close(dirfd);
+        return res;
+    }
+}
+
+}  // namespace vold
+}  // namespace android
diff --git a/Utils.h b/Utils.h
new file mode 100644
index 0000000..6ad87ae
--- /dev/null
+++ b/Utils.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VOLD_UTILS_H
+#define ANDROID_VOLD_UTILS_H
+
+#include <utils/Errors.h>
+#include <selinux/selinux.h>
+
+#include <vector>
+#include <string>
+
+// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions. It goes in the private:
+// declarations in a class.
+#if !defined(DISALLOW_COPY_AND_ASSIGN)
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+    TypeName(const TypeName&) = delete;  \
+    void operator=(const TypeName&) = delete
+#endif
+
+namespace android {
+namespace vold {
+
+/* SELinux contexts used depending on the block device type */
+extern security_context_t sBlkidContext;
+extern security_context_t sBlkidUntrustedContext;
+extern security_context_t sFsckContext;
+extern security_context_t sFsckUntrustedContext;
+
+status_t CreateDeviceNode(const std::string& path, dev_t dev);
+status_t DestroyDeviceNode(const std::string& path);
+
+/* fs_prepare_dir wrapper that creates with SELinux context */
+status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid);
+
+/* Really unmounts the path, killing active processes along the way */
+status_t ForceUnmount(const std::string& path);
+
+/* Creates bind mount from source to target */
+status_t BindMount(const std::string& source, const std::string& target);
+
+/* Reads filesystem metadata from device at path */
+status_t ReadMetadata(const std::string& path, std::string& fsType,
+        std::string& fsUuid, std::string& fsLabel);
+
+/* Reads filesystem metadata from untrusted device at path */
+status_t ReadMetadataUntrusted(const std::string& path, std::string& fsType,
+        std::string& fsUuid, std::string& fsLabel);
+
+/* Returns either WEXITSTATUS() status, or a negative errno */
+status_t ForkExecvp(const std::vector<std::string>& args);
+status_t ForkExecvp(const std::vector<std::string>& args, security_context_t context);
+
+status_t ForkExecvp(const std::vector<std::string>& args,
+        std::vector<std::string>& output);
+status_t ForkExecvp(const std::vector<std::string>& args,
+        std::vector<std::string>& output, security_context_t context);
+
+pid_t ForkExecvpAsync(const std::vector<std::string>& args);
+
+status_t ReadRandomBytes(size_t bytes, std::string& out);
+
+/* Converts hex string to raw bytes, ignoring [ :-] */
+status_t HexToStr(const std::string& hex, std::string& str);
+/* Converts raw bytes to hex string */
+status_t StrToHex(const std::string& str, std::string& hex);
+
+uint64_t GetFreeBytes(const std::string& path);
+uint64_t GetTreeBytes(const std::string& path);
+
+}  // namespace vold
+}  // namespace android
+
+#endif
diff --git a/Volume.cpp b/Volume.cpp
deleted file mode 100644
index ce4ed1e..0000000
--- a/Volume.cpp
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <mntent.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/param.h>
-
-#include <linux/kdev_t.h>
-
-#include <cutils/properties.h>
-
-#include <diskconfig/diskconfig.h>
-
-#include <private/android_filesystem_config.h>
-
-#define LOG_TAG "Vold"
-
-#include <cutils/fs.h>
-#include <cutils/log.h>
-
-#include <string>
-
-#include "Volume.h"
-#include "VolumeManager.h"
-#include "ResponseCode.h"
-#include "Fat.h"
-#include "Process.h"
-#include "cryptfs.h"
-#include "sehandle.h"
-
-extern "C" void dos_partition_dec(void const *pp, struct dos_partition *d);
-extern "C" void dos_partition_enc(void *pp, struct dos_partition *d);
-
-
-/*
- * Media directory - stuff that only media_rw user can see
- */
-const char *Volume::MEDIA_DIR           = "/mnt/media_rw";
-
-/*
- * Fuse directory - location where fuse wrapped filesystems go
- */
-const char *Volume::FUSE_DIR           = "/storage";
-
-/*
- * Path to external storage where *only* root can access ASEC image files
- */
-const char *Volume::SEC_ASECDIR_EXT   = "/mnt/secure/asec";
-
-/*
- * Path to internal storage where *only* root can access ASEC image files
- */
-const char *Volume::SEC_ASECDIR_INT   = "/data/app-asec";
-
-/*
- * Path to where secure containers are mounted
- */
-const char *Volume::ASECDIR           = "/mnt/asec";
-
-/*
- * Path to where OBBs are mounted
- */
-const char *Volume::LOOPDIR           = "/mnt/obb";
-
-const char *Volume::BLKID_PATH = "/system/bin/blkid";
-
-static const char *stateToStr(int state) {
-    if (state == Volume::State_Init)
-        return "Initializing";
-    else if (state == Volume::State_NoMedia)
-        return "No-Media";
-    else if (state == Volume::State_Idle)
-        return "Idle-Unmounted";
-    else if (state == Volume::State_Pending)
-        return "Pending";
-    else if (state == Volume::State_Mounted)
-        return "Mounted";
-    else if (state == Volume::State_Unmounting)
-        return "Unmounting";
-    else if (state == Volume::State_Checking)
-        return "Checking";
-    else if (state == Volume::State_Formatting)
-        return "Formatting";
-    else if (state == Volume::State_Shared)
-        return "Shared-Unmounted";
-    else if (state == Volume::State_SharedMnt)
-        return "Shared-Mounted";
-    else
-        return "Unknown-Error";
-}
-
-Volume::Volume(VolumeManager *vm, const fstab_rec* rec, int flags) {
-    mVm = vm;
-    mDebug = false;
-    mLabel = strdup(rec->label);
-    mUuid = NULL;
-    mUserLabel = NULL;
-    mState = Volume::State_Init;
-    mFlags = flags;
-    mCurrentlyMountedKdev = -1;
-    mPartIdx = rec->partnum;
-    mRetryMount = false;
-}
-
-Volume::~Volume() {
-    free(mLabel);
-    free(mUuid);
-    free(mUserLabel);
-}
-
-void Volume::setDebug(bool enable) {
-    mDebug = enable;
-}
-
-dev_t Volume::getDiskDevice() {
-    return MKDEV(0, 0);
-};
-
-dev_t Volume::getShareDevice() {
-    return getDiskDevice();
-}
-
-void Volume::handleVolumeShared() {
-}
-
-void Volume::handleVolumeUnshared() {
-}
-
-int Volume::handleBlockEvent(NetlinkEvent * /*evt*/) {
-    errno = ENOSYS;
-    return -1;
-}
-
-void Volume::setUuid(const char* uuid) {
-    char msg[256];
-
-    if (mUuid) {
-        free(mUuid);
-    }
-
-    if (uuid) {
-        mUuid = strdup(uuid);
-        snprintf(msg, sizeof(msg), "%s %s \"%s\"", getLabel(),
-                getFuseMountpoint(), mUuid);
-    } else {
-        mUuid = NULL;
-        snprintf(msg, sizeof(msg), "%s %s", getLabel(), getFuseMountpoint());
-    }
-
-    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeUuidChange, msg,
-            false);
-}
-
-void Volume::setUserLabel(const char* userLabel) {
-    char msg[256];
-
-    if (mUserLabel) {
-        free(mUserLabel);
-    }
-
-    if (userLabel) {
-        mUserLabel = strdup(userLabel);
-        snprintf(msg, sizeof(msg), "%s %s \"%s\"", getLabel(),
-                getFuseMountpoint(), mUserLabel);
-    } else {
-        mUserLabel = NULL;
-        snprintf(msg, sizeof(msg), "%s %s", getLabel(), getFuseMountpoint());
-    }
-
-    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeUserLabelChange,
-            msg, false);
-}
-
-void Volume::setState(int state) {
-    char msg[255];
-    int oldState = mState;
-
-    if (oldState == state) {
-        SLOGW("Duplicate state (%d)\n", state);
-        return;
-    }
-
-    if ((oldState == Volume::State_Pending) && (state != Volume::State_Idle)) {
-        mRetryMount = false;
-    }
-
-    mState = state;
-
-    SLOGD("Volume %s state changing %d (%s) -> %d (%s)", mLabel,
-         oldState, stateToStr(oldState), mState, stateToStr(mState));
-    snprintf(msg, sizeof(msg),
-             "Volume %s %s state changed from %d (%s) to %d (%s)", getLabel(),
-             getFuseMountpoint(), oldState, stateToStr(oldState), mState,
-             stateToStr(mState));
-
-    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeStateChange,
-                                         msg, false);
-}
-
-int Volume::createDeviceNode(const char *path, int major, int minor) {
-    char *secontext = NULL;
-    mode_t mode = 0660 | S_IFBLK;
-    dev_t dev = (major << 8) | minor;
-    int rc;
-    if (sehandle) {
-        rc = selabel_lookup(sehandle, &secontext, path, S_IFBLK);
-        if (rc == 0)
-            setfscreatecon(secontext);
-    }
-    if (mknod(path, mode, dev) < 0) {
-        if (errno != EEXIST) {
-            int sverrno = errno;
-            if (secontext) {
-                freecon(secontext);
-                setfscreatecon(NULL);
-            }
-            errno = sverrno;
-            return -1;
-        }
-    }
-    if (secontext) {
-        setfscreatecon(NULL);
-        freecon(secontext);
-    }
-    return 0;
-}
-
-int Volume::formatVol(bool wipe) {
-
-    if (getState() == Volume::State_NoMedia) {
-        errno = ENODEV;
-        return -1;
-    } else if (getState() != Volume::State_Idle) {
-        errno = EBUSY;
-        return -1;
-    }
-
-    if (isMountpointMounted(getMountpoint())) {
-        SLOGW("Volume is idle but appears to be mounted - fixing");
-        setState(Volume::State_Mounted);
-        // mCurrentlyMountedKdev = XXX
-        errno = EBUSY;
-        return -1;
-    }
-
-    bool formatEntireDevice = (mPartIdx == -1);
-    char devicePath[255];
-    dev_t diskNode = getDiskDevice();
-    dev_t partNode =
-        MKDEV(MAJOR(diskNode),
-              MINOR(diskNode) + (formatEntireDevice ? 0 : mPartIdx));
-
-    setState(Volume::State_Formatting);
-
-    int ret = -1;
-    // Only initialize the MBR if we are formatting the entire device
-    if (formatEntireDevice) {
-        sprintf(devicePath, "/dev/block/vold/%d:%d",
-                major(diskNode), minor(diskNode));
-
-        if (initializeMbr(devicePath)) {
-            SLOGE("Failed to initialize MBR (%s)", strerror(errno));
-            goto err;
-        }
-    }
-
-    sprintf(devicePath, "/dev/block/vold/%d:%d",
-            major(partNode), minor(partNode));
-
-    if (mDebug) {
-        SLOGI("Formatting volume %s (%s)", getLabel(), devicePath);
-    }
-
-    if (Fat::format(devicePath, 0, wipe)) {
-        SLOGE("Failed to format (%s)", strerror(errno));
-        goto err;
-    }
-
-    ret = 0;
-
-err:
-    setState(Volume::State_Idle);
-    return ret;
-}
-
-bool Volume::isMountpointMounted(const char *path) {
-    FILE *fp = setmntent("/proc/mounts", "r");
-    if (fp == NULL) {
-        SLOGE("Error opening /proc/mounts (%s)", strerror(errno));
-        return false;
-    }
-
-    bool found_path = false;
-    mntent* mentry;
-    while ((mentry = getmntent(fp)) != NULL) {
-        if (strcmp(mentry->mnt_dir, path) == 0) {
-            found_path = true;
-            break;
-        }
-    }
-    endmntent(fp);
-    return found_path;
-}
-
-int Volume::mountVol() {
-    dev_t deviceNodes[4];
-    int n, i;
-    char errmsg[255];
-
-    int flags = getFlags();
-    bool providesAsec = (flags & VOL_PROVIDES_ASEC) != 0;
-
-    // TODO: handle "bind" style mounts, for emulated storage
-
-    char decrypt_state[PROPERTY_VALUE_MAX];
-    char crypto_state[PROPERTY_VALUE_MAX];
-    char encrypt_progress[PROPERTY_VALUE_MAX];
-
-    property_get("vold.decrypt", decrypt_state, "");
-    property_get("vold.encrypt_progress", encrypt_progress, "");
-
-    /* Don't try to mount the volumes if we have not yet entered the disk password
-     * or are in the process of encrypting.
-     */
-    if ((getState() == Volume::State_NoMedia) ||
-        ((!strcmp(decrypt_state, "1") || encrypt_progress[0]) && providesAsec)) {
-        snprintf(errmsg, sizeof(errmsg),
-                 "Volume %s %s mount failed - no media",
-                 getLabel(), getFuseMountpoint());
-        mVm->getBroadcaster()->sendBroadcast(
-                                         ResponseCode::VolumeMountFailedNoMedia,
-                                         errmsg, false);
-        errno = ENODEV;
-        return -1;
-    } else if (getState() != Volume::State_Idle) {
-        errno = EBUSY;
-        if (getState() == Volume::State_Pending) {
-            mRetryMount = true;
-        }
-        return -1;
-    }
-
-    if (isMountpointMounted(getMountpoint())) {
-        SLOGW("Volume is idle but appears to be mounted - fixing");
-        setState(Volume::State_Mounted);
-        // mCurrentlyMountedKdev = XXX
-        return 0;
-    }
-
-    n = getDeviceNodes((dev_t *) &deviceNodes, 4);
-    if (!n) {
-        SLOGE("Failed to get device nodes (%s)\n", strerror(errno));
-        return -1;
-    }
-
-    /* If we're running encrypted, and the volume is marked as encryptable and nonremovable,
-     * and also marked as providing Asec storage, then we need to decrypt
-     * that partition, and update the volume object to point to it's new decrypted
-     * block device
-     */
-    property_get("ro.crypto.state", crypto_state, "");
-    if (providesAsec &&
-        ((flags & (VOL_NONREMOVABLE | VOL_ENCRYPTABLE))==(VOL_NONREMOVABLE | VOL_ENCRYPTABLE)) &&
-        !strcmp(crypto_state, "encrypted") && !isDecrypted()) {
-       char new_sys_path[MAXPATHLEN];
-       char nodepath[256];
-       int new_major, new_minor;
-
-       if (n != 1) {
-           /* We only expect one device node returned when mounting encryptable volumes */
-           SLOGE("Too many device nodes returned when mounting %s\n", getMountpoint());
-           return -1;
-       }
-
-       if (cryptfs_setup_volume(getLabel(), MAJOR(deviceNodes[0]), MINOR(deviceNodes[0]),
-                                new_sys_path, sizeof(new_sys_path),
-                                &new_major, &new_minor)) {
-           SLOGE("Cannot setup encryption mapping for %s\n", getMountpoint());
-           return -1;
-       }
-       /* We now have the new sysfs path for the decrypted block device, and the
-        * majore and minor numbers for it.  So, create the device, update the
-        * path to the new sysfs path, and continue.
-        */
-        snprintf(nodepath,
-                 sizeof(nodepath), "/dev/block/vold/%d:%d",
-                 new_major, new_minor);
-        if (createDeviceNode(nodepath, new_major, new_minor)) {
-            SLOGE("Error making device node '%s' (%s)", nodepath,
-                                                       strerror(errno));
-        }
-
-        // Todo: Either create sys filename from nodepath, or pass in bogus path so
-        //       vold ignores state changes on this internal device.
-        updateDeviceInfo(nodepath, new_major, new_minor);
-
-        /* Get the device nodes again, because they just changed */
-        n = getDeviceNodes((dev_t *) &deviceNodes, 4);
-        if (!n) {
-            SLOGE("Failed to get device nodes (%s)\n", strerror(errno));
-            return -1;
-        }
-    }
-
-    for (i = 0; i < n; i++) {
-        char devicePath[255];
-
-        sprintf(devicePath, "/dev/block/vold/%d:%d", major(deviceNodes[i]),
-                minor(deviceNodes[i]));
-
-        SLOGI("%s being considered for volume %s\n", devicePath, getLabel());
-
-        errno = 0;
-        setState(Volume::State_Checking);
-
-        if (Fat::check(devicePath)) {
-            if (errno == ENODATA) {
-                SLOGW("%s does not contain a FAT filesystem\n", devicePath);
-                continue;
-            }
-            errno = EIO;
-            /* Badness - abort the mount */
-            SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));
-            setState(Volume::State_Idle);
-            return -1;
-        }
-
-        errno = 0;
-
-        if (Fat::doMount(devicePath, getMountpoint(), false, false, false,
-                AID_MEDIA_RW, AID_MEDIA_RW, 0007, true)) {
-            SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno));
-            continue;
-        }
-
-        extractMetadata(devicePath);
-
-        if (providesAsec && mountAsecExternal() != 0) {
-            SLOGE("Failed to mount secure area (%s)", strerror(errno));
-            umount(getMountpoint());
-            setState(Volume::State_Idle);
-            return -1;
-        }
-
-        char service[64];
-        snprintf(service, 64, "fuse_%s", getLabel());
-        property_set("ctl.start", service);
-
-        setState(Volume::State_Mounted);
-        mCurrentlyMountedKdev = deviceNodes[i];
-        return 0;
-    }
-
-    SLOGE("Volume %s found no suitable devices for mounting :(\n", getLabel());
-    setState(Volume::State_Idle);
-
-    return -1;
-}
-
-int Volume::mountAsecExternal() {
-    char legacy_path[PATH_MAX];
-    char secure_path[PATH_MAX];
-
-    snprintf(legacy_path, PATH_MAX, "%s/android_secure", getMountpoint());
-    snprintf(secure_path, PATH_MAX, "%s/.android_secure", getMountpoint());
-
-    // Recover legacy secure path
-    if (!access(legacy_path, R_OK | X_OK) && access(secure_path, R_OK | X_OK)) {
-        if (rename(legacy_path, secure_path)) {
-            SLOGE("Failed to rename legacy asec dir (%s)", strerror(errno));
-        }
-    }
-
-    if (fs_prepare_dir(secure_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) != 0) {
-        SLOGW("fs_prepare_dir failed: %s", strerror(errno));
-        return -1;
-    }
-
-    if (mount(secure_path, SEC_ASECDIR_EXT, "", MS_BIND, NULL)) {
-        SLOGE("Failed to bind mount points %s -> %s (%s)", secure_path,
-                SEC_ASECDIR_EXT, strerror(errno));
-        return -1;
-    }
-
-    return 0;
-}
-
-int Volume::doUnmount(const char *path, bool force) {
-    int retries = 10;
-
-    if (mDebug) {
-        SLOGD("Unmounting {%s}, force = %d", path, force);
-    }
-
-    while (retries--) {
-        if (!umount(path) || errno == EINVAL || errno == ENOENT) {
-            SLOGI("%s sucessfully unmounted", path);
-            return 0;
-        }
-
-        int action = 0;
-
-        if (force) {
-            if (retries == 1) {
-                action = 2; // SIGKILL
-            } else if (retries == 2) {
-                action = 1; // SIGHUP
-            }
-        }
-
-        SLOGW("Failed to unmount %s (%s, retries %d, action %d)",
-                path, strerror(errno), retries, action);
-
-        Process::killProcessesWithOpenFiles(path, action);
-        usleep(1000*1000);
-    }
-    errno = EBUSY;
-    SLOGE("Giving up on unmount %s (%s)", path, strerror(errno));
-    return -1;
-}
-
-int Volume::unmountVol(bool force, bool revert) {
-    int flags = getFlags();
-    bool providesAsec = (flags & VOL_PROVIDES_ASEC) != 0;
-
-    if (getState() != Volume::State_Mounted) {
-        SLOGE("Volume %s unmount request when not mounted", getLabel());
-        errno = EINVAL;
-        return UNMOUNT_NOT_MOUNTED_ERR;
-    }
-
-    setState(Volume::State_Unmounting);
-    usleep(1000 * 1000); // Give the framework some time to react
-
-    char service[64];
-    snprintf(service, 64, "fuse_%s", getLabel());
-    property_set("ctl.stop", service);
-    /* Give it a chance to stop.  I wish we had a synchronous way to determine this... */
-    sleep(1);
-
-    // TODO: determine failure mode if FUSE times out
-
-    if (providesAsec && doUnmount(Volume::SEC_ASECDIR_EXT, force) != 0) {
-        SLOGE("Failed to unmount secure area on %s (%s)", getMountpoint(), strerror(errno));
-        goto out_mounted;
-    }
-
-    /* Now that the fuse daemon is dead, unmount it */
-    if (doUnmount(getFuseMountpoint(), force) != 0) {
-        SLOGE("Failed to unmount %s (%s)", getFuseMountpoint(), strerror(errno));
-        goto fail_remount_secure;
-    }
-
-    /* Unmount the real sd card */
-    if (doUnmount(getMountpoint(), force) != 0) {
-        SLOGE("Failed to unmount %s (%s)", getMountpoint(), strerror(errno));
-        goto fail_remount_secure;
-    }
-
-    SLOGI("%s unmounted successfully", getMountpoint());
-
-    /* If this is an encrypted volume, and we've been asked to undo
-     * the crypto mapping, then revert the dm-crypt mapping, and revert
-     * the device info to the original values.
-     */
-    if (revert && isDecrypted()) {
-        cryptfs_revert_volume(getLabel());
-        revertDeviceInfo();
-        SLOGI("Encrypted volume %s reverted successfully", getMountpoint());
-    }
-
-    setUuid(NULL);
-    setUserLabel(NULL);
-    setState(Volume::State_Idle);
-    mCurrentlyMountedKdev = -1;
-    return 0;
-
-fail_remount_secure:
-    if (providesAsec && mountAsecExternal() != 0) {
-        SLOGE("Failed to remount secure area (%s)", strerror(errno));
-        goto out_nomedia;
-    }
-
-out_mounted:
-    setState(Volume::State_Mounted);
-    return -1;
-
-out_nomedia:
-    setState(Volume::State_NoMedia);
-    return -1;
-}
-
-int Volume::initializeMbr(const char *deviceNode) {
-    struct disk_info dinfo;
-
-    memset(&dinfo, 0, sizeof(dinfo));
-
-    if (!(dinfo.part_lst = (struct part_info *) malloc(MAX_NUM_PARTS * sizeof(struct part_info)))) {
-        SLOGE("Failed to malloc prt_lst");
-        return -1;
-    }
-
-    memset(dinfo.part_lst, 0, MAX_NUM_PARTS * sizeof(struct part_info));
-    dinfo.device = strdup(deviceNode);
-    dinfo.scheme = PART_SCHEME_MBR;
-    dinfo.sect_size = 512;
-    dinfo.skip_lba = 2048;
-    dinfo.num_lba = 0;
-    dinfo.num_parts = 1;
-
-    struct part_info *pinfo = &dinfo.part_lst[0];
-
-    pinfo->name = strdup("android_sdcard");
-    pinfo->flags |= PART_ACTIVE_FLAG;
-    pinfo->type = PC_PART_TYPE_FAT32;
-    pinfo->len_kb = -1;
-
-    int rc = apply_disk_config(&dinfo, 0);
-
-    if (rc) {
-        SLOGE("Failed to apply disk configuration (%d)", rc);
-        goto out;
-    }
-
- out:
-    free(pinfo->name);
-    free(dinfo.device);
-    free(dinfo.part_lst);
-
-    return rc;
-}
-
-/*
- * Use blkid to extract UUID and label from device, since it handles many
- * obscure edge cases around partition types and formats. Always broadcasts
- * updated metadata values.
- */
-int Volume::extractMetadata(const char* devicePath) {
-    int res = 0;
-
-    std::string cmd;
-    cmd = BLKID_PATH;
-    cmd += " -c /dev/null ";
-    cmd += devicePath;
-
-    FILE* fp = popen(cmd.c_str(), "r");
-    if (!fp) {
-        ALOGE("Failed to run %s: %s", cmd.c_str(), strerror(errno));
-        res = -1;
-        goto done;
-    }
-
-    char line[1024];
-    char value[128];
-    if (fgets(line, sizeof(line), fp) != NULL) {
-        ALOGD("blkid identified as %s", line);
-
-        char* start = strstr(line, "UUID=");
-        if (start != NULL && sscanf(start + 5, "\"%127[^\"]\"", value) == 1) {
-            setUuid(value);
-        } else {
-            setUuid(NULL);
-        }
-
-        start = strstr(line, "LABEL=");
-        if (start != NULL && sscanf(start + 6, "\"%127[^\"]\"", value) == 1) {
-            setUserLabel(value);
-        } else {
-            setUserLabel(NULL);
-        }
-    } else {
-        ALOGW("blkid failed to identify %s", devicePath);
-        res = -1;
-    }
-
-    pclose(fp);
-
-done:
-    if (res == -1) {
-        setUuid(NULL);
-        setUserLabel(NULL);
-    }
-    return res;
-}
diff --git a/Volume.h b/Volume.h
deleted file mode 100644
index 1444ed3..0000000
--- a/Volume.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _VOLUME_H
-#define _VOLUME_H
-
-#include <utils/List.h>
-#include <fs_mgr.h>
-
-class NetlinkEvent;
-class VolumeManager;
-
-class Volume {
-private:
-    int mState;
-    int mFlags;
-
-public:
-    static const int State_Init       = -1;
-    static const int State_NoMedia    = 0;
-    static const int State_Idle       = 1;
-    static const int State_Pending    = 2;
-    static const int State_Checking   = 3;
-    static const int State_Mounted    = 4;
-    static const int State_Unmounting = 5;
-    static const int State_Formatting = 6;
-    static const int State_Shared     = 7;
-    static const int State_SharedMnt  = 8;
-
-    static const char *MEDIA_DIR;
-    static const char *FUSE_DIR;
-    static const char *SEC_ASECDIR_EXT;
-    static const char *SEC_ASECDIR_INT;
-    static const char *ASECDIR;
-    static const char *LOOPDIR;
-    static const char *BLKID_PATH;
-
-protected:
-    char* mLabel;
-    char* mUuid;
-    char* mUserLabel;
-    VolumeManager *mVm;
-    bool mDebug;
-    int mPartIdx;
-    int mOrigPartIdx;
-    bool mRetryMount;
-
-    /*
-     * The major/minor tuple of the currently mounted filesystem.
-     */
-    dev_t mCurrentlyMountedKdev;
-
-public:
-    Volume(VolumeManager *vm, const fstab_rec* rec, int flags);
-    virtual ~Volume();
-
-    int mountVol();
-    int unmountVol(bool force, bool revert);
-    int formatVol(bool wipe);
-
-    const char* getLabel() { return mLabel; }
-    const char* getUuid() { return mUuid; }
-    const char* getUserLabel() { return mUserLabel; }
-    int getState() { return mState; }
-    int getFlags() { return mFlags; };
-
-    /* Mountpoint of the raw volume */
-    virtual const char *getMountpoint() = 0;
-    virtual const char *getFuseMountpoint() = 0;
-
-    virtual int handleBlockEvent(NetlinkEvent *evt);
-    virtual dev_t getDiskDevice();
-    virtual dev_t getShareDevice();
-    virtual void handleVolumeShared();
-    virtual void handleVolumeUnshared();
-
-    void setDebug(bool enable);
-    virtual int getVolInfo(struct volume_info *v) = 0;
-
-protected:
-    void setUuid(const char* uuid);
-    void setUserLabel(const char* userLabel);
-    void setState(int state);
-
-    virtual int getDeviceNodes(dev_t *devs, int max) = 0;
-    virtual int updateDeviceInfo(char *new_path, int new_major, int new_minor) = 0;
-    virtual void revertDeviceInfo(void) = 0;
-    virtual int isDecrypted(void) = 0;
-
-    int createDeviceNode(const char *path, int major, int minor);
-
-private:
-    int initializeMbr(const char *deviceNode);
-    bool isMountpointMounted(const char *path);
-    int mountAsecExternal();
-    int doUnmount(const char *path, bool force);
-    int extractMetadata(const char* devicePath);
-};
-
-typedef android::List<Volume *> VolumeCollection;
-
-#endif
diff --git a/VolumeBase.cpp b/VolumeBase.cpp
new file mode 100644
index 0000000..ca056a4
--- /dev/null
+++ b/VolumeBase.cpp
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Utils.h"
+#include "VolumeBase.h"
+#include "VolumeManager.h"
+#include "ResponseCode.h"
+
+#include <base/stringprintf.h>
+#include <base/logging.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+using android::base::StringPrintf;
+
+#define DEBUG 1
+
+namespace android {
+namespace vold {
+
+VolumeBase::VolumeBase(Type type) :
+        mType(type), mMountFlags(0), mMountUserId(-1), mCreated(false), mState(
+                State::kUnmounted), mSilent(false) {
+}
+
+VolumeBase::~VolumeBase() {
+    CHECK(!mCreated);
+}
+
+void VolumeBase::setState(State state) {
+    mState = state;
+    notifyEvent(ResponseCode::VolumeStateChanged, StringPrintf("%d", mState));
+}
+
+status_t VolumeBase::setDiskId(const std::string& diskId) {
+    if (mCreated) {
+        LOG(WARNING) << getId() << " diskId change requires destroyed";
+        return -EBUSY;
+    }
+
+    mDiskId = diskId;
+    return OK;
+}
+
+status_t VolumeBase::setMountFlags(int mountFlags) {
+    if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
+        LOG(WARNING) << getId() << " flags change requires state unmounted or unmountable";
+        return -EBUSY;
+    }
+
+    mMountFlags = mountFlags;
+    return OK;
+}
+
+status_t VolumeBase::setMountUserId(userid_t mountUserId) {
+    if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
+        LOG(WARNING) << getId() << " user change requires state unmounted or unmountable";
+        return -EBUSY;
+    }
+
+    mMountUserId = mountUserId;
+    return OK;
+}
+
+status_t VolumeBase::setSilent(bool silent) {
+    if (mCreated) {
+        LOG(WARNING) << getId() << " silence change requires destroyed";
+        return -EBUSY;
+    }
+
+    mSilent = silent;
+    return OK;
+}
+
+status_t VolumeBase::setId(const std::string& id) {
+    if (mCreated) {
+        LOG(WARNING) << getId() << " id change requires not created";
+        return -EBUSY;
+    }
+
+    mId = id;
+    return OK;
+}
+
+status_t VolumeBase::setPath(const std::string& path) {
+    if (mState != State::kChecking) {
+        LOG(WARNING) << getId() << " path change requires state checking";
+        return -EBUSY;
+    }
+
+    mPath = path;
+    notifyEvent(ResponseCode::VolumePathChanged, mPath);
+    return OK;
+}
+
+status_t VolumeBase::setInternalPath(const std::string& internalPath) {
+    if (mState != State::kChecking) {
+        LOG(WARNING) << getId() << " internal path change requires state checking";
+        return -EBUSY;
+    }
+
+    mInternalPath = internalPath;
+    notifyEvent(ResponseCode::VolumeInternalPathChanged, mInternalPath);
+    return OK;
+}
+
+void VolumeBase::notifyEvent(int event) {
+    if (mSilent) return;
+    VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
+            getId().c_str(), false);
+}
+
+void VolumeBase::notifyEvent(int event, const std::string& value) {
+    if (mSilent) return;
+    VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
+            StringPrintf("%s %s", getId().c_str(), value.c_str()).c_str(), false);
+}
+
+void VolumeBase::addVolume(const std::shared_ptr<VolumeBase>& volume) {
+    mVolumes.push_back(volume);
+}
+
+void VolumeBase::removeVolume(const std::shared_ptr<VolumeBase>& volume) {
+    mVolumes.remove(volume);
+}
+
+std::shared_ptr<VolumeBase> VolumeBase::findVolume(const std::string& id) {
+    for (auto vol : mVolumes) {
+        if (vol->getId() == id) {
+            return vol;
+        }
+    }
+    return nullptr;
+}
+
+status_t VolumeBase::create() {
+    CHECK(!mCreated);
+
+    mCreated = true;
+    status_t res = doCreate();
+    notifyEvent(ResponseCode::VolumeCreated, StringPrintf("%d %s", mType, mDiskId.c_str()));
+    setState(State::kUnmounted);
+    return res;
+}
+
+status_t VolumeBase::doCreate() {
+    return OK;
+}
+
+status_t VolumeBase::destroy() {
+    CHECK(mCreated);
+
+    if (mState == State::kMounted) {
+        unmount();
+        setState(State::kBadRemoval);
+    } else {
+        setState(State::kRemoved);
+    }
+
+    notifyEvent(ResponseCode::VolumeDestroyed);
+    status_t res = doDestroy();
+    mCreated = false;
+    return res;
+}
+
+status_t VolumeBase::doDestroy() {
+    return OK;
+}
+
+status_t VolumeBase::mount() {
+    if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
+        LOG(WARNING) << getId() << " mount requires state unmounted or unmountable";
+        return -EBUSY;
+    }
+
+    setState(State::kChecking);
+    status_t res = doMount();
+    if (res == OK) {
+        setState(State::kMounted);
+    } else {
+        setState(State::kUnmountable);
+    }
+
+    return res;
+}
+
+status_t VolumeBase::unmount() {
+    if (mState != State::kMounted) {
+        LOG(WARNING) << getId() << " unmount requires state mounted";
+        return -EBUSY;
+    }
+
+    setState(State::kEjecting);
+
+    for (auto vol : mVolumes) {
+        if (vol->destroy()) {
+            LOG(WARNING) << getId() << " failed to destroy " << vol->getId()
+                    << " stacked above";
+        }
+    }
+    mVolumes.clear();
+
+    status_t res = doUnmount();
+    setState(State::kUnmounted);
+    return res;
+}
+
+status_t VolumeBase::format() {
+    if (mState == State::kMounted) {
+        unmount();
+    }
+
+    if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
+        LOG(WARNING) << getId() << " format requires state unmounted or unmountable";
+        return -EBUSY;
+    }
+
+    setState(State::kFormatting);
+    status_t res = doFormat();
+    setState(State::kUnmounted);
+    return res;
+}
+
+status_t VolumeBase::doFormat() {
+    return -ENOTSUP;
+}
+
+}  // namespace vold
+}  // namespace android
diff --git a/VolumeBase.h b/VolumeBase.h
new file mode 100644
index 0000000..a9975f8
--- /dev/null
+++ b/VolumeBase.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VOLD_VOLUME_BASE_H
+#define ANDROID_VOLD_VOLUME_BASE_H
+
+#include "Utils.h"
+
+#include <cutils/multiuser.h>
+#include <utils/Errors.h>
+
+#include <sys/types.h>
+#include <list>
+#include <string>
+
+namespace android {
+namespace vold {
+
+/*
+ * Representation of a mounted volume ready for presentation.
+ *
+ * Various subclasses handle the different mounting prerequisites, such as
+ * encryption details, etc.  Volumes can also be "stacked" above other
+ * volumes to help communicate dependencies.  For example, an ASEC volume
+ * can be stacked on a vfat volume.
+ *
+ * Mounted volumes can be asked to manage bind mounts to present themselves
+ * to specific users on the device.
+ *
+ * When an unmount is requested, the volume recursively unmounts any stacked
+ * volumes and removes any bind mounts before finally unmounting itself.
+ */
+class VolumeBase {
+public:
+    virtual ~VolumeBase();
+
+    enum class Type {
+        kPublic = 0,
+        kPrivate,
+        kEmulated,
+        kAsec,
+        kObb,
+    };
+
+    enum MountFlags {
+        /* Flag that volume is primary external storage */
+        kPrimary = 1 << 0,
+        /* Flag that volume is visible to normal apps */
+        kVisible = 1 << 1,
+    };
+
+    enum class State {
+        kUnmounted = 0,
+        kChecking,
+        kMounted,
+        kMountedReadOnly,
+        kFormatting,
+        kEjecting,
+        kUnmountable,
+        kRemoved,
+        kBadRemoval,
+    };
+
+    const std::string& getId() { return mId; }
+    const std::string& getDiskId() { return mDiskId; }
+    Type getType() { return mType; }
+    int getMountFlags() { return mMountFlags; }
+    userid_t getMountUserId() { return mMountUserId; }
+    State getState() { return mState; }
+    const std::string& getPath() { return mPath; }
+    const std::string& getInternalPath() { return mInternalPath; }
+
+    status_t setDiskId(const std::string& diskId);
+    status_t setMountFlags(int mountFlags);
+    status_t setMountUserId(userid_t mountUserId);
+    status_t setSilent(bool silent);
+
+    void addVolume(const std::shared_ptr<VolumeBase>& volume);
+    void removeVolume(const std::shared_ptr<VolumeBase>& volume);
+
+    std::shared_ptr<VolumeBase> findVolume(const std::string& id);
+
+    status_t create();
+    status_t destroy();
+    status_t mount();
+    status_t unmount();
+    status_t format();
+
+protected:
+    explicit VolumeBase(Type type);
+
+    virtual status_t doCreate();
+    virtual status_t doDestroy();
+    virtual status_t doMount() = 0;
+    virtual status_t doUnmount() = 0;
+    virtual status_t doFormat();
+
+    status_t setId(const std::string& id);
+    status_t setPath(const std::string& path);
+    status_t setInternalPath(const std::string& internalPath);
+
+    void notifyEvent(int msg);
+    void notifyEvent(int msg, const std::string& value);
+
+private:
+    /* ID that uniquely references volume while alive */
+    std::string mId;
+    /* ID that uniquely references parent disk while alive */
+    std::string mDiskId;
+    /* Volume type */
+    Type mType;
+    /* Flags used when mounting this volume */
+    int mMountFlags;
+    /* User that owns this volume, otherwise -1 */
+    userid_t mMountUserId;
+    /* Flag indicating object is created */
+    bool mCreated;
+    /* Current state of volume */
+    State mState;
+    /* Path to mounted volume */
+    std::string mPath;
+    /* Path to internal backing storage */
+    std::string mInternalPath;
+    /* Flag indicating that volume should emit no events */
+    bool mSilent;
+
+    /* Volumes stacked on top of this volume */
+    std::list<std::shared_ptr<VolumeBase>> mVolumes;
+
+    void setState(State state);
+
+    DISALLOW_COPY_AND_ASSIGN(VolumeBase);
+};
+
+}  // namespace vold
+}  // namespace android
+
+#endif
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index da4deb6..5c4f9af 100755
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -34,6 +34,8 @@
 
 #include <openssl/md5.h>
 
+#include <base/logging.h>
+#include <base/stringprintf.h>
 #include <cutils/fs.h>
 #include <cutils/log.h>
 
@@ -43,12 +45,14 @@
 
 #include <private/android_filesystem_config.h>
 
+#include "EmulatedVolume.h"
 #include "VolumeManager.h"
-#include "DirectVolume.h"
+#include "NetlinkManager.h"
 #include "ResponseCode.h"
 #include "Loop.h"
 #include "Ext4.h"
 #include "Fat.h"
+#include "Utils.h"
 #include "Devmapper.h"
 #include "Process.h"
 #include "Asec.h"
@@ -60,9 +64,35 @@
 #define ROUND_UP_POWER_OF_2(number, po2) (((!!(number & ((1U << po2) - 1))) << po2)\
                                          + (number & (~((1U << po2) - 1))))
 
+using android::base::StringPrintf;
+
+/*
+ * Path to external storage where *only* root can access ASEC image files
+ */
+const char *VolumeManager::SEC_ASECDIR_EXT   = "/mnt/secure/asec";
+
+/*
+ * Path to internal storage where *only* root can access ASEC image files
+ */
+const char *VolumeManager::SEC_ASECDIR_INT   = "/data/app-asec";
+
+/*
+ * Path to where secure containers are mounted
+ */
+const char *VolumeManager::ASECDIR           = "/mnt/asec";
+
+/*
+ * Path to where OBBs are mounted
+ */
+const char *VolumeManager::LOOPDIR           = "/mnt/obb";
+
+static const char* kUserMountPath = "/mnt/user";
+
+static const unsigned int kMajorBlockMmc = 179;
+
 /* writes superblock at end of file or device given by name */
 static int writeSuperBlock(const char* name, struct asec_superblock *sb, unsigned int numImgSectors) {
-    int sbfd = open(name, O_RDWR);
+    int sbfd = open(name, O_RDWR | O_CLOEXEC);
     if (sbfd < 0) {
         SLOGE("Failed to open %s for superblock write (%s)", name, strerror(errno));
         return -1;
@@ -171,18 +201,15 @@
 
 VolumeManager::VolumeManager() {
     mDebug = false;
-    mVolumes = new VolumeCollection();
     mActiveContainers = new AsecIdCollection();
     mBroadcaster = NULL;
     mUmsSharingCount = 0;
     mSavedDirtyRatio = -1;
     // set dirty ratio to 0 when UMS is active
     mUmsDirtyRatio = 0;
-    mVolManagerDisabled = 0;
 }
 
 VolumeManager::~VolumeManager() {
-    delete mVolumes;
     delete mActiveContainers;
 }
 
@@ -218,96 +245,234 @@
     return buffer;
 }
 
-void VolumeManager::setDebug(bool enable) {
+int VolumeManager::setDebug(bool enable) {
     mDebug = enable;
-    VolumeCollection::iterator it;
-    for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {
-        (*it)->setDebug(enable);
-    }
+    return 0;
 }
 
 int VolumeManager::start() {
+    // Always start from a clean slate by unmounting everything in
+    // directories that we own, in case we crashed.
+    unmountAll();
+
+    // Assume that we always have an emulated volume on internal
+    // storage; the framework will decide if it should be mounted.
+    CHECK(mInternalEmulated == nullptr);
+    mInternalEmulated = std::shared_ptr<android::vold::VolumeBase>(
+            new android::vold::EmulatedVolume("/data/media"));
+    mInternalEmulated->create();
+
     return 0;
 }
 
 int VolumeManager::stop() {
-    return 0;
-}
-
-int VolumeManager::addVolume(Volume *v) {
-    mVolumes->push_back(v);
+    CHECK(mInternalEmulated != nullptr);
+    mInternalEmulated->destroy();
+    mInternalEmulated = nullptr;
     return 0;
 }
 
 void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
-#ifdef NETLINK_DEBUG
-    const char *devpath = evt->findParam("DEVPATH");
-#endif
+    std::lock_guard<std::mutex> lock(mLock);
 
-    /* Lookup a volume to handle this device */
-    VolumeCollection::iterator it;
-    bool hit = false;
-    for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {
-        if (!(*it)->handleBlockEvent(evt)) {
-#ifdef NETLINK_DEBUG
-            SLOGD("Device '%s' event handled by volume %s\n", devpath, (*it)->getLabel());
-#endif
-            hit = true;
-            break;
-        }
+    if (mDebug) {
+        LOG(VERBOSE) << "----------------";
+        LOG(VERBOSE) << "handleBlockEvent with action " << (int) evt->getAction();
+        evt->dump();
     }
 
-    if (!hit) {
-#ifdef NETLINK_DEBUG
-        SLOGW("No volumes handled block event for '%s'", devpath);
-#endif
+    std::string eventPath(evt->findParam("DEVPATH"));
+    std::string devType(evt->findParam("DEVTYPE"));
+
+    if (devType != "disk") return;
+
+    int major = atoi(evt->findParam("MAJOR"));
+    int minor = atoi(evt->findParam("MINOR"));
+    dev_t device = makedev(major, minor);
+
+    switch (evt->getAction()) {
+    case NetlinkEvent::Action::kAdd: {
+        for (auto source : mDiskSources) {
+            if (source->matches(eventPath)) {
+                // For now, assume that MMC devices are SD, and that
+                // everything else is USB
+                int flags = source->getFlags();
+                if (major == kMajorBlockMmc) {
+                    flags |= android::vold::Disk::Flags::kSd;
+                } else {
+                    flags |= android::vold::Disk::Flags::kUsb;
+                }
+
+                auto disk = new android::vold::Disk(eventPath, device,
+                        source->getNickname(), flags);
+                disk->create();
+                mDisks.push_back(std::shared_ptr<android::vold::Disk>(disk));
+                break;
+            }
+        }
+        break;
+    }
+    case NetlinkEvent::Action::kChange: {
+        LOG(DEBUG) << "Disk at " << major << ":" << minor << " changed";
+        for (auto disk : mDisks) {
+            if (disk->getDevice() == device) {
+                disk->readMetadata();
+                disk->readPartitions();
+            }
+        }
+        break;
+    }
+    case NetlinkEvent::Action::kRemove: {
+        auto i = mDisks.begin();
+        while (i != mDisks.end()) {
+            if ((*i)->getDevice() == device) {
+                (*i)->destroy();
+                i = mDisks.erase(i);
+            } else {
+                ++i;
+            }
+        }
+        break;
+    }
+    default: {
+        LOG(WARNING) << "Unexpected block event action " << (int) evt->getAction();
+        break;
+    }
     }
 }
 
-int VolumeManager::listVolumes(SocketClient *cli, bool broadcast) {
-    VolumeCollection::iterator i;
-    char msg[256];
+void VolumeManager::addDiskSource(const std::shared_ptr<DiskSource>& diskSource) {
+    mDiskSources.push_back(diskSource);
+}
 
-    for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        char *buffer;
-        asprintf(&buffer, "%s %s %d",
-                 (*i)->getLabel(), (*i)->getFuseMountpoint(),
-                 (*i)->getState());
-        cli->sendMsg(ResponseCode::VolumeListResult, buffer, false);
-        free(buffer);
-        if (broadcast) {
-            if((*i)->getUuid()) {
-                snprintf(msg, sizeof(msg), "%s %s \"%s\"", (*i)->getLabel(),
-                    (*i)->getFuseMountpoint(), (*i)->getUuid());
-                mBroadcaster->sendBroadcast(ResponseCode::VolumeUuidChange,
-                    msg, false);
-            }
-            if((*i)->getUserLabel()) {
-                snprintf(msg, sizeof(msg), "%s %s \"%s\"", (*i)->getLabel(),
-                    (*i)->getFuseMountpoint(), (*i)->getUserLabel());
-                mBroadcaster->sendBroadcast(ResponseCode::VolumeUserLabelChange,
-                    msg, false);
-            }
+std::shared_ptr<android::vold::Disk> VolumeManager::findDisk(const std::string& id) {
+    for (auto disk : mDisks) {
+        if (disk->getId() == id) {
+            return disk;
         }
     }
-    cli->sendMsg(ResponseCode::CommandOkay, "Volumes listed.", false);
+    return nullptr;
+}
+
+std::shared_ptr<android::vold::VolumeBase> VolumeManager::findVolume(const std::string& id) {
+    if (mInternalEmulated->getId() == id) {
+        return mInternalEmulated;
+    }
+    for (auto disk : mDisks) {
+        auto vol = disk->findVolume(id);
+        if (vol != nullptr) {
+            return vol;
+        }
+    }
+    return nullptr;
+}
+
+int VolumeManager::linkPrimary(userid_t userId) {
+    std::string source(mPrimary->getPath());
+    if (mPrimary->getType() == android::vold::VolumeBase::Type::kEmulated) {
+        source = StringPrintf("%s/%d", source.c_str(), userId);
+    }
+
+    std::string target(StringPrintf("/mnt/user/%d/primary", userId));
+    if (TEMP_FAILURE_RETRY(unlink(target.c_str()))) {
+        if (errno != ENOENT) {
+            SLOGW("Failed to unlink %s: %s", target.c_str(), strerror(errno));
+        }
+    }
+    if (TEMP_FAILURE_RETRY(symlink(source.c_str(), target.c_str()))) {
+        SLOGW("Failed to link %s to %s: %s", source.c_str(), target.c_str(),
+                strerror(errno));
+        return -errno;
+    }
     return 0;
 }
 
-int VolumeManager::formatVolume(const char *label, bool wipe) {
-    Volume *v = lookupVolume(label);
+int VolumeManager::startUser(userid_t userId) {
+    // Note that sometimes the system will spin up processes from Zygote
+    // before actually starting the user, so we're okay if Zygote
+    // already created this directory.
+    std::string path(StringPrintf("%s/%d", kUserMountPath, userId));
+    fs_prepare_dir(path.c_str(), 0755, AID_ROOT, AID_ROOT);
 
-    if (!v) {
-        errno = ENOENT;
-        return -1;
+    mUsers.push_back(userId);
+    if (mPrimary) {
+        linkPrimary(userId);
+    }
+    return 0;
+}
+
+int VolumeManager::cleanupUser(userid_t userId) {
+    mUsers.remove(userId);
+    return 0;
+}
+
+int VolumeManager::setPrimary(const std::shared_ptr<android::vold::VolumeBase>& vol) {
+    mPrimary = vol;
+    for (userid_t userId : mUsers) {
+        linkPrimary(userId);
+    }
+    return 0;
+}
+
+int VolumeManager::reset() {
+    // Tear down all existing disks/volumes and start from a blank slate so
+    // newly connected framework hears all events.
+    mInternalEmulated->destroy();
+    mInternalEmulated->create();
+    for (auto disk : mDisks) {
+        disk->destroy();
+        disk->create();
+    }
+    mUsers.clear();
+    return 0;
+}
+
+int VolumeManager::shutdown() {
+    mInternalEmulated->destroy();
+    for (auto disk : mDisks) {
+        disk->destroy();
+    }
+    mDisks.clear();
+    return 0;
+}
+
+int VolumeManager::unmountAll() {
+    std::lock_guard<std::mutex> lock(mLock);
+
+    // First, try gracefully unmounting all known devices
+    if (mInternalEmulated != nullptr) {
+        mInternalEmulated->unmount();
+    }
+    for (auto disk : mDisks) {
+        disk->unmountAll();
     }
 
-    if (mVolManagerDisabled) {
-        errno = EBUSY;
-        return -1;
+    // Worst case we might have some stale mounts lurking around, so
+    // force unmount those just to be safe.
+    FILE* fp = setmntent("/proc/mounts", "r");
+    if (fp == NULL) {
+        SLOGE("Error opening /proc/mounts: %s", strerror(errno));
+        return -errno;
     }
 
-    return v->formatVol(wipe);
+    // Some volumes can be stacked on each other, so force unmount in
+    // reverse order to give us the best chance of success.
+    std::list<std::string> toUnmount;
+    mntent* mentry;
+    while ((mentry = getmntent(fp)) != NULL) {
+        if (strncmp(mentry->mnt_dir, "/mnt/", 5) == 0
+                || strncmp(mentry->mnt_dir, "/storage/", 9) == 0) {
+            toUnmount.push_front(std::string(mentry->mnt_dir));
+        }
+    }
+    endmntent(fp);
+
+    for (auto path : toUnmount) {
+        SLOGW("Tearing down stale mount %s", path.c_str());
+        android::vold::ForceUnmount(path);
+    }
+
+    return 0;
 }
 
 int VolumeManager::getObbMountPath(const char *sourceFile, char *mountPath, int mountPathLen) {
@@ -318,7 +483,7 @@
     }
 
     memset(mountPath, 0, mountPathLen);
-    int written = snprintf(mountPath, mountPathLen, "%s/%s", Volume::LOOPDIR, idHash);
+    int written = snprintf(mountPath, mountPathLen, "%s/%s", VolumeManager::LOOPDIR, idHash);
     if ((written < 0) || (written >= mountPathLen)) {
         errno = EINVAL;
         return -1;
@@ -352,7 +517,7 @@
         return -1;
     }
 
-    int written = snprintf(buffer, maxlen, "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(buffer, maxlen, "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (written >= maxlen)) {
         SLOGE("getAsecMountPath failed for %s: couldn't construct path in buffer", id);
         errno = EINVAL;
@@ -424,12 +589,6 @@
         return -1;
     }
 
-    if (lookupVolume(id)) {
-        SLOGE("ASEC id '%s' currently exists", id);
-        errno = EADDRINUSE;
-        return -1;
-    }
-
     char asecFileName[255];
 
     if (!findAsec(id, asecFileName, sizeof(asecFileName))) {
@@ -439,7 +598,7 @@
         return -1;
     }
 
-    const char *asecDir = isExternal ? Volume::SEC_ASECDIR_EXT : Volume::SEC_ASECDIR_INT;
+    const char *asecDir = isExternal ? VolumeManager::SEC_ASECDIR_EXT : VolumeManager::SEC_ASECDIR_INT;
 
     int written = snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", asecDir, id);
     if ((written < 0) || (size_t(written) >= sizeof(asecFileName))) {
@@ -515,7 +674,7 @@
         int formatStatus;
         char mountPoint[255];
 
-        int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+        int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
         if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
             SLOGE("ASEC fs format failed: couldn't construct mountPoint");
             if (cleanupDm) {
@@ -573,7 +732,7 @@
         }
 
         if (usingExt4) {
-            int dirfd = open(mountPoint, O_DIRECTORY);
+            int dirfd = open(mountPoint, O_DIRECTORY | O_CLOEXEC);
             if (dirfd >= 0) {
                 if (fchown(dirfd, ownerUid, AID_SYSTEM)
                         || fchmod(dirfd, S_IRUSR | S_IWUSR | S_IXUSR | S_ISGID | S_IRGRP | S_IXGRP)) {
@@ -606,7 +765,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
        SLOGE("ASEC resize failed for %s: couldn't construct mountpoint", id);
        return -1;
@@ -622,7 +781,7 @@
     int fd;
     unsigned int oldNumSec = 0;
 
-    if ((fd = open(asecFileName, O_RDONLY)) < 0) {
+    if ((fd = open(asecFileName, O_RDONLY | O_CLOEXEC)) < 0) {
         SLOGE("Failed to open ASEC file (%s)", strerror(errno));
         return -1;
     }
@@ -767,7 +926,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("ASEC finalize failed: couldn't construct mountPoint");
         return -1;
@@ -830,7 +989,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("Unable remount to fix permissions for %s: couldn't construct mountpoint", id);
         return -1;
@@ -868,7 +1027,7 @@
              */
             const bool privateFile = !strcmp(ftsent->fts_name, filename);
 
-            int fd = open(ftsent->fts_accpath, O_NOFOLLOW);
+            int fd = open(ftsent->fts_accpath, O_NOFOLLOW | O_CLOEXEC);
             if (fd < 0) {
                 SLOGE("Couldn't open file %s: %s", ftsent->fts_accpath, strerror(errno));
                 result = -1;
@@ -893,7 +1052,7 @@
         fts_close(fts);
 
         // Finally make the directory readable by everyone.
-        int dirfd = open(mountPoint, O_DIRECTORY);
+        int dirfd = open(mountPoint, O_DIRECTORY | O_CLOEXEC);
         if (dirfd < 0 || fchmod(dirfd, 0755)) {
             SLOGE("Couldn't change owner of existing directory %s: %s", mountPoint, strerror(errno));
             result |= -1;
@@ -945,7 +1104,7 @@
 
     asprintf(&asecFilename2, "%s/%s.asec", dir, id2);
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id1);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id1);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("Rename failed: couldn't construct mountpoint");
         goto out_err;
@@ -957,7 +1116,7 @@
         goto out_err;
     }
 
-    written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id2);
+    written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id2);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("Rename failed: couldn't construct mountpoint2");
         goto out_err;
@@ -1005,7 +1164,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("ASEC unmount failed for %s: couldn't construct mountpoint", id);
         return -1;
@@ -1029,7 +1188,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::LOOPDIR, idHash);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::LOOPDIR, idHash);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("OBB unmount failed for %s: couldn't construct mountpoint", fileName);
         return -1;
@@ -1060,16 +1219,16 @@
         SLOGW("%s unmount attempt %d failed (%s)",
               id, i, strerror(errno));
 
-        int action = 0; // default is to just complain
+        int signal = 0; // default is to just complain
 
         if (force) {
             if (i > (UNMOUNT_RETRIES - 2))
-                action = 2; // SIGKILL
+                signal = SIGKILL;
             else if (i > (UNMOUNT_RETRIES - 3))
-                action = 1; // SIGHUP
+                signal = SIGTERM;
         }
 
-        Process::killProcessesWithOpenFiles(mountPoint, action);
+        Process::killProcessesWithOpenFiles(mountPoint, signal);
         usleep(UNMOUNT_SLEEP_BETWEEN_RETRY_MS);
     }
 
@@ -1141,7 +1300,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("ASEC destroy failed for %s: couldn't construct mountpoint", id);
         return -1;
@@ -1201,7 +1360,7 @@
 }
 
 bool VolumeManager::isAsecInDirectory(const char *dir, const char *asecName) const {
-    int dirfd = open(dir, O_DIRECTORY);
+    int dirfd = open(dir, O_DIRECTORY | O_CLOEXEC);
     if (dirfd < 0) {
         SLOGE("Couldn't open internal ASEC dir (%s)", strerror(errno));
         return false;
@@ -1232,10 +1391,10 @@
     }
 
     const char *dir;
-    if (isAsecInDirectory(Volume::SEC_ASECDIR_INT, asecName)) {
-        dir = Volume::SEC_ASECDIR_INT;
-    } else if (isAsecInDirectory(Volume::SEC_ASECDIR_EXT, asecName)) {
-        dir = Volume::SEC_ASECDIR_EXT;
+    if (isAsecInDirectory(VolumeManager::SEC_ASECDIR_INT, asecName)) {
+        dir = VolumeManager::SEC_ASECDIR_INT;
+    } else if (isAsecInDirectory(VolumeManager::SEC_ASECDIR_EXT, asecName)) {
+        dir = VolumeManager::SEC_ASECDIR_EXT;
     } else {
         free(asecName);
         return -1;
@@ -1273,7 +1432,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("ASEC mount failed for %s: couldn't construct mountpoint", id);
         return -1;
@@ -1360,19 +1519,6 @@
     return 0;
 }
 
-Volume* VolumeManager::getVolumeForFile(const char *fileName) {
-    VolumeCollection::iterator i;
-
-    for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        const char* mountPoint = (*i)->getFuseMountpoint();
-        if (!strncmp(fileName, mountPoint, strlen(mountPoint))) {
-            return *i;
-        }
-    }
-
-    return NULL;
-}
-
 /**
  * Mounts an image file <code>img</code>.
  */
@@ -1385,7 +1531,7 @@
         return -1;
     }
 
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::LOOPDIR, idHash);
+    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::LOOPDIR, idHash);
     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
         SLOGE("OBB mount failed for %s: couldn't construct mountpoint", img);
         return -1;
@@ -1406,7 +1552,7 @@
     int fd;
     unsigned long nr_sec = 0;
 
-    if ((fd = open(loopDevice, O_RDWR)) < 0) {
+    if ((fd = open(loopDevice, O_RDWR | O_CLOEXEC)) < 0) {
         SLOGE("Failed to open loopdevice (%s)", strerror(errno));
         Loop::destroyByDevice(loopDevice);
         return -1;
@@ -1460,17 +1606,6 @@
     return 0;
 }
 
-int VolumeManager::mountVolume(const char *label) {
-    Volume *v = lookupVolume(label);
-
-    if (!v) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    return v->mountVol();
-}
-
 int VolumeManager::listMountedObbs(SocketClient* cli) {
     FILE *fp = setmntent("/proc/mounts", "r");
     if (fp == NULL) {
@@ -1479,16 +1614,16 @@
     }
 
     // Create a string to compare against that has a trailing slash
-    int loopDirLen = strlen(Volume::LOOPDIR);
+    int loopDirLen = strlen(VolumeManager::LOOPDIR);
     char loopDir[loopDirLen + 2];
-    strcpy(loopDir, Volume::LOOPDIR);
+    strcpy(loopDir, VolumeManager::LOOPDIR);
     loopDir[loopDirLen++] = '/';
     loopDir[loopDirLen] = '\0';
 
     mntent* mentry;
     while ((mentry = getmntent(fp)) != NULL) {
         if (!strncmp(mentry->mnt_dir, loopDir, loopDirLen)) {
-            int fd = open(mentry->mnt_fsname, O_RDONLY);
+            int fd = open(mentry->mnt_fsname, O_RDONLY | O_CLOEXEC);
             if (fd >= 0) {
                 struct loop_info64 li;
                 if (ioctl(fd, LOOP_GET_STATUS64, &li) >= 0) {
@@ -1503,299 +1638,9 @@
     return 0;
 }
 
-int VolumeManager::shareEnabled(const char *label, const char *method, bool *enabled) {
-    Volume *v = lookupVolume(label);
-
-    if (!v) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    if (strcmp(method, "ums")) {
-        errno = ENOSYS;
-        return -1;
-    }
-
-    if (v->getState() != Volume::State_Shared) {
-        *enabled = false;
-    } else {
-        *enabled = true;
-    }
-    return 0;
-}
-
-int VolumeManager::shareVolume(const char *label, const char *method) {
-    Volume *v = lookupVolume(label);
-
-    if (!v) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    /*
-     * Eventually, we'll want to support additional share back-ends,
-     * some of which may work while the media is mounted. For now,
-     * we just support UMS
-     */
-    if (strcmp(method, "ums")) {
-        errno = ENOSYS;
-        return -1;
-    }
-
-    if (v->getState() == Volume::State_NoMedia) {
-        errno = ENODEV;
-        return -1;
-    }
-
-    if (v->getState() != Volume::State_Idle) {
-        // You need to unmount manually befoe sharing
-        errno = EBUSY;
-        return -1;
-    }
-
-    if (mVolManagerDisabled) {
-        errno = EBUSY;
-        return -1;
-    }
-
-    dev_t d = v->getShareDevice();
-    if ((MAJOR(d) == 0) && (MINOR(d) == 0)) {
-        // This volume does not support raw disk access
-        errno = EINVAL;
-        return -1;
-    }
-
-    int fd;
-    char nodepath[255];
-    int written = snprintf(nodepath,
-             sizeof(nodepath), "/dev/block/vold/%d:%d",
-             major(d), minor(d));
-
-    if ((written < 0) || (size_t(written) >= sizeof(nodepath))) {
-        SLOGE("shareVolume failed: couldn't construct nodepath");
-        return -1;
-    }
-
-    if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
-        SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
-        return -1;
-    }
-
-    if (write(fd, nodepath, strlen(nodepath)) < 0) {
-        SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));
-        close(fd);
-        return -1;
-    }
-
-    close(fd);
-    v->handleVolumeShared();
-    if (mUmsSharingCount++ == 0) {
-        FILE* fp;
-        mSavedDirtyRatio = -1; // in case we fail
-        if ((fp = fopen("/proc/sys/vm/dirty_ratio", "r+"))) {
-            char line[16];
-            if (fgets(line, sizeof(line), fp) && sscanf(line, "%d", &mSavedDirtyRatio)) {
-                fprintf(fp, "%d\n", mUmsDirtyRatio);
-            } else {
-                SLOGE("Failed to read dirty_ratio (%s)", strerror(errno));
-            }
-            fclose(fp);
-        } else {
-            SLOGE("Failed to open /proc/sys/vm/dirty_ratio (%s)", strerror(errno));
-        }
-    }
-    return 0;
-}
-
-int VolumeManager::unshareVolume(const char *label, const char *method) {
-    Volume *v = lookupVolume(label);
-
-    if (!v) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    if (strcmp(method, "ums")) {
-        errno = ENOSYS;
-        return -1;
-    }
-
-    if (v->getState() != Volume::State_Shared) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    int fd;
-    if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
-        SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
-        return -1;
-    }
-
-    char ch = 0;
-    if (write(fd, &ch, 1) < 0) {
-        SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));
-        close(fd);
-        return -1;
-    }
-
-    close(fd);
-    v->handleVolumeUnshared();
-    if (--mUmsSharingCount == 0 && mSavedDirtyRatio != -1) {
-        FILE* fp;
-        if ((fp = fopen("/proc/sys/vm/dirty_ratio", "r+"))) {
-            fprintf(fp, "%d\n", mSavedDirtyRatio);
-            fclose(fp);
-        } else {
-            SLOGE("Failed to open /proc/sys/vm/dirty_ratio (%s)", strerror(errno));
-        }
-        mSavedDirtyRatio = -1;
-    }
-    return 0;
-}
-
-extern "C" int vold_disableVol(const char *label) {
+extern "C" int vold_unmountAll(void) {
     VolumeManager *vm = VolumeManager::Instance();
-    vm->disableVolumeManager();
-    vm->unshareVolume(label, "ums");
-    return vm->unmountVolume(label, true, false);
-}
-
-extern "C" int vold_getNumDirectVolumes(void) {
-    VolumeManager *vm = VolumeManager::Instance();
-    return vm->getNumDirectVolumes();
-}
-
-int VolumeManager::getNumDirectVolumes(void) {
-    VolumeCollection::iterator i;
-    int n=0;
-
-    for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        if ((*i)->getShareDevice() != (dev_t)0) {
-            n++;
-        }
-    }
-    return n;
-}
-
-extern "C" int vold_getDirectVolumeList(struct volume_info *vol_list) {
-    VolumeManager *vm = VolumeManager::Instance();
-    return vm->getDirectVolumeList(vol_list);
-}
-
-int VolumeManager::getDirectVolumeList(struct volume_info *vol_list) {
-    VolumeCollection::iterator i;
-    int n=0;
-    dev_t d;
-
-    for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        if ((d=(*i)->getShareDevice()) != (dev_t)0) {
-            (*i)->getVolInfo(&vol_list[n]);
-            snprintf(vol_list[n].blk_dev, sizeof(vol_list[n].blk_dev),
-                     "/dev/block/vold/%d:%d", major(d), minor(d));
-            n++;
-        }
-    }
-
-    return 0;
-}
-
-int VolumeManager::unmountVolume(const char *label, bool force, bool revert) {
-    Volume *v = lookupVolume(label);
-
-    if (!v) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    if (v->getState() == Volume::State_NoMedia) {
-        errno = ENODEV;
-        return -1;
-    }
-
-    if (v->getState() != Volume::State_Mounted) {
-        SLOGW("Attempt to unmount volume which isn't mounted (%d)\n",
-             v->getState());
-        errno = EBUSY;
-        return UNMOUNT_NOT_MOUNTED_ERR;
-    }
-
-    cleanupAsec(v, force);
-
-    return v->unmountVol(force, revert);
-}
-
-extern "C" int vold_unmountAllAsecs(void) {
-    int rc;
-
-    VolumeManager *vm = VolumeManager::Instance();
-    rc = vm->unmountAllAsecsInDir(Volume::SEC_ASECDIR_EXT);
-    if (vm->unmountAllAsecsInDir(Volume::SEC_ASECDIR_INT)) {
-        rc = -1;
-    }
-    return rc;
-}
-
-#define ID_BUF_LEN 256
-#define ASEC_SUFFIX ".asec"
-#define ASEC_SUFFIX_LEN (sizeof(ASEC_SUFFIX) - 1)
-int VolumeManager::unmountAllAsecsInDir(const char *directory) {
-    DIR *d = opendir(directory);
-    int rc = 0;
-
-    if (!d) {
-        SLOGE("Could not open asec dir %s", directory);
-        return -1;
-    }
-
-    size_t dirent_len = offsetof(struct dirent, d_name) +
-            fpathconf(dirfd(d), _PC_NAME_MAX) + 1;
-
-    struct dirent *dent = (struct dirent *) malloc(dirent_len);
-    if (dent == NULL) {
-        SLOGE("Failed to allocate memory for asec dir");
-        return -1;
-    }
-
-    struct dirent *result;
-    while (!readdir_r(d, dent, &result) && result != NULL) {
-        if (dent->d_name[0] == '.')
-            continue;
-        if (dent->d_type != DT_REG)
-            continue;
-        size_t name_len = strlen(dent->d_name);
-        if (name_len > 5 && name_len < (ID_BUF_LEN + ASEC_SUFFIX_LEN - 1) &&
-                !strcmp(&dent->d_name[name_len - 5], ASEC_SUFFIX)) {
-            char id[ID_BUF_LEN];
-            strlcpy(id, dent->d_name, name_len - 4);
-            if (unmountAsec(id, true)) {
-                /* Register the error, but try to unmount more asecs */
-                rc = -1;
-            }
-        }
-    }
-    closedir(d);
-
-    free(dent);
-
-    return rc;
-}
-
-/*
- * Looks up a volume by it's label or mount-point
- */
-Volume *VolumeManager::lookupVolume(const char *label) {
-    VolumeCollection::iterator i;
-
-    for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
-        if (label[0] == '/') {
-            if (!strcmp(label, (*i)->getFuseMountpoint()))
-                return (*i);
-        } else {
-            if (!strcmp(label, (*i)->getLabel()))
-                return (*i);
-        }
-    }
-    return NULL;
+    return vm->unmountAll();
 }
 
 bool VolumeManager::isMountpointMounted(const char *mp)
@@ -1818,77 +1663,13 @@
     return found_mp;
 }
 
-int VolumeManager::cleanupAsec(Volume *v, bool force) {
-    int rc = 0;
-
-    char asecFileName[255];
-
-    AsecIdCollection removeAsec;
-    AsecIdCollection removeObb;
-
-    for (AsecIdCollection::iterator it = mActiveContainers->begin(); it != mActiveContainers->end();
-            ++it) {
-        ContainerData* cd = *it;
-
-        if (cd->type == ASEC) {
-            if (findAsec(cd->id, asecFileName, sizeof(asecFileName))) {
-                SLOGE("Couldn't find ASEC %s; cleaning up", cd->id);
-                removeAsec.push_back(cd);
-            } else {
-                SLOGD("Found ASEC at path %s", asecFileName);
-                if (!strncmp(asecFileName, Volume::SEC_ASECDIR_EXT,
-                        strlen(Volume::SEC_ASECDIR_EXT))) {
-                    removeAsec.push_back(cd);
-                }
-            }
-        } else if (cd->type == OBB) {
-            if (v == getVolumeForFile(cd->id)) {
-                removeObb.push_back(cd);
-            }
-        } else {
-            SLOGE("Unknown container type %d!", cd->type);
-        }
-    }
-
-    for (AsecIdCollection::iterator it = removeAsec.begin(); it != removeAsec.end(); ++it) {
-        ContainerData *cd = *it;
-        SLOGI("Unmounting ASEC %s (dependent on %s)", cd->id, v->getLabel());
-        if (unmountAsec(cd->id, force)) {
-            SLOGE("Failed to unmount ASEC %s (%s)", cd->id, strerror(errno));
-            rc = -1;
-        }
-    }
-
-    for (AsecIdCollection::iterator it = removeObb.begin(); it != removeObb.end(); ++it) {
-        ContainerData *cd = *it;
-        SLOGI("Unmounting OBB %s (dependent on %s)", cd->id, v->getLabel());
-        if (unmountObb(cd->id, force)) {
-            SLOGE("Failed to unmount OBB %s (%s)", cd->id, strerror(errno));
-            rc = -1;
-        }
-    }
-
-    return rc;
-}
-
 int VolumeManager::mkdirs(char* path) {
-    // Require that path lives under a volume we manage and is mounted
-    const char* emulated_source = getenv("EMULATED_STORAGE_SOURCE");
-    const char* root = NULL;
-    if (emulated_source && !strncmp(path, emulated_source, strlen(emulated_source))) {
-        root = emulated_source;
+    // Only offer to create directories for paths managed by vold
+    if (strncmp(path, "/storage/", 9) == 0) {
+        // fs_mkdirs() does symlink checking and relative path enforcement
+        return fs_mkdirs(path, 0700);
     } else {
-        Volume* vol = getVolumeForFile(path);
-        if (vol && vol->getState() == Volume::State_Mounted) {
-            root = vol->getMountpoint();
-        }
-    }
-
-    if (!root) {
         SLOGE("Failed to find mounted volume for %s", path);
         return -EINVAL;
     }
-
-    /* fs_mkdirs() does symlink checking and relative path enforcement */
-    return fs_mkdirs(path, 0700);
 }
diff --git a/VolumeManager.h b/VolumeManager.h
index 17fa6f7..e0b0ac8 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -14,16 +14,26 @@
  * limitations under the License.
  */
 
-#ifndef _VOLUMEMANAGER_H
-#define _VOLUMEMANAGER_H
+#ifndef ANDROID_VOLD_VOLUME_MANAGER_H
+#define ANDROID_VOLD_VOLUME_MANAGER_H
 
 #include <pthread.h>
+#include <fnmatch.h>
+#include <stdlib.h>
 
 #ifdef __cplusplus
+
+#include <list>
+#include <mutex>
+#include <string>
+
+#include <cutils/multiuser.h>
 #include <utils/List.h>
 #include <sysutils/SocketListener.h>
+#include <sysutils/NetlinkEvent.h>
 
-#include "Volume.h"
+#include "Disk.h"
+#include "VolumeBase.h"
 
 /* The length of an MD5 hash when encoded into ASCII hex characters */
 #define MD5_ASCII_LENGTH_PLUS_NULL ((MD5_DIGEST_LENGTH*2)+1)
@@ -51,13 +61,17 @@
 typedef android::List<ContainerData*> AsecIdCollection;
 
 class VolumeManager {
+public:
+    static const char *SEC_ASECDIR_EXT;
+    static const char *SEC_ASECDIR_INT;
+    static const char *ASECDIR;
+    static const char *LOOPDIR;
+
 private:
     static VolumeManager *sInstance;
 
-private:
     SocketListener        *mBroadcaster;
 
-    VolumeCollection      *mVolumes;
     AsecIdCollection      *mActiveContainers;
     bool                   mDebug;
 
@@ -65,26 +79,53 @@
     int                    mUmsSharingCount;
     int                    mSavedDirtyRatio;
     int                    mUmsDirtyRatio;
-    int                    mVolManagerDisabled;
 
 public:
     virtual ~VolumeManager();
 
+    // TODO: pipe all requests through VM to avoid exposing this lock
+    std::mutex& getLock() { return mLock; }
+
     int start();
     int stop();
 
     void handleBlockEvent(NetlinkEvent *evt);
 
-    int addVolume(Volume *v);
+    class DiskSource {
+    public:
+        DiskSource(const std::string& sysPattern, const std::string& nickname, int flags) :
+                mSysPattern(sysPattern), mNickname(nickname), mFlags(flags) {
+        }
 
-    int listVolumes(SocketClient *cli, bool broadcast);
-    int mountVolume(const char *label);
-    int unmountVolume(const char *label, bool force, bool revert);
-    int shareVolume(const char *label, const char *method);
-    int unshareVolume(const char *label, const char *method);
-    int shareEnabled(const char *path, const char *method, bool *enabled);
-    int formatVolume(const char *label, bool wipe);
-    void disableVolumeManager(void) { mVolManagerDisabled = 1; }
+        bool matches(const std::string& sysPath) {
+            return !fnmatch(mSysPattern.c_str(), sysPath.c_str(), 0);
+        }
+
+        const std::string& getNickname() { return mNickname; }
+        int getFlags() { return mFlags; }
+
+    private:
+        std::string mSysPattern;
+        std::string mNickname;
+        int mFlags;
+    };
+
+    void addDiskSource(const std::shared_ptr<DiskSource>& diskSource);
+
+    std::shared_ptr<android::vold::Disk> findDisk(const std::string& id);
+    std::shared_ptr<android::vold::VolumeBase> findVolume(const std::string& id);
+
+    int startUser(userid_t userId);
+    int cleanupUser(userid_t userId);
+
+    int setPrimary(const std::shared_ptr<android::vold::VolumeBase>& vol);
+
+    /* Reset all internal state, typically during framework boot */
+    int reset();
+    /* Prepare for device shutdown, safely unmounting all devices */
+    int shutdown();
+    /* Unmount all volumes, usually for encryption */
+    int unmountAll();
 
     /* ASEC */
     int findAsec(const char *id, char *asecPath = NULL, size_t asecPathLen = 0,
@@ -118,16 +159,11 @@
     int unmountObb(const char *fileName, bool force);
     int getObbMountPath(const char *id, char *buffer, int maxlen);
 
-    Volume* getVolumeForFile(const char *fileName);
-
     /* Shared between ASEC and Loopback images */
     int unmountLoopImage(const char *containerId, const char *loopId,
             const char *fileName, const char *mountPoint, bool force);
 
-    void setDebug(bool enable);
-
-    // XXX: Post froyo this should be moved and cleaned up
-    int cleanupAsec(Volume *v, bool force);
+    int setDebug(bool enable);
 
     void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; }
     SocketListener *getBroadcaster() { return mBroadcaster; }
@@ -136,11 +172,6 @@
 
     static char *asecHash(const char *id, char *buffer, size_t len);
 
-    Volume *lookupVolume(const char *label);
-    int getNumDirectVolumes(void);
-    int getDirectVolumeList(struct volume_info *vol_list);
-    int unmountAllAsecsInDir(const char *directory);
-
     /*
      * Ensure that all directories along given path exist, creating parent
      * directories as needed.  Validates that given path is absolute and that
@@ -156,15 +187,24 @@
     bool isMountpointMounted(const char *mp);
     bool isAsecInDirectory(const char *dir, const char *asec) const;
     bool isLegalAsecId(const char *id) const;
+
+    int linkPrimary(userid_t userId);
+
+    std::mutex mLock;
+
+    std::list<std::shared_ptr<DiskSource>> mDiskSources;
+    std::list<std::shared_ptr<android::vold::Disk>> mDisks;
+
+    std::list<userid_t> mUsers;
+
+    std::shared_ptr<android::vold::VolumeBase> mInternalEmulated;
+    std::shared_ptr<android::vold::VolumeBase> mPrimary;
 };
 
 extern "C" {
 #endif /* __cplusplus */
 #define UNMOUNT_NOT_MOUNTED_ERR -2
-    int vold_disableVol(const char *label);
-    int vold_getNumDirectVolumes(void);
-    int vold_getDirectVolumeList(struct volume_info *v);
-    int vold_unmountAllAsecs(void);
+    int vold_unmountAll(void);
 #ifdef __cplusplus
 }
 #endif
diff --git a/cryptfs.c b/cryptfs.c
index 91487ed..f6bad74 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -236,20 +236,6 @@
     //    necessary, but is necessary to ensure consistency in
     //    implementations.
     switch (ftr->kdf_type) {
-        case KDF_SCRYPT_KEYMASTER_UNPADDED:
-            // This is broken: It produces a message which is shorter than
-            // the public modulus, failing criterion 2.
-            memcpy(to_sign, object, object_size);
-            to_sign_size = object_size;
-            SLOGI("Signing unpadded object");
-            break;
-        case KDF_SCRYPT_KEYMASTER_BADLY_PADDED:
-            // This is broken: Since the value of object is uniformly
-            // distributed, it produces a message that is larger than the
-            // public modulus with probability 0.25.
-            memcpy(to_sign, object, min(RSA_KEY_SIZE_BYTES, object_size));
-            SLOGI("Signing end-padded object");
-            break;
         case KDF_SCRYPT_KEYMASTER:
             // This ensures the most significant byte of the signed message
             // is zero.  We could have zero-padded to the left instead, but
@@ -394,7 +380,7 @@
     struct ext4_super_block sb;
     off64_t len;
 
-    if ((fd = open(dev, O_RDONLY)) < 0) {
+    if ((fd = open(dev, O_RDONLY|O_CLOEXEC)) < 0) {
         SLOGE("Cannot open device to get filesystem size ");
         return 0;
     }
@@ -437,7 +423,7 @@
     fs_mgr_get_crypt_info(fstab, key_loc, real_blkdev, sizeof(key_loc));
 
     if (!strcmp(key_loc, KEY_IN_FOOTER)) {
-      if ( (fd = open(real_blkdev, O_RDWR)) < 0) {
+      if ( (fd = open(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
         SLOGE("Cannot open real block device %s\n", real_blkdev);
         return -1;
       }
@@ -499,7 +485,7 @@
     SLOGE("Unexpected value for crypto key location\n");
     return -1;
   }
-  if ( (fd = open(fname, O_RDWR | O_CREAT, 0600)) < 0) {
+  if ( (fd = open(fname, O_RDWR | O_CREAT|O_CLOEXEC, 0600)) < 0) {
     SLOGE("Cannot open footer file %s for put\n", fname);
     return -1;
   }
@@ -637,7 +623,7 @@
     SLOGE("Unexpected value for crypto key location\n");
     return -1;
   }
-  if ( (fd = open(fname, O_RDWR)) < 0) {
+  if ( (fd = open(fname, O_RDWR|O_CLOEXEC)) < 0) {
     SLOGE("Cannot open footer file %s for get\n", fname);
     return -1;
   }
@@ -762,7 +748,7 @@
         return -1;
     }
 
-    fd = open(fname, O_RDONLY);
+    fd = open(fname, O_RDONLY|O_CLOEXEC);
     if (fd < 0) {
         SLOGE("Cannot open %s metadata file", fname);
         return -1;
@@ -843,7 +829,7 @@
         return -1;
     }
 
-    fd = open(fname, O_RDWR);
+    fd = open(fname, O_RDWR|O_CLOEXEC);
     if (fd < 0) {
         SLOGE("Cannot open %s metadata file", fname);
         return -1;
@@ -959,9 +945,8 @@
 /* Convert a binary key of specified length into an ascii hex string equivalent,
  * without the leading 0x and with null termination
  */
-static void convert_key_to_hex_ascii(unsigned char *master_key, unsigned int keysize,
-                              char *master_key_ascii)
-{
+static void convert_key_to_hex_ascii(const unsigned char *master_key,
+        unsigned int keysize, char *master_key_ascii) {
   unsigned int i, a;
   unsigned char nibble;
 
@@ -979,10 +964,9 @@
 
 }
 
-static int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr, unsigned char *master_key,
-                                     char *real_blk_name, const char *name, int fd,
-                                     char *extra_params)
-{
+static int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr,
+        const unsigned char *master_key, const char *real_blk_name,
+        const char *name, int fd, const char *extra_params) {
   _Alignas(struct dm_ioctl) char buffer[DM_CRYPT_BUF_SIZE];
   struct dm_ioctl *io;
   struct dm_target_spec *tgt;
@@ -1071,9 +1055,9 @@
     return -1;
 }
 
-static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char *master_key,
-                                    char *real_blk_name, char *crypto_blk_name, const char *name)
-{
+static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr,
+        const unsigned char *master_key, const char *real_blk_name,
+        char *crypto_blk_name, const char *name) {
   char buffer[DM_CRYPT_BUF_SIZE];
   struct dm_ioctl *io;
   unsigned int minor;
@@ -1083,7 +1067,7 @@
   char *extra_params;
   int load_count;
 
-  if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) {
+  if ((fd = open("/dev/device-mapper", O_RDWR|O_CLOEXEC)) < 0 ) {
     SLOGE("Cannot open device-mapper\n");
     goto errout;
   }
@@ -1148,7 +1132,7 @@
   struct dm_ioctl *io;
   int retval = -1;
 
-  if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) {
+  if ((fd = open("/dev/device-mapper", O_RDWR|O_CLOEXEC)) < 0 ) {
     SLOGE("Cannot open device-mapper\n");
     goto errout;
   }
@@ -1274,8 +1258,6 @@
     get_device_scrypt_params(crypt_ftr);
 
     switch (crypt_ftr->kdf_type) {
-    case KDF_SCRYPT_KEYMASTER_UNPADDED:
-    case KDF_SCRYPT_KEYMASTER_BADLY_PADDED:
     case KDF_SCRYPT_KEYMASTER:
         if (keymaster_create_key(crypt_ftr)) {
             SLOGE("keymaster_create_key failed");
@@ -1396,9 +1378,7 @@
 
 static void get_kdf_func(struct crypt_mnt_ftr *ftr, kdf_func *kdf, void** kdf_params)
 {
-    if (ftr->kdf_type == KDF_SCRYPT_KEYMASTER_UNPADDED ||
-        ftr->kdf_type == KDF_SCRYPT_KEYMASTER_BADLY_PADDED ||
-        ftr->kdf_type == KDF_SCRYPT_KEYMASTER) {
+    if (ftr->kdf_type == KDF_SCRYPT_KEYMASTER) {
         *kdf = scrypt_keymaster;
         *kdf_params = ftr;
     } else if (ftr->kdf_type == KDF_SCRYPT) {
@@ -1436,7 +1416,7 @@
     unsigned char key_buf[KEY_LEN_BYTES];
 
     /* Get some random bits for a key */
-    fd = open("/dev/urandom", O_RDONLY);
+    fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC);
     read(fd, key_buf, sizeof(key_buf));
     read(fd, salt, SALT_LEN);
     close(fd);
@@ -1469,10 +1449,10 @@
         if (kill) {
             if (i == (WAIT_UNMOUNT_COUNT - 3)) {
                 SLOGW("sending SIGHUP to processes with open files\n");
-                vold_killProcessesWithOpenFiles(mountpoint, 1);
+                vold_killProcessesWithOpenFiles(mountpoint, SIGTERM);
             } else if (i == (WAIT_UNMOUNT_COUNT - 2)) {
                 SLOGW("sending SIGKILL to processes with open files\n");
-                vold_killProcessesWithOpenFiles(mountpoint, 2);
+                vold_killProcessesWithOpenFiles(mountpoint, SIGKILL);
             }
         }
 
@@ -1903,36 +1883,18 @@
   return rc;
 }
 
-/* Called by vold when it wants to undo the crypto mapping of a volume it
- * manages.  This is usually in response to a factory reset, when we want
- * to undo the crypto mapping so the volume is formatted in the clear.
- */
-int cryptfs_revert_volume(const char *label)
-{
-    return delete_crypto_blk_dev((char *)label);
-}
-
 /*
- * Called by vold when it's asked to mount an encrypted, nonremovable volume.
- * Setup a dm-crypt mapping, use the saved master key from
- * setting up the /data mapping, and return the new device path.
+ * Called by vold when it's asked to mount an encrypted external
+ * storage volume. The incoming partition has no crypto header/footer,
+ * as any metadata is been stored in a separate, small partition.
+ *
+ * out_crypto_blkdev must be MAXPATHLEN.
  */
-int cryptfs_setup_volume(const char *label, int major, int minor,
-                         char *crypto_sys_path, unsigned int max_path,
-                         int *new_major, int *new_minor)
-{
-    char real_blkdev[MAXPATHLEN], crypto_blkdev[MAXPATHLEN];
-    struct crypt_mnt_ftr sd_crypt_ftr;
-    struct stat statbuf;
-
-    sprintf(real_blkdev, "/dev/block/vold/%d:%d", major, minor);
-
-    get_crypt_ftr_and_key(&sd_crypt_ftr);
-
-    /* Update the fs_size field to be the size of the volume */
-    int fd = open(real_blkdev, O_RDONLY);
+int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev,
+        const unsigned char* key, int keysize, char* out_crypto_blkdev) {
+    int fd = open(real_blkdev, O_RDONLY|O_CLOEXEC);
     if (fd == -1) {
-        SLOGE("Cannot open volume %s\n", real_blkdev);
+        SLOGE("Failed to open %s: %s", real_blkdev, strerror(errno));
         return -1;
     }
 
@@ -1941,25 +1903,26 @@
     close(fd);
 
     if (nr_sec == 0) {
-        SLOGE("Cannot get size of volume %s\n", real_blkdev);
+        SLOGE("Failed to get size of %s: %s", real_blkdev, strerror(errno));
         return -1;
     }
 
-    sd_crypt_ftr.fs_size = nr_sec;
-    create_crypto_blk_dev(&sd_crypt_ftr, saved_master_key, real_blkdev, 
-                          crypto_blkdev, label);
+    struct crypt_mnt_ftr ext_crypt_ftr;
+    memset(&ext_crypt_ftr, 0, sizeof(ext_crypt_ftr));
+    ext_crypt_ftr.fs_size = nr_sec;
+    ext_crypt_ftr.keysize = keysize;
+    strcpy((char*) ext_crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256");
 
-    if (stat(crypto_blkdev, &statbuf) < 0) {
-        SLOGE("Error get stat for crypto_blkdev %s. err=%d(%s)\n",
-              crypto_blkdev, errno, strerror(errno));
-    }
-    *new_major = MAJOR(statbuf.st_rdev);
-    *new_minor = MINOR(statbuf.st_rdev);
+    return create_crypto_blk_dev(&ext_crypt_ftr, key, real_blkdev,
+            out_crypto_blkdev, label);
+}
 
-    /* Create path to sys entry for this block device */
-    snprintf(crypto_sys_path, max_path, "/devices/virtual/block/%s", strrchr(crypto_blkdev, '/')+1);
-
-    return 0;
+/*
+ * Called by vold when it's asked to unmount an encrypted external
+ * storage volume.
+ */
+int cryptfs_revert_ext_volume(const char* label) {
+    return delete_crypto_blk_dev((char*) label);
 }
 
 int cryptfs_crypto_complete(void)
@@ -2490,14 +2453,14 @@
     data.real_blkdev = real_blkdev;
     data.crypto_blkdev = crypto_blkdev;
 
-    if ( (data.realfd = open(real_blkdev, O_RDWR)) < 0) {
+    if ( (data.realfd = open(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
         SLOGE("Error opening real_blkdev %s for inplace encrypt. err=%d(%s)\n",
               real_blkdev, errno, strerror(errno));
         rc = -1;
         goto errout;
     }
 
-    if ( (data.cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) {
+    if ( (data.cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) {
         SLOGE("Error opening crypto_blkdev %s for ext4 inplace encrypt. err=%d(%s)\n",
               crypto_blkdev, errno, strerror(errno));
         rc = ENABLE_INPLACE_ERR_DEV;
@@ -2621,12 +2584,12 @@
     data.crypto_blkdev = crypto_blkdev;
     data.realfd = -1;
     data.cryptofd = -1;
-    if ( (data.realfd = open64(real_blkdev, O_RDWR)) < 0) {
+    if ( (data.realfd = open64(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
         SLOGE("Error opening real_blkdev %s for f2fs inplace encrypt\n",
               real_blkdev);
         goto errout;
     }
-    if ( (data.cryptofd = open64(crypto_blkdev, O_WRONLY)) < 0) {
+    if ( (data.cryptofd = open64(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) {
         SLOGE("Error opening crypto_blkdev %s for f2fs inplace encrypt. err=%d(%s)\n",
               crypto_blkdev, errno, strerror(errno));
         rc = ENABLE_INPLACE_ERR_DEV;
@@ -2693,12 +2656,12 @@
     off64_t one_pct, cur_pct, new_pct;
     off64_t blocks_already_done, tot_numblocks;
 
-    if ( (realfd = open(real_blkdev, O_RDONLY)) < 0) { 
+    if ( (realfd = open(real_blkdev, O_RDONLY|O_CLOEXEC)) < 0) {
         SLOGE("Error opening real_blkdev %s for inplace encrypt\n", real_blkdev);
         return ENABLE_INPLACE_ERR_OTHER;
     }
 
-    if ( (cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) { 
+    if ( (cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) {
         SLOGE("Error opening crypto_blkdev %s for inplace encrypt. err=%d(%s)\n",
               crypto_blkdev, errno, strerror(errno));
         close(realfd);
@@ -2854,15 +2817,9 @@
 
 #define FRAMEWORK_BOOT_WAIT 60
 
-static inline int should_encrypt(struct volume_info *volume)
-{
-    return (volume->flags & (VOL_ENCRYPTABLE | VOL_NONREMOVABLE)) ==
-            (VOL_ENCRYPTABLE | VOL_NONREMOVABLE);
-}
-
 static int cryptfs_SHA256_fileblock(const char* filename, __le8* buf)
 {
-    int fd = open(filename, O_RDONLY);
+    int fd = open(filename, O_RDONLY|O_CLOEXEC);
     if (fd == -1) {
         SLOGE("Error opening file %s", filename);
         return -1;
@@ -2962,10 +2919,7 @@
     char encrypted_state[PROPERTY_VALUE_MAX];
     char lockid[32] = { 0 };
     char key_loc[PROPERTY_VALUE_MAX];
-    char fuse_sdcard[PROPERTY_VALUE_MAX];
-    char *sd_mnt_point;
     int num_vols;
-    struct volume_info *vol_list = 0;
     off64_t previously_encrypted_upto = 0;
 
     if (!strcmp(howarg, "wipe")) {
@@ -3005,7 +2959,7 @@
     fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev));
 
     /* Get the size of the real block device */
-    int fd = open(real_blkdev, O_RDONLY);
+    int fd = open(real_blkdev, O_RDONLY|O_CLOEXEC);
     if (fd == -1) {
         SLOGE("Cannot open block device %s\n", real_blkdev);
         goto error_unencrypted;
@@ -3040,55 +2994,15 @@
     snprintf(lockid, sizeof(lockid), "enablecrypto%d", (int) getpid());
     acquire_wake_lock(PARTIAL_WAKE_LOCK, lockid);
 
-    /* Get the sdcard mount point */
-    sd_mnt_point = getenv("EMULATED_STORAGE_SOURCE");
-    if (!sd_mnt_point) {
-       sd_mnt_point = getenv("EXTERNAL_STORAGE");
-    }
-    if (!sd_mnt_point) {
-        sd_mnt_point = "/mnt/sdcard";
-    }
-
-    /* TODO
-     * Currently do not have test devices with multiple encryptable volumes.
-     * When we acquire some, re-add support.
-     */
-    num_vols=vold_getNumDirectVolumes();
-    vol_list = malloc(sizeof(struct volume_info) * num_vols);
-    vold_getDirectVolumeList(vol_list);
-
-    for (i=0; i<num_vols; i++) {
-        if (should_encrypt(&vol_list[i])) {
-            SLOGE("Cannot encrypt if there are multiple encryptable volumes"
-                  "%s\n", vol_list[i].label);
-            goto error_unencrypted;
-        }
-    }
-
     /* The init files are setup to stop the class main and late start when
      * vold sets trigger_shutdown_framework.
      */
     property_set("vold.decrypt", "trigger_shutdown_framework");
     SLOGD("Just asked init to shut down class main\n");
 
-    if (vold_unmountAllAsecs()) {
-        /* Just report the error.  If any are left mounted,
-         * umounting /data below will fail and handle the error.
-         */
-        SLOGE("Error unmounting internal asecs");
-    }
-
-    property_get("ro.crypto.fuse_sdcard", fuse_sdcard, "");
-    if (!strcmp(fuse_sdcard, "true")) {
-        /* This is a device using the fuse layer to emulate the sdcard semantics
-         * on top of the userdata partition.  vold does not manage it, it is managed
-         * by the sdcard service.  The sdcard service was killed by the property trigger
-         * above, so just unmount it now.  We must do this _AFTER_ killing the framework,
-         * unlike the case for vold managed devices above.
-         */
-        if (wait_and_unmount(sd_mnt_point, false)) {
-            goto error_shutting_down;
-        }
+    /* Ask vold to unmount all devices that it manages */
+    if (vold_unmountAll()) {
+        SLOGE("Failed to unmount all vold managed devices");
     }
 
     /* Now unmount the /data partition. */
@@ -3236,8 +3150,6 @@
     /* Undo the dm-crypt mapping whether we succeed or not */
     delete_crypto_blk_dev("userdata");
 
-    free(vol_list);
-
     if (! rc) {
         /* Success */
         crypt_ftr.flags &= ~CRYPT_INCONSISTENT_STATE;
@@ -3278,7 +3190,7 @@
             /* wipe data if encryption failed */
             SLOGE("encryption failed - rebooting into recovery to wipe data\n");
             mkdir("/cache/recovery", 0700);
-            int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC, 0600);
+            int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0600);
             if (fd >= 0) {
                 write(fd, "--wipe_data\n", strlen("--wipe_data\n") + 1);
                 write(fd, "--reason=cryptfs_enable_internal\n", strlen("--reason=cryptfs_enable_internal\n") + 1);
@@ -3304,7 +3216,6 @@
     return rc;
 
 error_unencrypted:
-    free(vol_list);
     property_set("vold.encrypt_progress", "error_not_encrypted");
     if (lockid[0]) {
         release_wake_lock(lockid);
@@ -3321,7 +3232,6 @@
 
     /* shouldn't get here */
     property_set("vold.encrypt_progress", "error_shutting_down");
-    free(vol_list);
     if (lockid[0]) {
         release_wake_lock(lockid);
     }
@@ -3354,6 +3264,7 @@
     }
 
     struct crypt_mnt_ftr crypt_ftr;
+    int rc;
 
     /* This is only allowed after we've successfully decrypted the master key */
     if (!master_key_saved) {
@@ -3379,18 +3290,20 @@
         newpw = adjusted_passwd;
     }
 
-    encrypt_master_key(crypt_type == CRYPT_TYPE_DEFAULT ? DEFAULT_PASSWORD
+    rc = encrypt_master_key(crypt_type == CRYPT_TYPE_DEFAULT ? DEFAULT_PASSWORD
                                                         : newpw,
                        crypt_ftr.salt,
                        saved_master_key,
                        crypt_ftr.master_key,
                        &crypt_ftr);
-
+    free(adjusted_passwd);
+    if (rc) {
+        SLOGE("Encrypt master key failed: %d", rc);
+        return -1;
+    }
     /* save the key */
     put_crypt_ftr_and_key(&crypt_ftr);
 
-    free(adjusted_passwd);
-
 #ifdef CONFIG_HW_DISK_ENCRYPTION
     if (!strcmp((char *)crypt_ftr.crypto_type_name, "aes-xts")) {
         if (crypt_type == CRYPT_TYPE_DEFAULT) {
diff --git a/cryptfs.h b/cryptfs.h
index 1da6f94..6984944 100644
--- a/cryptfs.h
+++ b/cryptfs.h
@@ -71,10 +71,7 @@
 /* Key Derivation Function algorithms */
 #define KDF_PBKDF2 1
 #define KDF_SCRYPT 2
-/* TODO(paullawrence): Remove KDF_SCRYPT_KEYMASTER_UNPADDED and KDF_SCRYPT_KEYMASTER_BADLY_PADDED
- * when it is safe to do so. */
-#define KDF_SCRYPT_KEYMASTER_UNPADDED 3
-#define KDF_SCRYPT_KEYMASTER_BADLY_PADDED 4
+/* Algorithms 3 & 4 deprecated before shipping outside of google, so removed */
 #define KDF_SCRYPT_KEYMASTER 5
 
 /* Maximum allowed keymaster blob size. */
@@ -175,20 +172,6 @@
   struct crypt_persist_entry persist_entry[0];
 };
 
-struct volume_info {
-   unsigned int size;
-   unsigned int flags;
-   struct crypt_mnt_ftr crypt_ftr;
-   char mnt_point[256];
-   char blk_dev[256];
-   char crypto_blkdev[256];
-   char label[256];
-};
-#define VOL_NONREMOVABLE   0x1
-#define VOL_ENCRYPTABLE    0x2
-#define VOL_PRIMARY        0x4
-#define VOL_PROVIDES_ASEC  0x8
-
 #define DATA_MNT_POINT "/data"
 
 /* Return values for cryptfs_crypto_complete */
@@ -235,10 +218,9 @@
   int cryptfs_enable(char *flag, int type, char *passwd, int allow_reboot);
   int cryptfs_changepw(int type, const char *newpw);
   int cryptfs_enable_default(char *flag, int allow_reboot);
-  int cryptfs_setup_volume(const char *label, int major, int minor,
-                           char *crypto_dev_path, unsigned int max_pathlen,
-                           int *new_major, int *new_minor);
-  int cryptfs_revert_volume(const char *label);
+  int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev,
+          const unsigned char* key, int keysize, char* out_crypto_blkdev);
+  int cryptfs_revert_ext_volume(const char* label);
   int cryptfs_getfield(const char *fieldname, char *value, int len);
   int cryptfs_setfield(const char *fieldname, const char *value);
   int cryptfs_mount_default_encrypted(void);
diff --git a/fstrim.c b/fstrim.c
index 2c24fc9..60c9f24 100644
--- a/fstrim.c
+++ b/fstrim.c
@@ -64,6 +64,7 @@
     struct fstrim_range range = { 0 };
     extern struct fstab *fstab;
     int deep_trim = !!thread_arg;
+    struct fstab_rec *prev_rec = NULL;
 
     SLOGI("Starting fstrim work...\n");
 
@@ -88,6 +89,16 @@
         if (fs_mgr_is_voldmanaged(&fstab->recs[i])) {
             continue; /* Should we trim fat32 filesystems? */
         }
+        if (fs_mgr_is_notrim(&fstab->recs[i])) {
+            continue;
+        }
+
+        /* Skip the multi-type partitions, which are required to be following each other.
+         * See fs_mgr.c's mount_with_alternatives().
+         */
+        if (prev_rec && !strcmp(prev_rec->mount_point, fstab->recs[i].mount_point)) {
+            continue;
+        }
 
         fd = open(fstab->recs[i].mount_point, O_RDONLY | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
         if (fd < 0) {
@@ -108,6 +119,7 @@
             SLOGI("Trimmed %llu bytes on %s\n", range.len, fstab->recs[i].mount_point);
         }
         close(fd);
+        prev_rec = &fstab->recs[i];
     }
 
     /* Log the finish time in the event log */
diff --git a/main.cpp b/main.cpp
index c07f48d..64cd0ee 100644
--- a/main.cpp
+++ b/main.cpp
@@ -14,49 +14,59 @@
  * limitations under the License.
  */
 
+#include "Disk.h"
+#include "VolumeManager.h"
+#include "CommandListener.h"
+#include "NetlinkManager.h"
+#include "cryptfs.h"
+#include "sehandle.h"
+
+#include <base/logging.h>
+#include <base/stringprintf.h>
+#include <cutils/klog.h>
+#include <cutils/properties.h>
+#include <cutils/sockets.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-
+#include <getopt.h>
 #include <fcntl.h>
 #include <dirent.h>
 #include <fs_mgr.h>
 
-#define LOG_TAG "Vold"
-
-#include "cutils/klog.h"
-#include "cutils/log.h"
-#include "cutils/properties.h"
-
-#include "VolumeManager.h"
-#include "CommandListener.h"
-#include "NetlinkManager.h"
-#include "DirectVolume.h"
-#include "cryptfs.h"
-#include "sehandle.h"
-
 static int process_config(VolumeManager *vm);
 static void coldboot(const char *path);
+static void parse_args(int argc, char** argv);
 
-#define FSTAB_PREFIX "/fstab."
 struct fstab *fstab;
 
 struct selabel_handle *sehandle;
 
-int main() {
+using android::base::StringPrintf;
+
+int main(int argc, char** argv) {
+    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";
 
     VolumeManager *vm;
     CommandListener *cl;
     NetlinkManager *nm;
 
-    SLOGI("Vold 2.1 (the revenge) firing up");
+    parse_args(argc, argv);
 
     sehandle = selinux_android_file_context_handle();
-    if (sehandle)
+    if (sehandle) {
         selinux_android_set_sehandle(sehandle);
+    }
+
+    // Quickly throw a CLOEXEC on the socket we just inherited from init
+    fcntl(android_get_control_socket("vold"), F_SETFD, FD_CLOEXEC);
 
     mkdir("/dev/block/vold", 0755);
 
@@ -65,31 +75,30 @@
 
     /* Create our singleton managers */
     if (!(vm = VolumeManager::Instance())) {
-        SLOGE("Unable to create VolumeManager");
+        LOG(ERROR) << "Unable to create VolumeManager";
         exit(1);
-    };
+    }
 
     if (!(nm = NetlinkManager::Instance())) {
-        SLOGE("Unable to create NetlinkManager");
+        LOG(ERROR) << "Unable to create NetlinkManager";
         exit(1);
-    };
-
+    }
 
     cl = new CommandListener();
     vm->setBroadcaster((SocketListener *) cl);
     nm->setBroadcaster((SocketListener *) cl);
 
     if (vm->start()) {
-        SLOGE("Unable to start VolumeManager (%s)", strerror(errno));
+        PLOG(ERROR) << "Unable to start VolumeManager";
         exit(1);
     }
 
     if (process_config(vm)) {
-        SLOGE("Error reading configuration (%s)... continuing anyways", strerror(errno));
+        PLOG(ERROR) << "Error reading configuration... continuing anyways";
     }
 
     if (nm->start()) {
-        SLOGE("Unable to start NetlinkManager (%s)", strerror(errno));
+        PLOG(ERROR) << "Unable to start NetlinkManager";
         exit(1);
     }
 
@@ -100,7 +109,7 @@
      * Now that we're up, we can respond to commands
      */
     if (cl->startListener()) {
-        SLOGE("Unable to start CommandListener (%s)", strerror(errno));
+        PLOG(ERROR) << "Unable to start CommandListener";
         exit(1);
     }
 
@@ -109,18 +118,41 @@
         sleep(1000);
     }
 
-    SLOGI("Vold exiting");
+    LOG(ERROR) << "Vold exiting";
     exit(0);
 }
 
-static void do_coldboot(DIR *d, int lvl)
-{
+static void parse_args(int argc, char** argv) {
+    static struct option opts[] = {
+        {"blkid_context", required_argument, 0, 'b' },
+        {"blkid_untrusted_context", required_argument, 0, 'B' },
+        {"fsck_context", required_argument, 0, 'f' },
+        {"fsck_untrusted_context", required_argument, 0, 'F' },
+    };
+
+    int c;
+    while ((c = getopt_long(argc, argv, "", opts, nullptr)) != -1) {
+        switch (c) {
+        case 'b': android::vold::sBlkidContext = optarg; break;
+        case 'B': android::vold::sBlkidUntrustedContext = optarg; break;
+        case 'f': android::vold::sFsckContext = optarg; break;
+        case 'F': android::vold::sFsckUntrustedContext = optarg; break;
+        }
+    }
+
+    CHECK(android::vold::sBlkidContext != nullptr);
+    CHECK(android::vold::sBlkidUntrustedContext != nullptr);
+    CHECK(android::vold::sFsckContext != nullptr);
+    CHECK(android::vold::sFsckUntrustedContext != nullptr);
+}
+
+static void do_coldboot(DIR *d, int lvl) {
     struct dirent *de;
     int dfd, fd;
 
     dfd = dirfd(d);
 
-    fd = openat(dfd, "uevent", O_WRONLY);
+    fd = openat(dfd, "uevent", O_WRONLY | O_CLOEXEC);
     if(fd >= 0) {
         write(fd, "add\n", 4);
         close(fd);
@@ -149,8 +181,7 @@
     }
 }
 
-static void coldboot(const char *path)
-{
+static void coldboot(const char *path) {
     DIR *d = opendir(path);
     if(d) {
         do_coldboot(d, 0);
@@ -158,55 +189,47 @@
     }
 }
 
-static int process_config(VolumeManager *vm)
-{
-    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
-    char propbuf[PROPERTY_VALUE_MAX];
-    int i;
-    int ret = -1;
-    int flags;
+static int process_config(VolumeManager *vm) {
+    char hardware[PROPERTY_VALUE_MAX];
+    property_get("ro.hardware", hardware, "");
+    std::string fstab_filename(StringPrintf("/fstab.%s", hardware));
 
-    property_get("ro.hardware", propbuf, "");
-    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
+#ifdef DEBUG_FSTAB
+    if (access(DEBUG_FSTAB, R_OK) == 0) {
+        LOG(DEBUG) << "Found debug fstab; switching!";
+        fstab_filename = DEBUG_FSTAB;
+    }
+#endif
 
-    fstab = fs_mgr_read_fstab(fstab_filename);
+    fstab = fs_mgr_read_fstab(fstab_filename.c_str());
     if (!fstab) {
-        SLOGE("failed to open %s\n", fstab_filename);
+        PLOG(ERROR) << "Failed to open " << fstab_filename;
         return -1;
     }
 
     /* Loop through entries looking for ones that vold manages */
-    for (i = 0; i < fstab->num_entries; i++) {
+    for (int i = 0; i < fstab->num_entries; i++) {
         if (fs_mgr_is_voldmanaged(&fstab->recs[i])) {
-            DirectVolume *dv = NULL;
-            flags = 0;
-
-            /* Set any flags that might be set for this volume */
             if (fs_mgr_is_nonremovable(&fstab->recs[i])) {
-                flags |= VOL_NONREMOVABLE;
+                LOG(WARNING) << "nonremovable no longer supported; ignoring volume";
+                continue;
             }
+
+            std::string sysPattern(fstab->recs[i].blk_device);
+            std::string nickname(fstab->recs[i].label);
+            int flags = 0;
+
             if (fs_mgr_is_encryptable(&fstab->recs[i])) {
-                flags |= VOL_ENCRYPTABLE;
+                flags |= android::vold::Disk::Flags::kAdoptable;
             }
-            /* Only set this flag if there is not an emulated sd card */
-            if (fs_mgr_is_noemulatedsd(&fstab->recs[i]) &&
-                !strcmp(fstab->recs[i].fs_type, "vfat")) {
-                flags |= VOL_PROVIDES_ASEC;
-            }
-            dv = new DirectVolume(vm, &(fstab->recs[i]), flags);
-
-            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 (fs_mgr_is_noemulatedsd(&fstab->recs[i])) {
+                flags |= android::vold::Disk::Flags::kDefaultPrimary;
             }
 
-            vm->addVolume(dv);
+            vm->addDiskSource(std::shared_ptr<VolumeManager::DiskSource>(
+                    new VolumeManager::DiskSource(sysPattern, nickname, flags)));
         }
     }
 
-    ret = 0;
-
-out_fail:
-    return ret;
+    return 0;
 }
