From 6957555e295e8ae34ba5e8cfbfb1c7bd76b0024d Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Tue, 16 May 2017 15:51:46 -0700 Subject: [PATCH] Retry the update if ApplyBSDiffPatch | ApplyImagePatch fails We have seen one case when bspatch failed likely due to patch corruption. Since the package has passed verification before, we want to reboot and retry the patch command again since there's no alternative for users. We won't delete the stash before reboot, and the src has passed SHA1 check. If there's an error on the patch, it will fail the package verification during retry. Bug: 37855643 Test: angler reboots and retries the update when bspatch fails. Change-Id: I2ebac9621bd1f0649bb301b9a28a0dd079ed4e1d --- error_code.h | 1 + recovery.cpp | 9 +++++---- updater/blockimg.cpp | 2 ++ updater/updater.cpp | 4 ++++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/error_code.h b/error_code.h index 0e79c87c..9fe047c9 100644 --- a/error_code.h +++ b/error_code.h @@ -44,6 +44,7 @@ enum CauseCode { kTune2FsFailure, kRebootFailure, kPackageExtractFileFailure, + kPatchApplicationFailure, kVendorFailure = 200 }; diff --git a/recovery.cpp b/recovery.cpp index dfae7f03..122b89d0 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -112,8 +112,9 @@ static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log"; 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"; -// We will try to apply the update package 5 times at most in case of an I/O error. -static const int EIO_RETRY_COUNT = 4; +// We will try to apply the update package 5 times at most in case of an I/O error or +// bspatch | imgpatch error. +static const int RETRY_LIMIT = 4; 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. @@ -1530,9 +1531,9 @@ 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 + // When I/O error happens, reboot and retry installation RETRY_LIMIT // times before we abandon this OTA update. - if (status == INSTALL_RETRY && retry_count < EIO_RETRY_COUNT) { + if (status == INSTALL_RETRY && retry_count < RETRY_LIMIT) { copy_logs(); set_retry_bootloader_message(retry_count, args); // Print retry count on screen. diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp index d5c17047..df366b0b 100644 --- a/updater/blockimg.cpp +++ b/updater/blockimg.cpp @@ -1213,6 +1213,7 @@ static int PerformCommandDiff(CommandParameters& params) { std::placeholders::_2), nullptr, nullptr) != 0) { LOG(ERROR) << "Failed to apply image patch."; + failure_type = kPatchApplicationFailure; return -1; } } else { @@ -1221,6 +1222,7 @@ static int PerformCommandDiff(CommandParameters& params) { std::placeholders::_2), nullptr) != 0) { LOG(ERROR) << "Failed to apply bsdiff patch."; + failure_type = kPatchApplicationFailure; return -1; } } diff --git a/updater/updater.cpp b/updater/updater.cpp index 1be8b604..f5ff6df9 100644 --- a/updater/updater.cpp +++ b/updater/updater.cpp @@ -202,6 +202,10 @@ int main(int argc, char** argv) { // Cause code should provide additional information about the abort. if (state.cause_code != kNoCause) { fprintf(cmd_pipe, "log cause: %d\n", state.cause_code); + if (state.cause_code == kPatchApplicationFailure) { + LOG(INFO) << "Patch application failed, retry update."; + fprintf(cmd_pipe, "retry_update\n"); + } } if (updater_info.package_zip) {