Move even more vold commands over to Binder.

This moves fstrim, obb and appfuse commands over to the new Binder
interface.  This change also separates creating/destroying and
mounting/unmounting of OBB volumes, which means they finally flow
nicely into the modern VolumeInfo/VolumeBase design.

We now generate unique identifiers for all OBB volumes, instead of
using a shady MD5 hash.

Change all "loop" and "dm" devices to tag the kernel resources with
a vold-specific prefix so that we can clean them up if vold crashes;
there are new destroyAll() methods that handle this cleanup.

Move appfuse mounting/unmounting into VolumeManager so it can be
shared.  Move various model objects into a separate directory to
tidy things up.

Test: cts-tradefed run commandAndExit cts-dev -m CtsOsTestCases -t android.os.storage.cts.StorageManagerTest
Bug: 13758960
Change-Id: I7294e32b3fb6efe07cb3b77bd20166e70b66958f
diff --git a/Devmapper.cpp b/Devmapper.cpp
index 4b6942d..c945e9f 100644
--- a/Devmapper.cpp
+++ b/Devmapper.cpp
@@ -32,12 +32,18 @@
 
 #include <cutils/log.h>
 
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
 #include <sysutils/SocketClient.h>
 
 #include "Devmapper.h"
 
 #define DEVMAPPER_BUFFER_SIZE 4096
 
+using android::base::StringPrintf;
+
+static const char* kVoldPrefix = "vold:";
+
 int Devmapper::dumpState(SocketClient *c) {
 
     char *buffer = (char *) malloc(1024 * 64);
@@ -130,7 +136,10 @@
     }
 }
 
-int Devmapper::lookupActive(const char *name, char *ubuffer, size_t len) {
+int Devmapper::lookupActive(const char *name_raw, char *ubuffer, size_t len) {
+    auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
+    const char* name = name_string.c_str();
+
     char *buffer = (char *) malloc(DEVMAPPER_BUFFER_SIZE);
     if (!buffer) {
         SLOGE("Error allocating memory (%s)", strerror(errno));
@@ -163,8 +172,11 @@
     return 0;
 }
 
-int Devmapper::create(const char *name, const char *loopFile, const char *key,
+int Devmapper::create(const char *name_raw, const char *loopFile, const char *key,
                       unsigned long numSectors, char *ubuffer, size_t len) {
+    auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
+    const char* name = name_string.c_str();
+
     char *buffer = (char *) malloc(DEVMAPPER_BUFFER_SIZE);
     if (!buffer) {
         SLOGE("Error allocating memory (%s)", strerror(errno));
@@ -261,7 +273,10 @@
     return 0;
 }
 
-int Devmapper::destroy(const char *name) {
+int Devmapper::destroy(const char *name_raw) {
+    auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
+    const char* name = name_string.c_str();
+
     char *buffer = (char *) malloc(DEVMAPPER_BUFFER_SIZE);
     if (!buffer) {
         SLOGE("Error allocating memory (%s)", strerror(errno));
@@ -294,6 +309,74 @@
     return 0;
 }
 
+int Devmapper::destroyAll() {
+    char *buffer = (char *) malloc(1024 * 64);
+    if (!buffer) {
+        SLOGE("Error allocating memory (%s)", strerror(errno));
+        return -1;
+    }
+    memset(buffer, 0, (1024 * 64));
+
+    char *buffer2 = (char *) malloc(DEVMAPPER_BUFFER_SIZE);
+    if (!buffer2) {
+        SLOGE("Error allocating memory (%s)", strerror(errno));
+        free(buffer);
+        return -1;
+    }
+
+    int fd;
+    if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
+        SLOGE("Error opening devmapper (%s)", strerror(errno));
+        free(buffer);
+        free(buffer2);
+        return -1;
+    }
+
+    struct dm_ioctl *io = (struct dm_ioctl *) buffer;
+    ioctlInit(io, (1024 * 64), NULL, 0);
+
+    if (ioctl(fd, DM_LIST_DEVICES, io)) {
+        SLOGE("DM_LIST_DEVICES ioctl failed (%s)", strerror(errno));
+        free(buffer);
+        free(buffer2);
+        close(fd);
+        return -1;
+    }
+
+    struct dm_name_list *n = (struct dm_name_list *) (((char *) buffer) + io->data_start);
+    if (!n->dev) {
+        free(buffer);
+        free(buffer2);
+        close(fd);
+        return 0;
+    }
+
+    unsigned nxt = 0;
+    do {
+        n = (struct dm_name_list *) (((char *) n) + nxt);
+        if (strncmp(n->name, kVoldPrefix, strlen(kVoldPrefix)) == 0) {
+            LOG(DEBUG) << "Tearing down stale dm device named " << n->name;
+
+            memset(buffer2, 0, DEVMAPPER_BUFFER_SIZE);
+            struct dm_ioctl *io2 = (struct dm_ioctl *) buffer2;
+            ioctlInit(io2, DEVMAPPER_BUFFER_SIZE, n->name, 0);
+            if (ioctl(fd, DM_DEV_REMOVE, io2)) {
+                if (errno != ENXIO) {
+                    PLOG(WARNING) << "Failed to destroy dm device named " << n->name;
+                }
+            }
+        } else {
+            LOG(VERBOSE) << "Found unmanaged dm device named " << n->name;
+        }
+        nxt = n->next;
+    } while (nxt);
+
+    free(buffer);
+    free(buffer2);
+    close(fd);
+    return 0;
+}
+
 void *Devmapper::_align(void *ptr, unsigned int a)
 {
         unsigned long agn = --a;