summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk9
-rw-r--r--applypatch/Android.mk64
-rw-r--r--applypatch/applypatch.cpp2
-rw-r--r--applypatch/bspatch.cpp2
-rw-r--r--applypatch/freecache.cpp2
-rw-r--r--applypatch/imgpatch.cpp2
-rw-r--r--applypatch/include/applypatch/applypatch.h (renamed from applypatch/applypatch.h)0
-rw-r--r--applypatch/main.cpp2
-rw-r--r--etc/init.rc3
-rw-r--r--install.cpp6
-rw-r--r--install.h3
-rw-r--r--minui/graphics_fbdev.cpp12
-rw-r--r--otafault/Android.mk13
-rw-r--r--otafault/ota_io.cpp37
-rw-r--r--recovery.cpp86
-rw-r--r--updater/Android.mk66
-rw-r--r--updater/updater.cpp7
17 files changed, 227 insertions, 89 deletions
diff --git a/Android.mk b/Android.mk
index 4477fefe3..fc981e12d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,18 +14,20 @@
LOCAL_PATH := $(call my-dir)
+# libfusesideload (static library)
+# ===============================
include $(CLEAR_VARS)
LOCAL_SRC_FILES := fuse_sideload.cpp
LOCAL_CLANG := true
LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
-
LOCAL_MODULE := libfusesideload
-
LOCAL_STATIC_LIBRARIES := libcutils libc libmincrypt
include $(BUILD_STATIC_LIBRARY)
+# recovery (static executable)
+# ===============================
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
@@ -102,7 +104,8 @@ endif
include $(BUILD_EXECUTABLE)
-# All the APIs for testing
+# libverifier (static library)
+# ===============================
include $(CLEAR_VARS)
LOCAL_CLANG := true
LOCAL_MODULE := libverifier
diff --git a/applypatch/Android.mk b/applypatch/Android.mk
index 90a86dcb0..9e64718c1 100644
--- a/applypatch/Android.mk
+++ b/applypatch/Android.mk
@@ -14,59 +14,83 @@
LOCAL_PATH := $(call my-dir)
+# libapplypatch (static library)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
-LOCAL_SRC_FILES := applypatch.cpp bspatch.cpp freecache.cpp imgpatch.cpp utils.cpp
+LOCAL_SRC_FILES := \
+ applypatch.cpp \
+ bspatch.cpp \
+ freecache.cpp \
+ imgpatch.cpp \
+ utils.cpp
LOCAL_MODULE := libapplypatch
LOCAL_MODULE_TAGS := eng
-LOCAL_C_INCLUDES += bootable/recovery
-LOCAL_STATIC_LIBRARIES += libbase libotafault libmtdutils libcrypto_static libbz libz
-
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/include \
+ bootable/recovery
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_STATIC_LIBRARIES += \
+ libotafault \
+ libmtdutils \
+ libbase \
+ libcrypto_static \
+ libbz \
+ libz
include $(BUILD_STATIC_LIBRARY)
+# libimgpatch (static library)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
LOCAL_SRC_FILES := bspatch.cpp imgpatch.cpp utils.cpp
LOCAL_MODULE := libimgpatch
-LOCAL_C_INCLUDES += bootable/recovery
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/include \
+ bootable/recovery
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_STATIC_LIBRARIES += libcrypto_static libbz libz
-
include $(BUILD_STATIC_LIBRARY)
-ifeq ($(HOST_OS),linux)
+# libimgpatch (host static library)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
LOCAL_SRC_FILES := bspatch.cpp imgpatch.cpp utils.cpp
LOCAL_MODULE := libimgpatch
-LOCAL_C_INCLUDES += bootable/recovery
+LOCAL_MODULE_HOST_OS := linux
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/include \
+ bootable/recovery
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_STATIC_LIBRARIES += libcrypto_static libbz libz
-
include $(BUILD_HOST_STATIC_LIBRARY)
-endif # HOST_OS == linux
+# applypatch (executable)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
LOCAL_SRC_FILES := main.cpp
LOCAL_MODULE := applypatch
LOCAL_C_INCLUDES += bootable/recovery
-LOCAL_STATIC_LIBRARIES += libapplypatch libbase libotafault libmtdutils libcrypto_static libbz libedify
+LOCAL_STATIC_LIBRARIES += \
+ libapplypatch \
+ libbase \
+ libedify \
+ libotafault \
+ libminzip \
+ libmtdutils \
+ libcrypto_static \
+ libbz
LOCAL_SHARED_LIBRARIES += libz libcutils libc
-
include $(BUILD_EXECUTABLE)
+# imgdiff (host static executable)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
LOCAL_SRC_FILES := imgdiff.cpp utils.cpp bsdiff.cpp
LOCAL_MODULE := imgdiff
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_C_INCLUDES += external/zlib external/bzip2
LOCAL_STATIC_LIBRARIES += libz libbz
-
+LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_HOST_EXECUTABLE)
diff --git a/applypatch/applypatch.cpp b/applypatch/applypatch.cpp
index 644515997..c8594c283 100644
--- a/applypatch/applypatch.cpp
+++ b/applypatch/applypatch.cpp
@@ -31,7 +31,7 @@
#include <android-base/strings.h>
#include "openssl/sha.h"
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
#include "mtdutils/mtdutils.h"
#include "edify/expr.h"
#include "ota_io.h"
diff --git a/applypatch/bspatch.cpp b/applypatch/bspatch.cpp
index 1fc1455a6..a4945da28 100644
--- a/applypatch/bspatch.cpp
+++ b/applypatch/bspatch.cpp
@@ -30,7 +30,7 @@
#include <bzlib.h>
#include "openssl/sha.h"
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
void ShowBSDiffLicense() {
puts("The bsdiff library used herein is:\n"
diff --git a/applypatch/freecache.cpp b/applypatch/freecache.cpp
index c84f42797..331cae265 100644
--- a/applypatch/freecache.cpp
+++ b/applypatch/freecache.cpp
@@ -32,7 +32,7 @@
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
static int EliminateOpenFiles(std::set<std::string>* files) {
std::unique_ptr<DIR, decltype(&closedir)> d(opendir("/proc"), closedir);
diff --git a/applypatch/imgpatch.cpp b/applypatch/imgpatch.cpp
index 0ab995b30..4251c0120 100644
--- a/applypatch/imgpatch.cpp
+++ b/applypatch/imgpatch.cpp
@@ -28,7 +28,7 @@
#include "zlib.h"
#include "openssl/sha.h"
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
#include "imgdiff.h"
#include "utils.h"
diff --git a/applypatch/applypatch.h b/applypatch/include/applypatch/applypatch.h
index 9ee39d293..9ee39d293 100644
--- a/applypatch/applypatch.h
+++ b/applypatch/include/applypatch/applypatch.h
diff --git a/applypatch/main.cpp b/applypatch/main.cpp
index 9013760c4..0ff8cbf9a 100644
--- a/applypatch/main.cpp
+++ b/applypatch/main.cpp
@@ -22,7 +22,7 @@
#include <memory>
#include <vector>
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
#include "edify/expr.h"
#include "openssl/sha.h"
diff --git a/etc/init.rc b/etc/init.rc
index dc1865986..5915b8d80 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -1,6 +1,9 @@
import /init.recovery.${ro.hardware}.rc
on early-init
+ # Set the security context of /postinstall if present.
+ restorecon /postinstall
+
start ueventd
start healthd
diff --git a/install.cpp b/install.cpp
index 33c1f5498..144a353d6 100644
--- a/install.cpp
+++ b/install.cpp
@@ -144,6 +144,7 @@ try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache) {
close(pipefd[1]);
*wipe_cache = false;
+ bool retry_update = false;
char buffer[1024];
FILE* from_child = fdopen(pipefd[0], "r");
@@ -180,6 +181,8 @@ try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache) {
// to be able to reboot during installation (useful for
// debugging packages that don't exit).
ui->SetEnableReboot(true);
+ } else if (strcmp(command, "retry_update") == 0) {
+ retry_update = true;
} else {
LOGE("unknown command [%s]\n", command);
}
@@ -188,6 +191,9 @@ try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache) {
int status;
waitpid(pid, &status, 0);
+ if (retry_update) {
+ return INSTALL_RETRY;
+ }
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
LOGE("Error in %s\n(Status %d)\n", path, WEXITSTATUS(status));
return INSTALL_ERROR;
diff --git a/install.h b/install.h
index f92f061df..fd08e3c49 100644
--- a/install.h
+++ b/install.h
@@ -23,7 +23,8 @@
extern "C" {
#endif
-enum { INSTALL_SUCCESS, INSTALL_ERROR, INSTALL_CORRUPT, INSTALL_NONE, INSTALL_SKIPPED };
+enum { INSTALL_SUCCESS, INSTALL_ERROR, INSTALL_CORRUPT, INSTALL_NONE, INSTALL_SKIPPED,
+ INSTALL_RETRY };
// Install the package specified by root_path. If INSTALL_SUCCESS is
// returned and *wipe_cache is true on exit, caller should wipe the
// cache partition.
diff --git a/minui/graphics_fbdev.cpp b/minui/graphics_fbdev.cpp
index 997e9cac2..0788f7552 100644
--- a/minui/graphics_fbdev.cpp
+++ b/minui/graphics_fbdev.cpp
@@ -176,18 +176,6 @@ static GRSurface* fbdev_init(minui_backend* backend) {
static GRSurface* fbdev_flip(minui_backend* backend __unused) {
if (double_buffered) {
-#if defined(RECOVERY_BGRA)
- // In case of BGRA, do some byte swapping
- unsigned int idx;
- unsigned char tmp;
- unsigned char* ucfb_vaddr = (unsigned char*)gr_draw->data;
- for (idx = 0 ; idx < (gr_draw->height * gr_draw->row_bytes);
- idx += 4) {
- tmp = ucfb_vaddr[idx];
- ucfb_vaddr[idx ] = ucfb_vaddr[idx + 2];
- ucfb_vaddr[idx + 2] = tmp;
- }
-#endif
// Change gr_draw to point to the buffer currently displayed,
// then flip the driver so we're displaying the other buffer
// instead.
diff --git a/otafault/Android.mk b/otafault/Android.mk
index 7468de6c4..52d706722 100644
--- a/otafault/Android.mk
+++ b/otafault/Android.mk
@@ -14,29 +14,34 @@
LOCAL_PATH := $(call my-dir)
+# otafault (static library)
+# ===============================
include $(CLEAR_VARS)
otafault_static_libs := \
libminzip \
- libz \
libselinux \
+ libz
LOCAL_SRC_FILES := config.cpp ota_io.cpp
-LOCAL_MODULE_TAGS := eng
LOCAL_MODULE := libotafault
LOCAL_CLANG := true
LOCAL_C_INCLUDES := bootable/recovery
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-LOCAL_WHOLE_STATIC_LIBRARIES := $(otafault_static_libs)
+LOCAL_STATIC_LIBRARIES := $(otafault_static_libs)
include $(BUILD_STATIC_LIBRARY)
+# otafault_test (static executable)
+# ===============================
include $(CLEAR_VARS)
LOCAL_SRC_FILES := config.cpp ota_io.cpp test.cpp
LOCAL_MODULE_TAGS := tests
LOCAL_MODULE := otafault_test
-LOCAL_STATIC_LIBRARIES := $(otafault_static_libs)
+LOCAL_STATIC_LIBRARIES := \
+ libotafault \
+ $(otafault_static_libs)
LOCAL_C_INCLUDES := bootable/recovery
LOCAL_FORCE_STATIC_EXECUTABLE := true
diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp
index 2ce3dfcc2..dd805e56e 100644
--- a/otafault/ota_io.cpp
+++ b/otafault/ota_io.cpp
@@ -29,6 +29,7 @@ static std::map<intptr_t, const char*> filename_cache;
static std::string read_fault_file_name = "";
static std::string write_fault_file_name = "";
static std::string fsync_fault_file_name = "";
+bool have_eio_error = false;
static bool get_hit_file(const char* cached_path, std::string ffn) {
return should_hit_cache()
@@ -85,10 +86,16 @@ size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream) {
get_hit_file(cached_path, read_fault_file_name)) {
read_fault_file_name = "";
errno = EIO;
+ have_eio_error = true;
return 0;
}
}
- return fread(ptr, size, nitems, stream);
+ size_t status = fread(ptr, size, nitems, stream);
+ // If I/O error occurs, set the retry-update flag.
+ if (status != nitems && errno == EIO) {
+ have_eio_error = true;
+ }
+ return status;
}
ssize_t ota_read(int fd, void* buf, size_t nbyte) {
@@ -99,10 +106,15 @@ ssize_t ota_read(int fd, void* buf, size_t nbyte) {
&& get_hit_file(cached_path, read_fault_file_name)) {
read_fault_file_name = "";
errno = EIO;
+ have_eio_error = true;
return -1;
}
}
- return read(fd, buf, nbyte);
+ ssize_t status = read(fd, buf, nbyte);
+ if (status == -1 && errno == EIO) {
+ have_eio_error = true;
+ }
+ return status;
}
size_t ota_fwrite(const void* ptr, size_t size, size_t count, FILE* stream) {
@@ -113,10 +125,15 @@ size_t ota_fwrite(const void* ptr, size_t size, size_t count, FILE* stream) {
get_hit_file(cached_path, write_fault_file_name)) {
write_fault_file_name = "";
errno = EIO;
+ have_eio_error = true;
return 0;
}
}
- return fwrite(ptr, size, count, stream);
+ size_t status = fwrite(ptr, size, count, stream);
+ if (status != count && errno == EIO) {
+ have_eio_error = true;
+ }
+ return status;
}
ssize_t ota_write(int fd, const void* buf, size_t nbyte) {
@@ -127,10 +144,15 @@ ssize_t ota_write(int fd, const void* buf, size_t nbyte) {
get_hit_file(cached_path, write_fault_file_name)) {
write_fault_file_name = "";
errno = EIO;
+ have_eio_error = true;
return -1;
}
}
- return write(fd, buf, nbyte);
+ ssize_t status = write(fd, buf, nbyte);
+ if (status == -1 && errno == EIO) {
+ have_eio_error = true;
+ }
+ return status;
}
int ota_fsync(int fd) {
@@ -141,9 +163,14 @@ int ota_fsync(int fd) {
get_hit_file(cached_path, fsync_fault_file_name)) {
fsync_fault_file_name = "";
errno = EIO;
+ have_eio_error = true;
return -1;
}
}
- return fsync(fd);
+ int status = fsync(fd);
+ if (status == -1 && errno == EIO) {
+ have_eio_error = true;
+ }
+ return status;
}
diff --git a/recovery.cpp b/recovery.cpp
index 3ce218548..6781fa4b4 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -36,6 +36,7 @@
#include <adb.h>
#include <android-base/file.h>
+#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <cutils/android_reboot.h>
#include <cutils/properties.h>
@@ -60,6 +61,7 @@ struct selabel_handle *sehandle;
static const struct option OPTIONS[] = {
{ "send_intent", required_argument, NULL, 'i' },
{ "update_package", required_argument, NULL, 'u' },
+ { "retry_count", required_argument, NULL, 'n' },
{ "wipe_data", no_argument, NULL, 'w' },
{ "wipe_cache", no_argument, NULL, 'c' },
{ "show_text", no_argument, NULL, 't' },
@@ -86,6 +88,7 @@ static const char *TEMPORARY_INSTALL_FILE = "/tmp/last_install";
static const char *LAST_KMSG_FILE = "/cache/recovery/last_kmsg";
static const char *LAST_LOG_FILE = "/cache/recovery/last_log";
static const int KEEP_LOG_COUNT = 10;
+static const int EIO_RETRY_COUNT = 2;
static const int BATTERY_READ_TIMEOUT_IN_SEC = 10;
// GmsCore enters recovery mode to install package when having enough battery
// percentage. Normally, the threshold is 40% without charger and 20% with charger.
@@ -98,6 +101,7 @@ char* locale = NULL;
char* stage = NULL;
char* reason = NULL;
bool modified_flash = false;
+static bool has_cache = false;
/*
* The recovery tool communicates with the main system through /cache files.
@@ -310,8 +314,8 @@ get_args(int *argc, char ***argv) {
}
}
- // --- if that doesn't work, try the command file
- if (*argc <= 1) {
+ // --- if that doesn't work, try the command file (if we have /cache).
+ if (*argc <= 1 && has_cache) {
FILE *fp = fopen_path(COMMAND_FILE, "r");
if (fp != NULL) {
char *token;
@@ -433,6 +437,11 @@ static void rotate_logs(int max) {
}
static void copy_logs() {
+ // We can do nothing for now if there's no /cache partition.
+ if (!has_cache) {
+ return;
+ }
+
// We only rotate and record the log of the current session if there are
// actual attempts to modify the flash, such as wipes, installs from BCB
// or menu selections. This is to avoid unnecessary rotation (and
@@ -464,7 +473,7 @@ static void copy_logs() {
static void
finish_recovery(const char *send_intent) {
// By this point, we're ready to return to the main system...
- if (send_intent != NULL) {
+ if (send_intent != NULL && has_cache) {
FILE *fp = fopen_path(INTENT_FILE, "w");
if (fp == NULL) {
LOGE("Can't open %s\n", INTENT_FILE);
@@ -477,7 +486,7 @@ finish_recovery(const char *send_intent) {
// Save the locale to cache, so if recovery is next started up
// without a --locale argument (eg, directly from the bootloader)
// it will use the last-known locale.
- if (locale != NULL) {
+ if (locale != NULL && has_cache) {
LOGI("Saving locale \"%s\"\n", locale);
FILE* fp = fopen_path(LOCALE_FILE, "w");
fwrite(locale, 1, strlen(locale), fp);
@@ -494,12 +503,13 @@ finish_recovery(const char *send_intent) {
set_bootloader_message(&boot);
// Remove the command file, so recovery won't repeat indefinitely.
- if (ensure_path_mounted(COMMAND_FILE) != 0 ||
- (unlink(COMMAND_FILE) && errno != ENOENT)) {
- LOGW("Can't unlink %s\n", COMMAND_FILE);
+ if (has_cache) {
+ if (ensure_path_mounted(COMMAND_FILE) != 0 || (unlink(COMMAND_FILE) && errno != ENOENT)) {
+ LOGW("Can't unlink %s\n", COMMAND_FILE);
+ }
+ ensure_path_unmounted(CACHE_ROOT);
}
- ensure_path_unmounted(CACHE_ROOT);
sync(); // For good measure.
}
@@ -768,7 +778,7 @@ static bool wipe_data(int should_confirm, Device* device) {
bool success =
device->PreWipeData() &&
erase_volume("/data") &&
- erase_volume("/cache") &&
+ (has_cache ? erase_volume("/cache") : true) &&
device->PostWipeData();
ui->Print("Data wipe %s.\n", success ? "complete" : "failed");
return success;
@@ -776,6 +786,11 @@ static bool wipe_data(int should_confirm, Device* device) {
// Return true on success.
static bool wipe_cache(bool should_confirm, Device* device) {
+ if (!has_cache) {
+ ui->Print("No /cache partition found.\n");
+ return false;
+ }
+
if (should_confirm && !yes_no(device, "Wipe cache?", " THIS CAN NOT BE UNDONE!")) {
return false;
}
@@ -789,6 +804,11 @@ static bool wipe_cache(bool should_confirm, Device* device) {
}
static void choose_recovery_file(Device* device) {
+ if (!has_cache) {
+ ui->Print("No /cache partition found.\n");
+ return;
+ }
+
// "Back" + KEEP_LOG_COUNT * 2 + terminating nullptr entry
char* entries[1 + KEEP_LOG_COUNT * 2 + 1];
memset(entries, 0, sizeof(entries));
@@ -1120,6 +1140,29 @@ static bool is_battery_ok() {
}
}
+static void set_retry_bootloader_message(int retry_count, int argc, char** argv) {
+ struct bootloader_message boot {};
+ strlcpy(boot.command, "boot-recovery", sizeof(boot.command));
+ strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery));
+
+ for (int i = 1; i < argc; ++i) {
+ if (strstr(argv[i], "retry_count") == nullptr) {
+ strlcat(boot.recovery, argv[i], sizeof(boot.recovery));
+ strlcat(boot.recovery, "\n", sizeof(boot.recovery));
+ }
+ }
+
+ // Initialize counter to 1 if it's not in BCB, otherwise increment it by 1.
+ if (retry_count == 0) {
+ strlcat(boot.recovery, "--retry_count=1\n", sizeof(boot.recovery));
+ } else {
+ char buffer[20];
+ snprintf(buffer, sizeof(buffer), "--retry_count=%d\n", retry_count+1);
+ strlcat(boot.recovery, buffer, sizeof(boot.recovery));
+ }
+ set_bootloader_message(&boot);
+}
+
int main(int argc, char **argv) {
// If this binary is started with the single argument "--adbd",
// instead of being the normal recovery binary, it turns into kind
@@ -1142,6 +1185,8 @@ int main(int argc, char **argv) {
printf("Starting recovery (pid %d) on %s", getpid(), ctime(&start));
load_volume_table();
+ has_cache = volume_for_path(CACHE_ROOT) != nullptr;
+
get_args(&argc, &argv);
const char *send_intent = NULL;
@@ -1153,11 +1198,13 @@ int main(int argc, char **argv) {
bool sideload_auto_reboot = false;
bool just_exit = false;
bool shutdown_after = false;
+ int retry_count = 0;
int arg;
while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
switch (arg) {
case 'i': send_intent = optarg; break;
+ case 'n': android::base::ParseInt(optarg, &retry_count, 0); break;
case 'u': update_package = optarg; break;
case 'w': should_wipe_data = true; break;
case 'c': should_wipe_cache = true; break;
@@ -1182,7 +1229,7 @@ int main(int argc, char **argv) {
}
}
- if (locale == NULL) {
+ if (locale == nullptr && has_cache) {
load_locale_from_cache();
}
printf("locale is [%s]\n", locale);
@@ -1262,7 +1309,24 @@ int main(int argc, char **argv) {
}
if (status != INSTALL_SUCCESS) {
ui->Print("Installation aborted.\n");
-
+ // When I/O error happens, reboot and retry installation EIO_RETRY_COUNT
+ // times before we abandon this OTA update.
+ if (status == INSTALL_RETRY && retry_count < EIO_RETRY_COUNT) {
+ copy_logs();
+ set_retry_bootloader_message(retry_count, argc, argv);
+ // Print retry count on screen.
+ ui->Print("Retry attempt %d\n", retry_count);
+
+ // Reboot and retry the update
+ int ret = property_set(ANDROID_RB_PROPERTY, "reboot,recovery");
+ if (ret < 0) {
+ ui->Print("Reboot failed\n");
+ } else {
+ while (true) {
+ pause();
+ }
+ }
+ }
// If this is an eng or userdebug build, then automatically
// turn the text display on if the script fails so the error
// message is visible.
diff --git a/updater/Android.mk b/updater/Android.mk
index d7aa613e9..47c56ccd9 100644
--- a/updater/Android.mk
+++ b/updater/Android.mk
@@ -14,26 +14,50 @@
LOCAL_PATH := $(call my-dir)
-updater_src_files := \
- install.cpp \
- blockimg.cpp \
- updater.cpp
-
-#
-# Build a statically-linked binary to include in OTA packages
-#
+# updater (static executable)
+# ===============================
+# Build a statically-linked binary to include in OTA packages.
include $(CLEAR_VARS)
-# Build only in eng, so we don't end up with a copy of this in /system
-# on user builds. (TODO: find a better way to build device binaries
-# needed only for OTA packages.)
-LOCAL_MODULE_TAGS := eng
+updater_src_files := \
+ install.cpp \
+ blockimg.cpp \
+ updater.cpp
LOCAL_CLANG := true
-
LOCAL_SRC_FILES := $(updater_src_files)
-LOCAL_STATIC_LIBRARIES += libfec libfec_rs libext4_utils_static libsquashfs_utils libcrypto_static
+LOCAL_STATIC_LIBRARIES += \
+ $(TARGET_RECOVERY_UPDATER_LIBS) \
+ $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) \
+ libfec \
+ libfec_rs \
+ libext4_utils_static \
+ libsquashfs_utils \
+ libcrypto_static \
+ libapplypatch \
+ libbase \
+ libotafault \
+ libedify \
+ libmtdutils \
+ libminzip \
+ libz \
+ libbz \
+ libcutils \
+ liblog \
+ libselinux
+
+tune2fs_static_libraries := \
+ libext2_com_err \
+ libext2_blkid \
+ libext2_quota \
+ libext2_uuid_static \
+ libext2_e2p \
+ libext2fs
+
+LOCAL_STATIC_LIBRARIES += \
+ libtune2fs \
+ $(tune2fs_static_libraries)
ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
LOCAL_CFLAGS += -DUSE_EXT4
@@ -44,20 +68,6 @@ LOCAL_STATIC_LIBRARIES += \
libz
endif
-LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS)
-LOCAL_STATIC_LIBRARIES += libapplypatch libbase libotafault libedify libmtdutils libminzip libz
-LOCAL_STATIC_LIBRARIES += libbz
-LOCAL_STATIC_LIBRARIES += libcutils liblog libc
-LOCAL_STATIC_LIBRARIES += libselinux
-tune2fs_static_libraries := \
- libext2_com_err \
- libext2_blkid \
- libext2_quota \
- libext2_uuid_static \
- libext2_e2p \
- libext2fs
-LOCAL_STATIC_LIBRARIES += libtune2fs $(tune2fs_static_libraries)
-
LOCAL_C_INCLUDES += external/e2fsprogs/misc
LOCAL_C_INCLUDES += $(LOCAL_PATH)/..
diff --git a/updater/updater.cpp b/updater/updater.cpp
index efb4a8cec..1693fa1db 100644
--- a/updater/updater.cpp
+++ b/updater/updater.cpp
@@ -36,6 +36,8 @@
// (Note it's "updateR-script", not the older "update-script".)
#define SCRIPT_NAME "META-INF/com/google/android/updater-script"
+extern bool have_eio_error;
+
struct selabel_handle *sehandle;
int main(int argc, char** argv) {
@@ -141,6 +143,11 @@ int main(int argc, char** argv) {
state.errmsg = NULL;
char* result = Evaluate(&state, root);
+
+ if (have_eio_error) {
+ fprintf(cmd_pipe, "retry_update\n");
+ }
+
if (result == NULL) {
if (state.errmsg == NULL) {
printf("script aborted (no error message)\n");