diff options
Diffstat (limited to '')
-rw-r--r-- | updater/Android.mk | 67 | ||||
-rw-r--r-- | updater/blockimg.cpp | 98 | ||||
-rw-r--r-- | updater/install.cpp | 26 | ||||
-rw-r--r-- | updater/updater.cpp | 12 | ||||
-rw-r--r-- | updater/updater.h | 4 |
5 files changed, 130 insertions, 77 deletions
diff --git a/updater/Android.mk b/updater/Android.mk index d7aa613e9..7c3f6160c 100644 --- a/updater/Android.mk +++ b/updater/Android.mk @@ -14,26 +14,51 @@ 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_utils_static \ + 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 +69,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/blockimg.cpp b/updater/blockimg.cpp index 44de4e031..908e11631 100644 --- a/updater/blockimg.cpp +++ b/updater/blockimg.cpp @@ -33,21 +33,22 @@ #include <unistd.h> #include <fec/io.h> +#include <map> #include <memory> #include <string> #include <vector> #include <android-base/parseint.h> #include <android-base/strings.h> +#include <android-base/unique_fd.h> #include "applypatch/applypatch.h" #include "edify/expr.h" #include "install.h" #include "openssl/sha.h" #include "minzip/Hash.h" -#include "otafault/ota_io.h" +#include "ota_io.h" #include "print_sha1.h" -#include "unique_fd.h" #include "updater.h" #define BLOCKSIZE 4096 @@ -67,6 +68,8 @@ struct RangeSet { std::vector<size_t> pos; // Actual limit is INT_MAX. }; +static std::map<std::string, RangeSet> stash_map; + static void parse_range(const std::string& range_text, RangeSet& rs) { std::vector<std::string> pieces = android::base::Split(range_text, ","); @@ -365,7 +368,7 @@ struct CommandParameters { std::string stashbase; bool canwrite; int createdstash; - int fd; + android::base::unique_fd fd; bool foundwrites; bool isunresumable; int version; @@ -522,8 +525,28 @@ static void DeleteStash(const std::string& base) { } } -static int LoadStash(const std::string& base, const std::string& id, bool verify, size_t* blocks, - std::vector<uint8_t>& buffer, bool printnoent) { +static int LoadStash(CommandParameters& params, const std::string& base, const std::string& id, + bool verify, size_t* blocks, std::vector<uint8_t>& buffer, bool printnoent) { + // In verify mode, if source range_set was saved for the given hash, + // check contents in the source blocks first. If the check fails, + // search for the stashed files on /cache as usual. + if (!params.canwrite) { + if (stash_map.find(id) != stash_map.end()) { + const RangeSet& src = stash_map[id]; + allocate(src.size * BLOCKSIZE, buffer); + + if (ReadBlocks(src, buffer, params.fd) == -1) { + fprintf(stderr, "failed to read source blocks in stash map.\n"); + return -1; + } + if (VerifyBlocks(id, buffer, src.size, true) != 0) { + fprintf(stderr, "failed to verify loaded source blocks in stash map.\n"); + return -1; + } + return 0; + } + } + if (base.empty()) { return -1; } @@ -554,9 +577,7 @@ static int LoadStash(const std::string& base, const std::string& id, bool verify return -1; } - int fd = TEMP_FAILURE_RETRY(ota_open(fn.c_str(), O_RDONLY)); - unique_fd fd_holder(fd); - + android::base::unique_fd fd(TEMP_FAILURE_RETRY(ota_open(fn.c_str(), O_RDONLY))); if (fd == -1) { fprintf(stderr, "open \"%s\" failed: %s\n", fn.c_str(), strerror(errno)); return -1; @@ -611,9 +632,9 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks fprintf(stderr, " writing %d blocks to %s\n", blocks, cn.c_str()); - int fd = TEMP_FAILURE_RETRY(ota_open(fn.c_str(), O_WRONLY | O_CREAT | O_TRUNC, STASH_FILE_MODE)); - unique_fd fd_holder(fd); - + android::base::unique_fd fd(TEMP_FAILURE_RETRY(ota_open(fn.c_str(), + O_WRONLY | O_CREAT | O_TRUNC, + STASH_FILE_MODE))); if (fd == -1) { fprintf(stderr, "failed to create \"%s\": %s\n", fn.c_str(), strerror(errno)); return -1; @@ -635,9 +656,8 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks } std::string dname = GetStashFileName(base, "", ""); - int dfd = TEMP_FAILURE_RETRY(ota_open(dname.c_str(), O_RDONLY | O_DIRECTORY)); - unique_fd dfd_holder(dfd); - + android::base::unique_fd dfd(TEMP_FAILURE_RETRY(ota_open(dname.c_str(), + O_RDONLY | O_DIRECTORY))); if (dfd == -1) { fprintf(stderr, "failed to open \"%s\" failed: %s\n", dname.c_str(), strerror(errno)); return -1; @@ -722,7 +742,7 @@ static int SaveStash(CommandParameters& params, const std::string& base, const std::string& id = params.tokens[params.cpos++]; size_t blocks = 0; - if (usehash && LoadStash(base, id, true, &blocks, buffer, false) == 0) { + if (usehash && LoadStash(params, base, id, true, &blocks, buffer, false) == 0) { // Stash file already exists and has expected contents. Do not // read from source again, as the source may have been already // overwritten during a previous attempt. @@ -747,6 +767,12 @@ static int SaveStash(CommandParameters& params, const std::string& base, return 0; } + // In verify mode, save source range_set instead of stashing blocks. + if (!params.canwrite && usehash) { + stash_map[id] = src; + return 0; + } + fprintf(stderr, "stashing %zu blocks to %s\n", blocks, id.c_str()); return WriteStash(base, id, blocks, buffer, false, nullptr); } @@ -857,7 +883,7 @@ static int LoadSrcTgtVersion2(CommandParameters& params, RangeSet& tgt, size_t& } std::vector<uint8_t> stash; - int res = LoadStash(stashbase, tokens[0], false, nullptr, stash, true); + int res = LoadStash(params, stashbase, tokens[0], false, nullptr, stash, true); if (res == -1) { // These source blocks will fail verification if used later, but we @@ -913,8 +939,8 @@ static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet& tgt, size_t& tgthash = params.tokens[params.cpos++]; } - if (LoadSrcTgtVersion2(params, tgt, src_blocks, params.buffer, params.fd, params.stashbase, - &overlap) == -1) { + if (LoadSrcTgtVersion2(params, tgt, src_blocks, params.buffer, params.fd, + params.stashbase, &overlap) == -1) { return -1; } @@ -931,8 +957,9 @@ static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet& tgt, size_t& if (VerifyBlocks(srchash, params.buffer, src_blocks, true) == 0) { // If source and target blocks overlap, stash the source blocks so we can - // resume from possible write errors - if (overlap) { + // resume from possible write errors. In verify mode, we can skip stashing + // because the source blocks won't be overwritten. + if (overlap && params.canwrite) { fprintf(stderr, "stashing %zu overlapping blocks to %s\n", src_blocks, srchash.c_str()); @@ -953,7 +980,8 @@ static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet& tgt, size_t& return 0; } - if (overlap && LoadStash(params.stashbase, srchash, true, nullptr, params.buffer, true) == 0) { + if (overlap && LoadStash(params, params.stashbase, srchash, true, nullptr, params.buffer, + true) == 0) { // Overlapping source blocks were previously stashed, command can proceed. // We are recovering from an interrupted command, so we don't know if the // stash can safely be deleted after this command. @@ -1028,8 +1056,15 @@ static int PerformCommandFree(CommandParameters& params) { return -1; } + const std::string& id = params.tokens[params.cpos++]; + + if (!params.canwrite && stash_map.find(id) != stash_map.end()) { + stash_map.erase(id); + return 0; + } + if (params.createdstash || params.canwrite) { - return FreeStash(params.stashbase, params.tokens[params.cpos++]); + return FreeStash(params.stashbase, id); } return 0; @@ -1347,9 +1382,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg return StringValue(strdup("")); } - params.fd = TEMP_FAILURE_RETRY(ota_open(blockdev_filename->data, O_RDWR)); - unique_fd fd_holder(params.fd); - + params.fd.reset(TEMP_FAILURE_RETRY(ota_open(blockdev_filename->data, O_RDWR))); if (params.fd == -1) { fprintf(stderr, "open \"%s\" failed: %s\n", blockdev_filename->data, strerror(errno)); return StringValue(strdup("")); @@ -1494,7 +1527,7 @@ pbiudone: if (ota_fsync(params.fd) == -1) { fprintf(stderr, "fsync failed: %s\n", strerror(errno)); } - // params.fd will be automatically closed because of the fd_holder above. + // params.fd will be automatically closed because it's a unique_fd. // Only delete the stash if the update cannot be resumed, or it's // a verification run and we created the stash. @@ -1615,9 +1648,8 @@ Value* RangeSha1Fn(const char* name, State* state, int /* argc */, Expr* argv[]) return StringValue(strdup("")); } - int fd = ota_open(blockdev_filename->data, O_RDWR); - unique_fd fd_holder(fd); - if (fd < 0) { + android::base::unique_fd fd(ota_open(blockdev_filename->data, O_RDWR)); + if (fd == -1) { ErrorAbort(state, "open \"%s\" failed: %s", blockdev_filename->data, strerror(errno)); return StringValue(strdup("")); } @@ -1638,7 +1670,7 @@ Value* RangeSha1Fn(const char* name, State* state, int /* argc */, Expr* argv[]) for (size_t j = rs.pos[i*2]; j < rs.pos[i*2+1]; ++j) { if (read_all(fd, buffer, BLOCKSIZE) == -1) { ErrorAbort(state, "failed to read %s: %s", blockdev_filename->data, - strerror(errno)); + strerror(errno)); return StringValue(strdup("")); } @@ -1669,8 +1701,7 @@ Value* CheckFirstBlockFn(const char* name, State* state, int argc, Expr* argv[]) return StringValue(strdup("")); } - int fd = ota_open(arg_filename->data, O_RDONLY); - unique_fd fd_holder(fd); + android::base::unique_fd fd(ota_open(arg_filename->data, O_RDONLY)); if (fd == -1) { ErrorAbort(state, "open \"%s\" failed: %s", arg_filename->data, strerror(errno)); return StringValue(strdup("")); @@ -1680,8 +1711,7 @@ Value* CheckFirstBlockFn(const char* name, State* state, int argc, Expr* argv[]) std::vector<uint8_t> block0_buffer(BLOCKSIZE); if (ReadBlocks(blk0, block0_buffer, fd) == -1) { - ErrorAbort(state, "failed to read %s: %s", arg_filename->data, - strerror(errno)); + ErrorAbort(state, "failed to read %s: %s", arg_filename->data, strerror(errno)); return StringValue(strdup("")); } diff --git a/updater/install.cpp b/updater/install.cpp index 1cd9a5690..925604f31 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -27,7 +27,6 @@ #include <unistd.h> #include <fcntl.h> #include <time.h> -#include <selinux/selinux.h> #include <ftw.h> #include <sys/capability.h> #include <sys/xattr.h> @@ -40,6 +39,8 @@ #include <android-base/parseint.h> #include <android-base/strings.h> #include <android-base/stringprintf.h> +#include <selinux/label.h> +#include <selinux/selinux.h> #include "bootloader.h" #include "applypatch/applypatch.h" @@ -51,7 +52,7 @@ #include "minzip/DirUtil.h" #include "mtdutils/mounts.h" #include "mtdutils/mtdutils.h" -#include "otafault/ota_io.h" +#include "ota_io.h" #include "updater.h" #include "install.h" #include "tune2fs.h" @@ -1398,21 +1399,22 @@ Value* ReadFileFn(const char* name, State* state, int argc, Expr* argv[]) { char* filename; if (ReadArgs(state, argv, 1, &filename) < 0) return NULL; - Value* v = reinterpret_cast<Value*>(malloc(sizeof(Value))); + Value* v = static_cast<Value*>(malloc(sizeof(Value))); + if (v == nullptr) { + return nullptr; + } v->type = VAL_BLOB; + v->size = -1; + v->data = nullptr; FileContents fc; if (LoadFileContents(filename, &fc) != 0) { - free(filename); - v->size = -1; - v->data = NULL; - free(fc.data); - return v; + v->data = static_cast<char*>(malloc(fc.data.size())); + if (v->data != nullptr) { + memcpy(v->data, fc.data.data(), fc.data.size()); + v->size = fc.data.size(); + } } - - v->size = fc.size; - v->data = (char*)fc.data; - free(filename); return v; } diff --git a/updater/updater.cpp b/updater/updater.cpp index 0f22e6d04..0497d6a85 100644 --- a/updater/updater.cpp +++ b/updater/updater.cpp @@ -25,6 +25,10 @@ #include "blockimg.h" #include "minzip/Zip.h" #include "minzip/SysUtil.h" +#include "config.h" + +#include <selinux/label.h> +#include <selinux/selinux.h> // Generated by the makefile, this function defines the // RegisterDeviceExtensions() function, which calls all the @@ -35,6 +39,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) { @@ -82,6 +88,7 @@ int main(int argc, char** argv) { argv[3], strerror(err)); return 3; } + ota_io_init(&za); const ZipEntry* script_entry = mzFindZipEntry(&za, SCRIPT_NAME); if (script_entry == NULL) { @@ -139,6 +146,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"); diff --git a/updater/updater.h b/updater/updater.h index d1dfdd05e..d3a09b93d 100644 --- a/updater/updater.h +++ b/updater/updater.h @@ -20,9 +20,6 @@ #include <stdio.h> #include "minzip/Zip.h" -#include <selinux/selinux.h> -#include <selinux/label.h> - typedef struct { FILE* cmd_pipe; ZipArchive* package_zip; @@ -32,6 +29,7 @@ typedef struct { size_t package_zip_len; } UpdaterInfo; +struct selabel_handle; extern struct selabel_handle *sehandle; #endif |