Merge "Create a fallback to install from fuse if mmap fails"
This commit is contained in:
@@ -128,11 +128,12 @@ static bool StartInstallPackageFuse(std::string_view path) {
|
|||||||
|
|
||||||
constexpr auto FUSE_BLOCK_SIZE = 65536;
|
constexpr auto FUSE_BLOCK_SIZE = 65536;
|
||||||
bool is_block_map = android::base::ConsumePrefix(&path, "@");
|
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)
|
is_block_map ? FuseBlockDataProvider::CreateFromBlockMap(std::string(path), FUSE_BLOCK_SIZE)
|
||||||
: FuseFileDataProvider::CreateFromFile(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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +143,7 @@ static bool StartInstallPackageFuse(std::string_view path) {
|
|||||||
umount2(SDCARD_ROOT, MNT_DETACH);
|
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) {
|
InstallResult InstallWithFuseFromPath(std::string_view path, RecoveryUI* ui) {
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@
|
|||||||
BlockMapData BlockMapData::ParseBlockMapFile(const std::string& block_map_path) {
|
BlockMapData BlockMapData::ParseBlockMapFile(const std::string& block_map_path) {
|
||||||
std::string content;
|
std::string content;
|
||||||
if (!android::base::ReadFileToString(block_map_path, &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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-4
@@ -84,6 +84,8 @@ const char* reason = nullptr;
|
|||||||
*
|
*
|
||||||
* The arguments which may be supplied in the recovery.command file:
|
* The arguments which may be supplied in the recovery.command file:
|
||||||
* --update_package=path - verify install an OTA package 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
|
* --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
|
* --prompt_and_wipe_data - prompt the user that data is corrupt, with their consent erase user
|
||||||
* data (and cache), then reboot
|
* data (and cache), then reboot
|
||||||
@@ -577,6 +579,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
static constexpr struct option OPTIONS[] = {
|
static constexpr struct option OPTIONS[] = {
|
||||||
{ "fastboot", no_argument, nullptr, 0 },
|
{ "fastboot", no_argument, nullptr, 0 },
|
||||||
{ "fsck_unshare_blocks", no_argument, nullptr, 0 },
|
{ "fsck_unshare_blocks", no_argument, nullptr, 0 },
|
||||||
|
{ "install_with_fuse", no_argument, nullptr, 0 },
|
||||||
{ "just_exit", no_argument, nullptr, 'x' },
|
{ "just_exit", no_argument, nullptr, 'x' },
|
||||||
{ "locale", required_argument, nullptr, 0 },
|
{ "locale", required_argument, nullptr, 0 },
|
||||||
{ "prompt_and_wipe_data", no_argument, nullptr, 0 },
|
{ "prompt_and_wipe_data", no_argument, nullptr, 0 },
|
||||||
@@ -597,6 +600,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
};
|
};
|
||||||
|
|
||||||
const char* update_package = nullptr;
|
const char* update_package = nullptr;
|
||||||
|
bool install_with_fuse = false; // memory map the update package by default.
|
||||||
bool should_wipe_data = false;
|
bool should_wipe_data = false;
|
||||||
bool should_prompt_and_wipe_data = false;
|
bool should_prompt_and_wipe_data = false;
|
||||||
bool should_wipe_cache = false;
|
bool should_wipe_cache = false;
|
||||||
@@ -632,6 +636,8 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
std::string option = OPTIONS[option_index].name;
|
std::string option = OPTIONS[option_index].name;
|
||||||
if (option == "fsck_unshare_blocks") {
|
if (option == "fsck_unshare_blocks") {
|
||||||
fsck_unshare_blocks = true;
|
fsck_unshare_blocks = true;
|
||||||
|
} else if (option == "install_with_fuse") {
|
||||||
|
install_with_fuse = true;
|
||||||
} else if (option == "locale" || option == "fastboot") {
|
} else if (option == "locale" || option == "fastboot") {
|
||||||
// Handled in recovery_main.cpp
|
// Handled in recovery_main.cpp
|
||||||
} else if (option == "prompt_and_wipe_data") {
|
} else if (option == "prompt_and_wipe_data") {
|
||||||
@@ -737,10 +743,24 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
} else {
|
} else {
|
||||||
ensure_path_mounted(update_package);
|
ensure_path_mounted(update_package);
|
||||||
}
|
}
|
||||||
// TODO(xunchang) install package from fuse for large packages on ILP32 builds.
|
|
||||||
auto package = Package::CreateMemoryPackage(
|
if (install_with_fuse) {
|
||||||
update_package, std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
|
LOG(INFO) << "Installing package " << update_package << " with fuse";
|
||||||
status = InstallPackage(package.get(), update_package, should_wipe_cache, retry_count, ui);
|
status = InstallWithFuseFromPath(update_package, ui);
|
||||||
|
} else if (auto memory_package = Package::CreateMemoryPackage(
|
||||||
|
update_package,
|
||||||
|
std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
|
||||||
|
memory_package != nullptr) {
|
||||||
|
status = InstallPackage(memory_package.get(), update_package, should_wipe_cache,
|
||||||
|
retry_count, ui);
|
||||||
|
} else {
|
||||||
|
// We may fail to memory map the package on 32 bit builds for packages with 2GiB+ size.
|
||||||
|
// In such cases, we will try to install the package with fuse. This is not the default
|
||||||
|
// installation method because it introduces a layer of indirection from the kernel space.
|
||||||
|
LOG(WARNING) << "Failed to memory map package " << update_package
|
||||||
|
<< "; falling back to install with fuse";
|
||||||
|
status = InstallWithFuseFromPath(update_package, ui);
|
||||||
|
}
|
||||||
if (status != INSTALL_SUCCESS) {
|
if (status != INSTALL_SUCCESS) {
|
||||||
ui->Print("Installation aborted.\n");
|
ui->Print("Installation aborted.\n");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user