From e5218615084c3bb4f12c91d0ebed823927f1bc68 Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Tue, 25 Jun 2019 13:59:39 -0700 Subject: Create a fallback to install from fuse if mmap fails We may fail to memory map the package on 32 bit builds for packages with 2GiB+ size. This cl tries to install the package with fuse when memory map fails in such cases. Bug: 127071893 Test: build 32 bit version sailfish, push package and block.map, reboot into recovery with the corresponding update_package argument. Change-Id: I5dae4f3e27ccaf8d64ff3657d36f0e75db2330b0 --- install/fuse_install.cpp | 7 ++++--- otautil/sysutil.cpp | 2 +- recovery.cpp | 28 ++++++++++++++++++++++++---- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/install/fuse_install.cpp b/install/fuse_install.cpp index ffde4a348..8a7a278e0 100644 --- a/install/fuse_install.cpp +++ b/install/fuse_install.cpp @@ -128,11 +128,12 @@ static bool StartInstallPackageFuse(std::string_view path) { constexpr auto FUSE_BLOCK_SIZE = 65536; bool is_block_map = android::base::ConsumePrefix(&path, "@"); - auto file_data_reader = + auto fuse_data_provider = is_block_map ? FuseBlockDataProvider::CreateFromBlockMap(std::string(path), FUSE_BLOCK_SIZE) : FuseFileDataProvider::CreateFromFile(std::string(path), FUSE_BLOCK_SIZE); - if (!file_data_reader->Valid()) { + if (!fuse_data_provider || !fuse_data_provider->Valid()) { + LOG(ERROR) << "Failed to create fuse data provider."; return false; } @@ -142,7 +143,7 @@ static bool StartInstallPackageFuse(std::string_view path) { umount2(SDCARD_ROOT, MNT_DETACH); } - return run_fuse_sideload(std::move(file_data_reader)) == 0; + return run_fuse_sideload(std::move(fuse_data_provider)) == 0; } InstallResult InstallWithFuseFromPath(std::string_view path, RecoveryUI* ui) { diff --git a/otautil/sysutil.cpp b/otautil/sysutil.cpp index a8829858d..6cd46c6a9 100644 --- a/otautil/sysutil.cpp +++ b/otautil/sysutil.cpp @@ -38,7 +38,7 @@ BlockMapData BlockMapData::ParseBlockMapFile(const std::string& block_map_path) { std::string content; if (!android::base::ReadFileToString(block_map_path, &content)) { - LOG(ERROR) << "Failed to read " << block_map_path; + PLOG(ERROR) << "Failed to read " << block_map_path; return {}; } diff --git a/recovery.cpp b/recovery.cpp index b18a8e74a..97ca0a504 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -84,6 +84,8 @@ const char* reason = nullptr; * * The arguments which may be supplied in the recovery.command file: * --update_package=path - verify install an OTA package file + * --install_with_fuse - install the update package with FUSE. This allows installation of large + * packages on LP32 builds. Since the mmap will otherwise fail due to out of memory. * --wipe_data - erase user data (and cache), then reboot * --prompt_and_wipe_data - prompt the user that data is corrupt, with their consent erase user * data (and cache), then reboot @@ -577,6 +579,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vectorPrint("Installation aborted.\n"); -- cgit v1.2.3