Merge "Rename language+country resources to just language"
diff --git a/Android.mk b/Android.mk
index 2943f01..633f18d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -76,8 +76,8 @@
 LOCAL_STATIC_LIBRARIES := \
     libbatterymonitor \
     libbootloader_message \
-    libext4_utils_static \
-    libsparse_static \
+    libext4_utils \
+    libsparse \
     libziparchive \
     libotautil \
     libmounts \
diff --git a/minadbd/README.txt b/minadbd/README.md
similarity index 79%
rename from minadbd/README.txt
rename to minadbd/README.md
index e69dc87..5a0a067 100644
--- a/minadbd/README.txt
+++ b/minadbd/README.md
@@ -3,6 +3,6 @@
 
   - all services removed
   - all host mode support removed
-  - sideload_service() added; this is the only service supported.  It
+  - `sideload_service()` added; this is the only service supported. It
     receives a single blob of data, writes it to a fixed filename, and
     makes the process exit.
diff --git a/otafault/config.cpp b/otafault/config.cpp
index ee4ef89..8590833 100644
--- a/otafault/config.cpp
+++ b/otafault/config.cpp
@@ -29,21 +29,23 @@
 #define OTAIO_MAX_FNAME_SIZE 128
 
 static ZipArchiveHandle archive;
+static bool is_retry = false;
 static std::map<std::string, bool> should_inject_cache;
 
 static std::string get_type_path(const char* io_type) {
     return android::base::StringPrintf("%s/%s", OTAIO_BASE_DIR, io_type);
 }
 
-void ota_io_init(ZipArchiveHandle za) {
+void ota_io_init(ZipArchiveHandle za, bool retry) {
     archive = za;
+    is_retry = retry;
     ota_set_fault_files();
 }
 
 bool should_fault_inject(const char* io_type) {
     // archive will be NULL if we used an entry point other
     // than updater/updater.cpp:main
-    if (archive == NULL) {
+    if (archive == nullptr || is_retry) {
         return false;
     }
     const std::string type_path = get_type_path(io_type);
diff --git a/otafault/config.h b/otafault/config.h
index c048617..4adbdd1 100644
--- a/otafault/config.h
+++ b/otafault/config.h
@@ -52,7 +52,7 @@
 /*
  * Initialize libotafault by providing a reference to the OTA package.
  */
-void ota_io_init(ZipArchiveHandle zip);
+void ota_io_init(ZipArchiveHandle zip, bool retry);
 
 /*
  * Return true if a config file is present for the given IO type.
diff --git a/recovery.cpp b/recovery.cpp
index 5888c54..fac241d 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -322,7 +322,7 @@
   std::vector<std::string> args(argv, argv + argc);
 
   // --- if arguments weren't supplied, look in the bootloader control block
-  if (argc == 1) {
+  if (args.size() == 1) {
     boot.recovery[sizeof(boot.recovery) - 1] = '\0';  // Ensure termination
     std::string boot_recovery(boot.recovery);
     std::vector<std::string> tokens = android::base::Split(boot_recovery, "\n");
@@ -338,7 +338,7 @@
   }
 
   // --- if that doesn't work, try the command file (if we have /cache).
-  if (argc == 1 && has_cache) {
+  if (args.size() == 1 && has_cache) {
     std::string content;
     if (ensure_path_mounted(COMMAND_FILE) == 0 &&
         android::base::ReadFileToString(COMMAND_FILE, &content)) {
diff --git a/tests/Android.mk b/tests/Android.mk
index 0aca8c6..1203817 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -99,8 +99,8 @@
     libfs_mgr \
     liblog \
     libselinux \
-    libext4_utils_static \
-    libsparse_static \
+    libext4_utils \
+    libsparse \
     libcrypto_utils \
     libcrypto \
     libcutils \
diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp
index 5973076..4f5b2f8 100644
--- a/uncrypt/uncrypt.cpp
+++ b/uncrypt/uncrypt.cpp
@@ -118,7 +118,8 @@
 
 #include "error_code.h"
 
-#define WINDOW_SIZE 5
+static constexpr int WINDOW_SIZE = 5;
+static constexpr int FIBMAP_RETRY_LIMIT = 3;
 
 // uncrypt provides three services: SETUP_BCB, CLEAR_BCB and UNCRYPT.
 //
@@ -233,6 +234,26 @@
     return true;
 }
 
+static int retry_fibmap(const int fd, const char* name, int* block, const int head_block) {
+    CHECK(block != nullptr);
+    for (size_t i = 0; i < FIBMAP_RETRY_LIMIT; i++) {
+        if (fsync(fd) == -1) {
+            PLOG(ERROR) << "failed to fsync \"" << name << "\"";
+            return kUncryptFileSyncError;
+        }
+        if (ioctl(fd, FIBMAP, block) != 0) {
+            PLOG(ERROR) << "failed to find block " << head_block;
+            return kUncryptIoctlError;
+        }
+        if (*block != 0) {
+            return kUncryptNoError;
+        }
+        sleep(1);
+    }
+    LOG(ERROR) << "fibmap of " << head_block << "always returns 0";
+    return kUncryptIoctlError;
+}
+
 static int produce_block_map(const char* path, const char* map_file, const char* blk_dev,
                              bool encrypted, int socket) {
     std::string err;
@@ -314,6 +335,15 @@
                 PLOG(ERROR) << "failed to find block " << head_block;
                 return kUncryptIoctlError;
             }
+
+            if (block == 0) {
+                LOG(ERROR) << "failed to find block " << head_block << ", retrying";
+                int error = retry_fibmap(fd, path, &block, head_block);
+                if (error != kUncryptNoError) {
+                    return error;
+                }
+            }
+
             add_block_to_ranges(ranges, block);
             if (encrypted) {
                 if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
@@ -350,6 +380,15 @@
             PLOG(ERROR) << "failed to find block " << head_block;
             return kUncryptIoctlError;
         }
+
+        if (block == 0) {
+            LOG(ERROR) << "failed to find block " << head_block << ", retrying";
+            int error = retry_fibmap(fd, path, &block, head_block);
+            if (error != kUncryptNoError) {
+                return error;
+            }
+        }
+
         add_block_to_ranges(ranges, block);
         if (encrypted) {
             if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
diff --git a/updater/Android.mk b/updater/Android.mk
index 5d328a3..d8a84c2 100644
--- a/updater/Android.mk
+++ b/updater/Android.mk
@@ -31,13 +31,13 @@
     libutils \
     libmounts \
     libotafault \
-    libext4_utils_static \
+    libext4_utils \
     libfec \
     libfec_rs \
     libfs_mgr \
     liblog \
     libselinux \
-    libsparse_static \
+    libsparse \
     libsquashfs_utils \
     libbz \
     libz \
diff --git a/updater/updater.cpp b/updater/updater.cpp
index 3e624da..4730662 100644
--- a/updater/updater.cpp
+++ b/updater/updater.cpp
@@ -100,7 +100,6 @@
     CloseArchive(za);
     return 3;
   }
-  ota_io_init(za);
 
   ZipString script_name(SCRIPT_NAME);
   ZipEntry script_entry;
@@ -166,6 +165,7 @@
       printf("unexpected argument: %s", argv[4]);
     }
   }
+  ota_io_init(za, state.is_retry);
 
   std::string result;
   bool status = Evaluate(&state, root, &result);