From 388d253b9cf4d12ca7879d29dc6711ad44541ccd Mon Sep 17 00:00:00 2001 From: xunchang Date: Fri, 12 Apr 2019 16:22:15 -0700 Subject: DO NOT MERGE: Move wipe cache|data to libinstall Therefore, libinstall becomes the sole owner to handle the request from minadbd service. The change also includes 1. move logging.cpp out of librecovery 2. drop the dependency on common.h 3. now it's more sensible to move the wipe_cache as part of install_package. move the wipe_cache to the end of the function. Bug: 130166585 Test: wipe data and cache from menu Change-Id: I6f356dccdb38015c50acf756bac246f87c30fc1f (cherry picked from commit 316e9717461890dd319dc370970069fe4532a561) --- recovery.cpp | 217 +++++++++-------------------------------------------------- 1 file changed, 31 insertions(+), 186 deletions(-) (limited to 'recovery.cpp') diff --git a/recovery.cpp b/recovery.cpp index 034918498..0e6e4976d 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -55,30 +54,27 @@ #include "install/fuse_sdcard_install.h" #include "install/install.h" #include "install/package.h" -#include "logging.h" -#include "otautil/dirutil.h" +#include "install/wipe_data.h" #include "otautil/error_code.h" +#include "otautil/logging.h" #include "otautil/paths.h" #include "otautil/roots.h" #include "otautil/sysutil.h" #include "recovery_ui/screen_ui.h" #include "recovery_ui/ui.h" -static constexpr const char* CACHE_LOG_DIR = "/cache/recovery"; static constexpr const char* COMMAND_FILE = "/cache/recovery/command"; static constexpr const char* LAST_KMSG_FILE = "/cache/recovery/last_kmsg"; static constexpr const char* LAST_LOG_FILE = "/cache/recovery/last_log"; static constexpr const char* LOCALE_FILE = "/cache/recovery/last_locale"; static constexpr const char* CACHE_ROOT = "/cache"; -static constexpr const char* DATA_ROOT = "/data"; -static constexpr const char* METADATA_ROOT = "/metadata"; // We define RECOVERY_API_VERSION in Android.mk, which will be picked up by build system and packed // into target_files.zip. Assert the version defined in code and in Android.mk are consistent. static_assert(kRecoveryApiVersion == RECOVERY_API_VERSION, "Mismatching recovery API versions."); -static bool modified_flash = false; +static bool save_current_log = false; std::string stage; const char* reason = nullptr; @@ -148,7 +144,7 @@ static void finish_recovery() { } } - copy_logs(modified_flash, has_cache); + copy_logs(save_current_log, has_cache, sehandle); // Reset to normal system boot so recovery won't cycle indefinitely. std::string err; @@ -167,110 +163,6 @@ static void finish_recovery() { sync(); // For good measure. } -struct saved_log_file { - std::string name; - struct stat sb; - std::string data; -}; - -static bool erase_volume(const char* volume) { - bool is_cache = (strcmp(volume, CACHE_ROOT) == 0); - bool is_data = (strcmp(volume, DATA_ROOT) == 0); - - ui->SetBackground(RecoveryUI::ERASING); - ui->SetProgressType(RecoveryUI::INDETERMINATE); - - std::vector log_files; - - if (is_cache) { - // If we're reformatting /cache, we load any past logs - // (i.e. "/cache/recovery/last_*") and the current log - // ("/cache/recovery/log") into memory, so we can restore them after - // the reformat. - - ensure_path_mounted(volume); - - struct dirent* de; - std::unique_ptr d(opendir(CACHE_LOG_DIR), closedir); - if (d) { - while ((de = readdir(d.get())) != nullptr) { - if (strncmp(de->d_name, "last_", 5) == 0 || strcmp(de->d_name, "log") == 0) { - std::string path = android::base::StringPrintf("%s/%s", CACHE_LOG_DIR, de->d_name); - - struct stat sb; - if (stat(path.c_str(), &sb) == 0) { - // truncate files to 512kb - if (sb.st_size > (1 << 19)) { - sb.st_size = 1 << 19; - } - - std::string data(sb.st_size, '\0'); - FILE* f = fopen(path.c_str(), "rbe"); - fread(&data[0], 1, data.size(), f); - fclose(f); - - log_files.emplace_back(saved_log_file{ path, sb, data }); - } - } - } - } else { - if (errno != ENOENT) { - PLOG(ERROR) << "Failed to opendir " << CACHE_LOG_DIR; - } - } - } - - ui->Print("Formatting %s...\n", volume); - - ensure_path_unmounted(volume); - - int result; - if (is_data && reason && strcmp(reason, "convert_fbe") == 0) { - static constexpr const char* CONVERT_FBE_DIR = "/tmp/convert_fbe"; - static constexpr const char* CONVERT_FBE_FILE = "/tmp/convert_fbe/convert_fbe"; - // Create convert_fbe breadcrumb file to signal init to convert to file based encryption, not - // full disk encryption. - if (mkdir(CONVERT_FBE_DIR, 0700) != 0) { - PLOG(ERROR) << "Failed to mkdir " << CONVERT_FBE_DIR; - return false; - } - FILE* f = fopen(CONVERT_FBE_FILE, "wbe"); - if (!f) { - PLOG(ERROR) << "Failed to convert to file encryption"; - return false; - } - fclose(f); - result = format_volume(volume, CONVERT_FBE_DIR); - remove(CONVERT_FBE_FILE); - rmdir(CONVERT_FBE_DIR); - } else { - result = format_volume(volume); - } - - if (is_cache) { - // Re-create the log dir and write back the log entries. - if (ensure_path_mounted(CACHE_LOG_DIR) == 0 && - mkdir_recursively(CACHE_LOG_DIR, 0777, false, sehandle) == 0) { - for (const auto& log : log_files) { - if (!android::base::WriteStringToFile(log.data, log.name, log.sb.st_mode, log.sb.st_uid, - log.sb.st_gid)) { - PLOG(ERROR) << "Failed to write to " << log.name; - } - } - } else { - PLOG(ERROR) << "Failed to mount / create " << CACHE_LOG_DIR; - } - - // Any part of the log we'd copied to cache is now gone. - // Reset the pointer so we copy from the beginning of the temp - // log. - reset_tmplog_offset(); - copy_logs(modified_flash, has_cache); - } - - return (result == 0); -} - static bool yes_no(Device* device, const char* question1, const char* question2) { std::vector headers{ question1, question2 }; std::vector items{ " No", " Yes" }; @@ -292,28 +184,6 @@ static bool ask_to_wipe_data(Device* device) { return (chosen_item == 1); } -// Return true on success. -static bool wipe_data(Device* device) { - modified_flash = true; - - ui->Print("\n-- Wiping data...\n"); - bool success = device->PreWipeData(); - if (success) { - success &= erase_volume(DATA_ROOT); - if (has_cache) { - success &= erase_volume(CACHE_ROOT); - } - if (volume_for_mount_point(METADATA_ROOT) != nullptr) { - success &= erase_volume(METADATA_ROOT); - } - } - if (success) { - success &= device->PostWipeData(); - } - ui->Print("Data wipe %s.\n", success ? "complete" : "failed"); - return success; -} - static InstallResult prompt_and_wipe_data(Device* device) { // Use a single string and let ScreenRecoveryUI handles the wrapping. std::vector wipe_data_menu_headers{ @@ -341,7 +211,8 @@ static InstallResult prompt_and_wipe_data(Device* device) { } if (ask_to_wipe_data(device)) { - if (wipe_data(device)) { + bool convert_fbe = reason && strcmp(reason, "convert_fbe") == 0; + if (WipeData(device, convert_fbe)) { return INSTALL_SUCCESS; } else { return INSTALL_ERROR; @@ -350,25 +221,6 @@ static InstallResult prompt_and_wipe_data(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; - } - - modified_flash = true; - - ui->Print("\n-- Wiping cache...\n"); - bool success = erase_volume("/cache"); - ui->Print("Cache wipe %s.\n", success ? "complete" : "failed"); - return success; -} - // Secure-wipe a given partition. It uses BLKSECDISCARD, if supported. Otherwise, it goes with // BLKDISCARD (if device supports BLKDISCARDZEROES) or BLKZEROOUT. static bool secure_wipe_partition(const std::string& partition) { @@ -653,7 +505,6 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) { ? Device::REBOOT : device->InvokeMenuItem(chosen_item); - bool should_wipe_cache = false; switch (chosen_action) { case Device::NO_ACTION: break; @@ -666,41 +517,40 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) { return chosen_action; case Device::WIPE_DATA: + save_current_log = true; if (ui->IsTextVisible()) { if (ask_to_wipe_data(device)) { - wipe_data(device); + WipeData(device, false); } } else { - wipe_data(device); + WipeData(device, false); return Device::NO_ACTION; } break; - case Device::WIPE_CACHE: - wipe_cache(ui->IsTextVisible(), device); + case Device::WIPE_CACHE: { + save_current_log = true; + std::function confirm_func = [&device]() { + return yes_no(device, "Wipe cache?", " THIS CAN NOT BE UNDONE!"); + }; + WipeCache(ui, ui->IsTextVisible() ? confirm_func : nullptr); if (!ui->IsTextVisible()) return Device::NO_ACTION; break; - + } case Device::APPLY_ADB_SIDELOAD: case Device::APPLY_SDCARD: { - modified_flash = true; + save_current_log = true; bool adb = (chosen_action == Device::APPLY_ADB_SIDELOAD); if (adb) { - status = apply_from_adb(&should_wipe_cache, ui); + status = apply_from_adb(ui); } else { - status = ApplyFromSdcard(device, &should_wipe_cache, ui); - } - - if (status == INSTALL_SUCCESS && should_wipe_cache) { - if (!wipe_cache(false, device)) { - status = INSTALL_ERROR; - } + status = ApplyFromSdcard(device, ui); } if (status != INSTALL_SUCCESS) { ui->SetBackground(RecoveryUI::ERROR); ui->Print("Installation aborted.\n"); - copy_logs(modified_flash, has_cache); + copy_logs(save_current_log, has_cache, sehandle); } else if (!ui->IsTextVisible()) { return Device::NO_ACTION; // reboot if logs aren't visible } else { @@ -987,7 +837,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vectorPrint("Installation aborted.\n"); @@ -1021,7 +867,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vectorShowText(true); ui->SetBackground(RecoveryUI::ERROR); @@ -1059,7 +907,8 @@ Device::BuiltinAction start_recovery(Device* device, const std::vectorShowText(false); } } else if (should_wipe_cache) { - if (!wipe_cache(false, device)) { + save_current_log = true; + if (!WipeCache(ui, nullptr)) { status = INSTALL_ERROR; } } else if (should_wipe_ab) { @@ -1073,15 +922,11 @@ Device::BuiltinAction start_recovery(Device* device, const std::vectorShowText(true); } - status = apply_from_adb(&should_wipe_cache, ui); - if (status == INSTALL_SUCCESS && should_wipe_cache) { - if (!wipe_cache(false, device)) { - status = INSTALL_ERROR; - } - } + status = apply_from_adb(ui); ui->Print("\nInstall from ADB complete (status: %d).\n", status); if (sideload_auto_reboot) { ui->Print("Rebooting automatically.\n"); -- cgit v1.2.3