unmount cache before paving it over with the radio/hboot image

Try to unmount the cache.  If that fails, try to remount it read-only
and sync (which isn't as safe but is better than leaving it r/w).  If
we can't even do that, abort the firmware installation.

Change-Id: I2ebb1ebf3d1f58270133c58b0e9337fb33d78dfa
diff --git a/updater/recovery_updater.c b/updater/recovery_updater.c
index d382f96..b7df23a 100644
--- a/updater/recovery_updater.c
+++ b/updater/recovery_updater.c
@@ -14,16 +14,20 @@
  * limitations under the License.
  */
 
-#include <stdio.h>
 #include <errno.h>
 #include <stdarg.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
+#include <unistd.h>
 
-#include "mincrypt/sha.h"
 #include "edify/expr.h"
 #include "firmware.h"
+#include "mincrypt/sha.h"
+#include "minzip/Zip.h"
+#include "mtdutils/mounts.h"
+#include "updater/updater.h"
 
 Value* UpdateFn(const char* name, State* state, int argc, Expr* argv[]) {
     if (argc != 7) {
@@ -50,6 +54,35 @@
         return NULL;
     }
 
+    // close the package
+    ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip;
+    mzCloseZipArchive(za);
+    ((UpdaterInfo*)(state->cookie))->package_zip = NULL;
+
+    // Try to unmount /cache.  If we fail (because we're running in an
+    // older recovery that still has the package file open), try to
+    // remount it read-only.  If that fails, abort.
+    sync();
+    scan_mounted_volumes();
+    MountedVolume* vol = find_mounted_volume_by_mount_point("/cache");
+    int result = unmount_mounted_volume(vol);
+    if (result != 0) {
+        printf("%s(): failed to unmount cache (%d: %s)\n",
+               name, result, strerror(errno));
+
+        result = remount_read_only(vol);
+        if (result != 0) {
+            printf("%s(): failed to remount cache (%d: %s)\n",
+                   name, result, strerror(errno));
+            return StringValue(strdup(""));
+        } else {
+            printf("%s(): remounted cache\n", name);
+        }
+        sync();
+    } else {
+        printf("%s(): unmounted cache\n", name);
+    }
+
     int width = 0, height = 0, bpp = 0;
 
     if (width_string->type != VAL_STRING ||