Merge change 7792

* changes:
  Code generator cleanup
diff --git a/vold/blkdev.c b/vold/blkdev.c
index 3167507..1482a1a 100644
--- a/vold/blkdev.c
+++ b/vold/blkdev.c
@@ -73,7 +73,7 @@
     }
 
     if (ioctl(fd, BLKGETSIZE, &blk->nr_sec)) {
-        LOGE("Unable to get device size (%m)");
+        LOGE("Unable to get device size (%s)", strerror(errno));
         return -errno;
     }
     close(fd);
diff --git a/vold/mmc.c b/vold/mmc.c
index fb61b2f..b321c80 100644
--- a/vold/mmc.c
+++ b/vold/mmc.c
@@ -43,7 +43,8 @@
     struct dirent *de;
 
     if (!(d = opendir(SYSFS_CLASS_MMC_PATH))) {
-        LOG_ERROR("Unable to open '%s' (%m)", SYSFS_CLASS_MMC_PATH);
+        LOG_ERROR("Unable to open '%s' (%s)", SYSFS_CLASS_MMC_PATH,
+                  strerror(errno));
         return -errno;
     }
 
@@ -54,8 +55,10 @@
             continue;
 
         sprintf(tmp, "%s/%s", SYSFS_CLASS_MMC_PATH, de->d_name);
-        if (mmc_bootstrap_controller(tmp))
-            LOG_ERROR("Error bootstrapping controller '%s' (%m)", tmp);
+        if (mmc_bootstrap_controller(tmp)) {
+            LOG_ERROR("Error bootstrapping controller '%s' (%s)", tmp,
+                      strerror(errno));
+        }
     }
 
     closedir(d);
@@ -72,7 +75,7 @@
     LOG_VOL("bootstrap_controller(%s):", sysfs_path);
 #endif
     if (!(d = opendir(sysfs_path))) {
-        LOG_ERROR("Unable to open '%s' (%m)", sysfs_path);
+        LOG_ERROR("Unable to open '%s' (%s)", sysfs_path, strerror(errno));
         return -errno;
     }
 
@@ -92,7 +95,7 @@
         sprintf(tmp, "%s/%s", sysfs_path, de->d_name);
 
         if (mmc_bootstrap_card(tmp) < 0)
-            LOG_ERROR("Error bootstrapping card '%s' (%m)", tmp);
+            LOG_ERROR("Error bootstrapping card '%s' (%s)", tmp, strerror(errno));
     } // while
 
     closedir(d);
@@ -123,7 +126,7 @@
     }
     
     if (chdir(sysfs_path) < 0) {
-        LOGE("Unable to chdir to %s (%m)", sysfs_path);
+        LOGE("Unable to chdir to %s (%s)", sysfs_path, strerror(errno));
         return -errno;
     }
 
@@ -162,7 +165,7 @@
     uevent_params[3] = (char *) NULL;
 
     if (simulate_uevent("mmc", devpath, "add", uevent_params) < 0) {
-        LOGE("Error simulating uevent (%m)");
+        LOGE("Error simulating uevent (%s)", strerror(errno));
         return -errno;
     }
 
@@ -264,7 +267,7 @@
 
     sprintf(filename, "/sys%s/uevent", devpath);
     if (!(fp = fopen(filename, "r"))) {
-        LOGE("Unable to open '%s' (%m)", filename);
+        LOGE("Unable to open '%s' (%s)", filename, strerror(errno));
         return -errno;
     }
 
@@ -286,7 +289,7 @@
     uevent_params[4] = '\0';
     
     if (simulate_uevent("block", devpath, "add", uevent_params) < 0) {
-        LOGE("Error simulating uevent (%m)");
+        LOGE("Error simulating uevent (%s)", strerror(errno));
         return -errno;
     }
     return 0;
diff --git a/vold/switch.c b/vold/switch.c
index ba9ddb3..d8dab43 100644
--- a/vold/switch.c
+++ b/vold/switch.c
@@ -35,7 +35,8 @@
     struct dirent *de;
 
     if (!(d = opendir(SYSFS_CLASS_SWITCH_PATH))) {
-        LOG_ERROR("Unable to open '%s' (%m)", SYSFS_CLASS_SWITCH_PATH);
+        LOG_ERROR("Unable to open '%s' (%s)", SYSFS_CLASS_SWITCH_PATH,
+                   strerror(errno));
         return -errno;
     }
 
@@ -46,8 +47,10 @@
             continue;
 
         sprintf(tmp, "%s/%s", SYSFS_CLASS_SWITCH_PATH, de->d_name);
-        if (mmc_bootstrap_switch(tmp))
-            LOG_ERROR("Error bootstrapping switch '%s' (%m)", tmp);
+        if (mmc_bootstrap_switch(tmp)) {
+            LOG_ERROR("Error bootstrapping switch '%s' (%s)", tmp,
+                      strerror(errno));
+        }
     }
 
     closedir(d);
diff --git a/vold/uevent.c b/vold/uevent.c
index 66e70c5..dffe817 100644
--- a/vold/uevent.c
+++ b/vold/uevent.c
@@ -333,7 +333,7 @@
                                      min,
                                      media,
                                      get_uevent_param(event, "DEVTYPE")))) {
-            LOGE("Unable to allocate new blkdev (%m)");
+            LOGE("Unable to allocate new blkdev (%s)", strerror(errno));
             return -1;
         }
 
@@ -354,8 +354,12 @@
 
         if (blkdev_get_num_pending_partitions(blkdev->disk) == 0) {
             if ((rc = volmgr_consider_disk(blkdev->disk)) < 0) {
-                LOGE("Volmgr failed to handle device (%d)", rc);
-                return rc;
+                if (rc == -EBUSY) {
+                    LOGI("Volmgr not ready to handle device");
+                } else {
+                    LOGE("Volmgr failed to handle device (%d)", rc);
+                    return rc;
+                }
             }
         }
     } else if (event->action == action_remove) {
@@ -414,7 +418,7 @@
                                    get_uevent_param(event, "MMC_NAME"),
                                    serial,
                                    media_mmc))) {
-            LOGE("Unable to allocate new media (%m)");
+            LOGE("Unable to allocate new media (%s)", strerror(errno));
             return -1;
         }
         LOGI("New MMC card '%s' (serial %u) added @ %s", media->name,
diff --git a/vold/vold.c b/vold/vold.c
index 7d50a2f..11b99a9 100644
--- a/vold/vold.c
+++ b/vold/vold.c
@@ -53,6 +53,8 @@
 static pthread_mutex_t write_mutex = PTHREAD_MUTEX_INITIALIZER;
 static int fw_sock = -1;
 
+int bootstrap = 0;
+
 int main(int argc, char **argv)
 {
     int door_sock = -1;
@@ -108,6 +110,7 @@
      * Bootstrap 
      */
 
+    bootstrap = 1;
     // Volume Manager
     volmgr_bootstrap();
 
@@ -120,6 +123,7 @@
     // Switch
     switch_bootstrap();
 
+    bootstrap = 0;
     /*
      * Main loop
      */
diff --git a/vold/vold.h b/vold/vold.h
index 4ff690a..abc27a1 100644
--- a/vold/vold.h
+++ b/vold/vold.h
@@ -97,4 +97,5 @@
 
 int send_msg(char *msg);
 int send_msg_with_data(char *msg, char *data);
+extern int bootstrap;
 #endif
diff --git a/vold/volmgr.c b/vold/volmgr.c
index 17c9a49..3c34a9c 100644
--- a/vold/volmgr.c
+++ b/vold/volmgr.c
@@ -523,8 +523,7 @@
 
     if (vol->state == volstate_unknown ||
         vol->state == volstate_mounted ||
-        vol->state == volstate_mounted_ro ||
-        vol->state == volstate_damaged) {
+        vol->state == volstate_mounted_ro) {
         LOGE("Cannot consider volume '%s' because it is in state '%d", 
              vol->mount_point, vol->state);
         return -EADDRINUSE;
@@ -584,7 +583,7 @@
             LOG_VOL("_volmgr_start(%s, %d:%d) rc = %d",
                     vol->mount_point, part->major, part->minor, rc);
 #endif
-            if (!rc) 
+            if (!rc || rc == -EBUSY) 
                 break;
         }
 
@@ -1066,6 +1065,13 @@
 
     vol->dev = dev; 
 
+    if (bootstrap) {
+        LOGI("Aborting start of %s (bootstrap = %d)\n", vol->mount_point,
+             bootstrap);
+        vol->state = volstate_unmounted;
+        return -EBUSY;
+    }
+
     vol->worker_args.start_args.fs = fs;
     vol->worker_args.start_args.dev = dev;
 
diff --git a/vold/volmgr_vfat.c b/vold/volmgr_vfat.c
index 7a4e12f..22e2dcf 100644
--- a/vold/volmgr_vfat.c
+++ b/vold/volmgr_vfat.c
@@ -51,28 +51,40 @@
         return 0;
     }
 
-    char *args[5];
-    args[0] = FSCK_MSDOS_PATH;
-    args[1] = "-p";
-    args[2] = "-f";
-    args[3] = blkdev_get_devpath(dev);
-    args[4] = NULL;
-    rc = logwrap(4, args, 1);
-    free(args[3]);
+    int pass = 1;
+    do {
+        char *args[5];
+        args[0] = FSCK_MSDOS_PATH;
+        args[1] = "-p";
+        args[2] = "-f";
+        args[3] = blkdev_get_devpath(dev);
+        args[4] = NULL;
+        rc = logwrap(4, args, 1);
+        free(args[3]);
 
-    if (rc == 0) {
-        LOG_VOL("Filesystem check completed OK");
-        return 0;
-    } else if (rc == 2) {
-        LOG_VOL("Filesystem check failed (not a FAT filesystem)");
-        return -ENODATA;
-    } else if (rc == -11) {
-        LOG_VOL("Filesystem check crashed");
-        return -EIO;
-    } else {
-        LOG_VOL("Filesystem check failed (unknown exit code %d)", rc);
-        return -EIO;
-    }
+        if (rc == 0) {
+            LOG_VOL("Filesystem check completed OK");
+            return 0;
+        } else if (rc == 2) {
+            LOG_VOL("Filesystem check failed (not a FAT filesystem)");
+            return -ENODATA;
+        } else if (rc == 4) {
+            if (pass++ <= 3) {
+                LOG_VOL("Filesystem modified - rechecking (pass %d)",
+                        pass);
+                continue;
+            } else {
+                LOG_VOL("Failing check after too many rechecks");
+                return -EIO;
+            }
+        } else if (rc == -11) {
+            LOG_VOL("Filesystem check crashed");
+            return -EIO;
+        } else {
+            LOG_VOL("Filesystem check failed (unknown exit code %d)", rc);
+            return -EIO;
+        }
+    } while (0);
     return 0;
 }
 
@@ -113,6 +125,21 @@
                    "utf8,uid=1000,gid=1015,fmask=702,dmask=702,shortname=mixed");
     }
 
+    if (rc == 0) {
+        char *lost_path;
+        asprintf(&lost_path, "%s/LOST.DIR", vol->mount_point);
+        if (access(lost_path, F_OK)) {
+            /*
+             * Create a LOST.DIR in the root so we have somewhere to put
+             * lost cluster chains (fsck_msdos doesn't currently do this)
+             */
+            if (mkdir(lost_path, 0755)) {
+                LOGE("Unable to create LOST.DIR (%s)", strerror(errno));
+            }
+        }
+        free(lost_path);
+    }
+
 #if VFAT_DEBUG
     LOG_VOL("vfat_mount(%s, %d:%d): mount rc = %d", dev->major,k dev->minor,
             vol->mount_point, rc);