auto import from //branches/cupcake/...@132276
diff --git a/vold/misc.c b/vold/misc.c
index 951414c..b8e5957 100644
--- a/vold/misc.c
+++ b/vold/misc.c
@@ -49,8 +49,11 @@
 
 	/* slurp it into our buffer */
 	ret = read(fd, buffer, size);
-	if (ret != size)
+	if (ret != size) {
+	        free(buffer);
+	        buffer = NULL;
 		goto bail;
+        }
 
 	/* let the caller know how big it is */
 	*_size = size;
@@ -59,33 +62,90 @@
 	close(fd);
 	return buffer;
 }
-char *truncate_sysfs_path(char *path, int num_elements_to_remove, char *buffer)
+
+char *truncate_sysfs_path(char *path, int count, char *buffer, size_t bufflen)
 {
-    int i;
+    char*  p;
 
-    strcpy(buffer, path);
+    strlcpy(buffer, path, bufflen);
+    p = buffer + strlen(buffer);
 
-    for (i = 0; i < num_elements_to_remove; i++) {
-        char *p = &buffer[strlen(buffer)-1];
+    for ( ; count > 0; count-- ) {
+        while (p > buffer && p[-1] != '/') {
+            p--; 
+        }
+        if (p == buffer)
+            break;
 
-        for (p = &buffer[strlen(buffer) -1]; *p != '/'; p--);
-        *p = '\0';
+        p -= 1;
     }
+    p[0] = '\0';
 
     return buffer;
 }
 
-char *read_sysfs_var(char *buffer, size_t maxlen, char *devpath, char *var)
+/* used to read the first line of a /sys file into a heap-allocated buffer
+ * this assumes that reading the file returns a list of zero-terminated strings,
+ * each could also have a terminating \n before the 0
+ *
+ * returns NULL on error, of a new string on success, which must be freed by the
+ * caller.
+ */
+char *read_first_line_of(const char*  filepath)
 {
-    char filename[255];
-    char *p;
+    char *p, *q, *line;
+    size_t  len;
     ssize_t sz;
 
-    sprintf(filename, "/sys%s/%s", devpath, var);
-    p = read_file(filename, &sz);
-    p[(strlen(p) - 1)] = '\0';
-    strncpy(buffer, p, maxlen);
+    p = read_file((char*)filepath, &sz);
+    if (p == NULL)
+        goto FAIL;
+
+    /* search end of first line */
+    q = memchr(p, sz, '\0');
+    if (q == NULL)
+        q = p + sz;  /* let's be flexible */
+
+    len = (size_t)(q - p); /* compute line length */
+    if (len == 0)
+        goto FAIL;
+
+    if (p[len-1] == '\n') { /* strip trailing \n */
+        len -= 1;
+        if (len == 0)
+            goto FAIL;
+    }
+
+    line = malloc(len+1);
+    if (line == NULL)
+        goto FAIL;
+
+    memcpy(line, p, len);
+    line[len] = 0;
     free(p);
+
+    return line;
+
+FAIL:
+    if (p != NULL)
+        free(p);
+
+    return NULL;
+}
+
+char *read_sysfs_var(char *buffer, size_t maxlen, char *devpath, char *var)
+{
+    char filename[255], *line;
+
+    snprintf(filename, sizeof filename, "/sys%s/%s", devpath, var);
+
+    line = read_first_line_of(filename);
+    if (line == NULL)
+        return NULL;
+
+    snprintf(buffer, maxlen, "%s", line);
+    free(line);
+
     return buffer;
 }
 
diff --git a/vold/uevent.c b/vold/uevent.c
index 3b7e53b..b1a6944 100644
--- a/vold/uevent.c
+++ b/vold/uevent.c
@@ -72,7 +72,7 @@
 };
 
 static boolean low_batt = false;
-static boolean door_open = false;
+static boolean door_open = true;
 
 int process_uevent_message(int socket)
 {
diff --git a/vold/volmgr.c b/vold/volmgr.c
index 0cec825..c3ce8d1 100644
--- a/vold/volmgr.c
+++ b/vold/volmgr.c
@@ -356,6 +356,7 @@
     LOG_VOL("Volmgr notified of %d:%d eject", dev->major, dev->minor);
 
     volume_t *v;
+    int rc;
 
     // XXX: Partitioning support is going to need us to stop *all*
     // devices in this volume
@@ -371,9 +372,38 @@
 
     if (v->state == volstate_mounted ||
         v->state == volstate_ums ||
-        v->state == volstate_checking)
+        v->state == volstate_checking) {
+
         volume_setstate(v, volstate_badremoval);
-    else if (v->state == volstate_formatting) {
+
+        /*
+         * Stop any devmapper volumes which
+         * are using us as a source
+         * XXX: We may need to enforce stricter
+         * order here
+         */
+        volume_t *dmvol = vol_root;
+        while (dmvol) {
+            if ((dmvol->media_type == media_devmapper) &&
+                (dmvol->dm->src_type == dmsrc_loopback) &&
+                (!strncmp(dmvol->dm->type_data.loop.loop_src, 
+                          v->mount_point, strlen(v->mount_point)))) {
+
+                pthread_mutex_lock(&dmvol->lock);
+                if (dmvol->state != volstate_nomedia) {
+                    rc = volmgr_shutdown_volume(dmvol, _cb_volstopped_for_devmapper_teardown, false);
+                    if (rc != -EINPROGRESS) {
+                        if (rc)
+                            LOGE("unable to shutdown volume '%s'", v->mount_point);
+                        pthread_mutex_unlock(&dmvol->lock);
+                    }
+                } else 
+                    pthread_mutex_unlock(&dmvol->lock);
+            }
+            dmvol = dmvol->next;
+        }
+
+    } else if (v->state == volstate_formatting) {
         /*
          * The device is being ejected due to
          * kernel disk revalidation.
@@ -409,7 +439,8 @@
     LOG_VOL("Volume %s has been stopped for eject", v->mount_point);
 #endif
 
-    eject_cb(v->dev);
+    if (eject_cb)
+        eject_cb(v->dev);
     v->dev = NULL; // Clear dev because its being ejected
 }