Merge "Move wipe cache|data to libinstall"
This commit is contained in:
@@ -107,7 +107,6 @@ cc_binary {
|
|||||||
],
|
],
|
||||||
|
|
||||||
srcs: [
|
srcs: [
|
||||||
"logging.cpp",
|
|
||||||
"recovery_main.cpp",
|
"recovery_main.cpp",
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -139,7 +138,6 @@ cc_binary {
|
|||||||
],
|
],
|
||||||
|
|
||||||
srcs: [
|
srcs: [
|
||||||
"logging.cpp",
|
|
||||||
"recovery-persist.cpp",
|
"recovery-persist.cpp",
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -167,7 +165,6 @@ cc_binary {
|
|||||||
],
|
],
|
||||||
|
|
||||||
srcs: [
|
srcs: [
|
||||||
"logging.cpp",
|
|
||||||
"recovery-refresh.cpp",
|
"recovery-refresh.cpp",
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ cc_library_static {
|
|||||||
"install.cpp",
|
"install.cpp",
|
||||||
"package.cpp",
|
"package.cpp",
|
||||||
"verifier.cpp",
|
"verifier.cpp",
|
||||||
|
"wipe_data.cpp",
|
||||||
],
|
],
|
||||||
|
|
||||||
shared_libs: [
|
shared_libs: [
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ static bool WriteStatusToFd(MinadbdCommandStatus status, int fd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Installs the package from FUSE. Returns true if the installation succeeds, and false otherwise.
|
// Installs the package from FUSE. Returns true if the installation succeeds, and false otherwise.
|
||||||
static bool AdbInstallPackageHandler(bool* wipe_cache, RecoveryUI* ui, int* result) {
|
static bool AdbInstallPackageHandler(RecoveryUI* ui, int* result) {
|
||||||
// How long (in seconds) we wait for the package path to be ready. It doesn't need to be too long
|
// How long (in seconds) we wait for the package path to be ready. It doesn't need to be too long
|
||||||
// because the minadbd service has already issued an install command. FUSE_SIDELOAD_HOST_PATHNAME
|
// because the minadbd service has already issued an install command. FUSE_SIDELOAD_HOST_PATHNAME
|
||||||
// will start to exist once the host connects and starts serving a package. Poll for its
|
// will start to exist once the host connects and starts serving a package. Poll for its
|
||||||
@@ -99,7 +99,7 @@ static bool AdbInstallPackageHandler(bool* wipe_cache, RecoveryUI* ui, int* resu
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, false, 0, ui);
|
*result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, false, false, 0, ui);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +280,7 @@ static void CreateMinadbdServiceAndExecuteCommands(
|
|||||||
signal(SIGPIPE, SIG_DFL);
|
signal(SIGPIPE, SIG_DFL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int apply_from_adb(bool* wipe_cache, RecoveryUI* ui) {
|
int apply_from_adb(RecoveryUI* ui) {
|
||||||
// Save the usb state to restore after the sideload operation.
|
// Save the usb state to restore after the sideload operation.
|
||||||
std::string usb_state = android::base::GetProperty("sys.usb.state", "none");
|
std::string usb_state = android::base::GetProperty("sys.usb.state", "none");
|
||||||
// Clean up state and stop adbd.
|
// Clean up state and stop adbd.
|
||||||
@@ -295,8 +295,7 @@ int apply_from_adb(bool* wipe_cache, RecoveryUI* ui) {
|
|||||||
|
|
||||||
int install_result = INSTALL_ERROR;
|
int install_result = INSTALL_ERROR;
|
||||||
std::map<MinadbdCommands, CommandFunction> command_map{
|
std::map<MinadbdCommands, CommandFunction> command_map{
|
||||||
{ MinadbdCommands::kInstall,
|
{ MinadbdCommands::kInstall, std::bind(&AdbInstallPackageHandler, ui, &install_result) },
|
||||||
std::bind(&AdbInstallPackageHandler, wipe_cache, ui, &install_result) },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CreateMinadbdServiceAndExecuteCommands(command_map);
|
CreateMinadbdServiceAndExecuteCommands(command_map);
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ static bool StartSdcardFuse(const std::string& path) {
|
|||||||
return run_fuse_sideload(std::move(file_data_reader)) == 0;
|
return run_fuse_sideload(std::move(file_data_reader)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ApplyFromSdcard(Device* device, bool* wipe_cache, RecoveryUI* ui) {
|
int ApplyFromSdcard(Device* device, RecoveryUI* ui) {
|
||||||
if (ensure_path_mounted(SDCARD_ROOT) != 0) {
|
if (ensure_path_mounted(SDCARD_ROOT) != 0) {
|
||||||
LOG(ERROR) << "\n-- Couldn't mount " << SDCARD_ROOT << ".\n";
|
LOG(ERROR) << "\n-- Couldn't mount " << SDCARD_ROOT << ".\n";
|
||||||
return INSTALL_ERROR;
|
return INSTALL_ERROR;
|
||||||
@@ -184,7 +184,7 @@ int ApplyFromSdcard(Device* device, bool* wipe_cache, RecoveryUI* ui) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, false, 0 /*retry_count*/, ui);
|
result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, false, false, 0 /*retry_count*/, ui);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,4 +18,4 @@
|
|||||||
|
|
||||||
#include <recovery_ui/ui.h>
|
#include <recovery_ui/ui.h>
|
||||||
|
|
||||||
int apply_from_adb(bool* wipe_cache, RecoveryUI* ui);
|
int apply_from_adb(RecoveryUI* ui);
|
||||||
|
|||||||
@@ -19,4 +19,4 @@
|
|||||||
#include "recovery_ui/device.h"
|
#include "recovery_ui/device.h"
|
||||||
#include "recovery_ui/ui.h"
|
#include "recovery_ui/ui.h"
|
||||||
|
|
||||||
int ApplyFromSdcard(Device* device, bool* wipe_cache, RecoveryUI* ui);
|
int ApplyFromSdcard(Device* device, RecoveryUI* ui);
|
||||||
|
|||||||
@@ -43,10 +43,11 @@ enum class OtaType {
|
|||||||
BRICK,
|
BRICK,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Installs the given update package. If INSTALL_SUCCESS is returned and *wipe_cache is true on
|
// Installs the given update package. This function should also wipe the cache partition after a
|
||||||
// exit, caller should wipe the cache partition.
|
// successful installation if |should_wipe_cache| is true or an updater command asks to wipe the
|
||||||
int install_package(const std::string& package, bool* wipe_cache, bool needs_mount, int retry_count,
|
// cache.
|
||||||
RecoveryUI* ui);
|
int install_package(const std::string& package, bool should_wipe_cache, bool needs_mount,
|
||||||
|
int retry_count, RecoveryUI* ui);
|
||||||
|
|
||||||
// Verifies the package by ota keys. Returns true if the package is verified successfully,
|
// Verifies the package by ota keys. Returns true if the package is verified successfully,
|
||||||
// otherwise returns false.
|
// otherwise returns false.
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "recovery_ui/device.h"
|
||||||
|
#include "recovery_ui/ui.h"
|
||||||
|
|
||||||
|
struct selabel_handle;
|
||||||
|
|
||||||
|
void SetWipeDataSehandle(selabel_handle* handle);
|
||||||
|
|
||||||
|
// Returns true on success.
|
||||||
|
bool WipeCache(RecoveryUI* ui, const std::function<bool()>& confirm);
|
||||||
|
|
||||||
|
// Returns true on success.
|
||||||
|
bool WipeData(Device* device, bool convert_fbe);
|
||||||
+13
-5
@@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#include "install/package.h"
|
#include "install/package.h"
|
||||||
#include "install/verifier.h"
|
#include "install/verifier.h"
|
||||||
|
#include "install/wipe_data.h"
|
||||||
#include "otautil/error_code.h"
|
#include "otautil/error_code.h"
|
||||||
#include "otautil/paths.h"
|
#include "otautil/paths.h"
|
||||||
#include "otautil/roots.h"
|
#include "otautil/roots.h"
|
||||||
@@ -631,10 +632,9 @@ static int really_install_package(const std::string& path, bool* wipe_cache, boo
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int install_package(const std::string& path, bool* wipe_cache, bool needs_mount, int retry_count,
|
int install_package(const std::string& path, bool should_wipe_cache, bool needs_mount,
|
||||||
RecoveryUI* ui) {
|
int retry_count, RecoveryUI* ui) {
|
||||||
CHECK(!path.empty());
|
CHECK(!path.empty());
|
||||||
CHECK(wipe_cache != nullptr);
|
|
||||||
|
|
||||||
auto start = std::chrono::system_clock::now();
|
auto start = std::chrono::system_clock::now();
|
||||||
|
|
||||||
@@ -647,8 +647,10 @@ int install_package(const std::string& path, bool* wipe_cache, bool needs_mount,
|
|||||||
LOG(ERROR) << "failed to set up expected mounts for install; aborting";
|
LOG(ERROR) << "failed to set up expected mounts for install; aborting";
|
||||||
result = INSTALL_ERROR;
|
result = INSTALL_ERROR;
|
||||||
} else {
|
} else {
|
||||||
result = really_install_package(path, wipe_cache, needs_mount, &log_buffer, retry_count,
|
bool updater_wipe_cache = false;
|
||||||
&max_temperature, ui);
|
result = really_install_package(path, &updater_wipe_cache, needs_mount, &log_buffer,
|
||||||
|
retry_count, &max_temperature, ui);
|
||||||
|
should_wipe_cache = should_wipe_cache || updater_wipe_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Measure the time spent to apply OTA update in seconds.
|
// Measure the time spent to apply OTA update in seconds.
|
||||||
@@ -703,6 +705,12 @@ int install_package(const std::string& path, bool* wipe_cache, bool needs_mount,
|
|||||||
// Write a copy into last_log.
|
// Write a copy into last_log.
|
||||||
LOG(INFO) << log_content;
|
LOG(INFO) << log_content;
|
||||||
|
|
||||||
|
if (result == INSTALL_SUCCESS && should_wipe_cache) {
|
||||||
|
if (!WipeCache(ui, nullptr)) {
|
||||||
|
result = INSTALL_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "install/wipe_data.h"
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <android-base/file.h>
|
||||||
|
#include <android-base/logging.h>
|
||||||
|
#include <android-base/stringprintf.h>
|
||||||
|
|
||||||
|
#include "otautil/dirutil.h"
|
||||||
|
#include "otautil/logging.h"
|
||||||
|
#include "otautil/roots.h"
|
||||||
|
#include "recovery_ui/ui.h"
|
||||||
|
|
||||||
|
constexpr const char* CACHE_ROOT = "/cache";
|
||||||
|
constexpr const char* DATA_ROOT = "/data";
|
||||||
|
constexpr const char* METADATA_ROOT = "/metadata";
|
||||||
|
|
||||||
|
constexpr const char* CACHE_LOG_DIR = "/cache/recovery";
|
||||||
|
|
||||||
|
static struct selabel_handle* sehandle;
|
||||||
|
|
||||||
|
void SetWipeDataSehandle(selabel_handle* handle) {
|
||||||
|
sehandle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct saved_log_file {
|
||||||
|
std::string name;
|
||||||
|
struct stat sb;
|
||||||
|
std::string data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool EraseVolume(const char* volume, RecoveryUI* ui, bool convert_fbe) {
|
||||||
|
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<saved_log_file> 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<DIR, decltype(&closedir)> 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 && convert_fbe) {
|
||||||
|
constexpr const char* CONVERT_FBE_DIR = "/tmp/convert_fbe";
|
||||||
|
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(true /* save_current_log */, true /* has_cache */, sehandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WipeCache(RecoveryUI* ui, const std::function<bool()>& confirm_func) {
|
||||||
|
bool has_cache = volume_for_mount_point("/cache") != nullptr;
|
||||||
|
if (!has_cache) {
|
||||||
|
ui->Print("No /cache partition found.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (confirm_func && !confirm_func()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->Print("\n-- Wiping cache...\n");
|
||||||
|
bool success = EraseVolume("/cache", ui, false);
|
||||||
|
ui->Print("Cache wipe %s.\n", success ? "complete" : "failed");
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WipeData(Device* device, bool convert_fbe) {
|
||||||
|
RecoveryUI* ui = device->GetUI();
|
||||||
|
ui->Print("\n-- Wiping data...\n");
|
||||||
|
bool success = device->PreWipeData();
|
||||||
|
if (success) {
|
||||||
|
success &= EraseVolume(DATA_ROOT, ui, convert_fbe);
|
||||||
|
bool has_cache = volume_for_mount_point("/cache") != nullptr;
|
||||||
|
if (has_cache) {
|
||||||
|
success &= EraseVolume(CACHE_ROOT, ui, false);
|
||||||
|
}
|
||||||
|
if (volume_for_mount_point(METADATA_ROOT) != nullptr) {
|
||||||
|
success &= EraseVolume(METADATA_ROOT, ui, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (success) {
|
||||||
|
success &= device->PostWipeData();
|
||||||
|
}
|
||||||
|
ui->Print("Data wipe %s.\n", success ? "complete" : "failed");
|
||||||
|
return success;
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ cc_library_static {
|
|||||||
android: {
|
android: {
|
||||||
srcs: [
|
srcs: [
|
||||||
"dirutil.cpp",
|
"dirutil.cpp",
|
||||||
|
"logging.cpp",
|
||||||
"mounts.cpp",
|
"mounts.cpp",
|
||||||
"parse_install_logs.cpp",
|
"parse_install_logs.cpp",
|
||||||
"roots.cpp",
|
"roots.cpp",
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
static constexpr int KEEP_LOG_COUNT = 10;
|
static constexpr int KEEP_LOG_COUNT = 10;
|
||||||
|
|
||||||
|
struct selabel_handle;
|
||||||
|
|
||||||
ssize_t logbasename(log_id_t id, char prio, const char* filename, const char* buf, size_t len,
|
ssize_t logbasename(log_id_t id, char prio, const char* filename, const char* buf, size_t len,
|
||||||
void* arg);
|
void* arg);
|
||||||
|
|
||||||
@@ -41,8 +43,7 @@ void rotate_logs(const char* last_log_file, const char* last_kmsg_file);
|
|||||||
void check_and_fclose(FILE* fp, const std::string& name);
|
void check_and_fclose(FILE* fp, const std::string& name);
|
||||||
|
|
||||||
void copy_log_file_to_pmsg(const std::string& source, const std::string& destination);
|
void copy_log_file_to_pmsg(const std::string& source, const std::string& destination);
|
||||||
void copy_log_file(const std::string& source, const std::string& destination, bool append);
|
void copy_logs(bool save_current_log, bool has_cache, const selabel_handle* sehandle);
|
||||||
void copy_logs(bool modified_flash, bool has_cache);
|
|
||||||
void reset_tmplog_offset();
|
void reset_tmplog_offset();
|
||||||
|
|
||||||
void save_kernel_log(const char* destination);
|
void save_kernel_log(const char* destination);
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "logging.h"
|
#include "otautil/logging.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
#include <android-base/stringprintf.h>
|
#include <android-base/stringprintf.h>
|
||||||
#include <private/android_filesystem_config.h> /* for AID_SYSTEM */
|
#include <private/android_filesystem_config.h> /* for AID_SYSTEM */
|
||||||
#include <private/android_logger.h> /* private pmsg functions */
|
#include <private/android_logger.h> /* private pmsg functions */
|
||||||
|
#include <selinux/label.h>
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "otautil/dirutil.h"
|
#include "otautil/dirutil.h"
|
||||||
#include "otautil/paths.h"
|
#include "otautil/paths.h"
|
||||||
#include "otautil/roots.h"
|
#include "otautil/roots.h"
|
||||||
@@ -45,7 +45,7 @@ static const std::string LAST_LOG_FILTER = "recovery/last_log";
|
|||||||
|
|
||||||
// fopen(3)'s the given file, by mounting volumes and making parent dirs as necessary. Returns the
|
// fopen(3)'s the given file, by mounting volumes and making parent dirs as necessary. Returns the
|
||||||
// file pointer, or nullptr on error.
|
// file pointer, or nullptr on error.
|
||||||
static FILE* fopen_path(const std::string& path, const char* mode) {
|
static FILE* fopen_path(const std::string& path, const char* mode, const selabel_handle* sehandle) {
|
||||||
if (ensure_path_mounted(path) != 0) {
|
if (ensure_path_mounted(path) != 0) {
|
||||||
LOG(ERROR) << "Can't mount " << path;
|
LOG(ERROR) << "Can't mount " << path;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -165,8 +165,9 @@ void reset_tmplog_offset() {
|
|||||||
tmplog_offset = 0;
|
tmplog_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_log_file(const std::string& source, const std::string& destination, bool append) {
|
static void copy_log_file(const std::string& source, const std::string& destination, bool append,
|
||||||
FILE* dest_fp = fopen_path(destination, append ? "ae" : "we");
|
const selabel_handle* sehandle) {
|
||||||
|
FILE* dest_fp = fopen_path(destination, append ? "ae" : "we", sehandle);
|
||||||
if (dest_fp == nullptr) {
|
if (dest_fp == nullptr) {
|
||||||
PLOG(ERROR) << "Can't open " << destination;
|
PLOG(ERROR) << "Can't open " << destination;
|
||||||
} else {
|
} else {
|
||||||
@@ -189,11 +190,11 @@ void copy_log_file(const std::string& source, const std::string& destination, bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_logs(bool modified_flash, bool has_cache) {
|
void copy_logs(bool save_current_log, bool has_cache, const selabel_handle* sehandle) {
|
||||||
// We only rotate and record the log of the current session if there are actual attempts to modify
|
// We only rotate and record the log of the current session if explicitly requested. This usually
|
||||||
// the flash, such as wipes, installs from BCB or menu selections. This is to avoid unnecessary
|
// happens after wipes, installation from BCB or menu selections. This is to avoid unnecessary
|
||||||
// rotation (and possible deletion) of log files, if it does not do anything loggable.
|
// rotation (and possible deletion) of log files, if it does not do anything loggable.
|
||||||
if (!modified_flash) {
|
if (!save_current_log) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,9 +212,9 @@ void copy_logs(bool modified_flash, bool has_cache) {
|
|||||||
rotate_logs(LAST_LOG_FILE, LAST_KMSG_FILE);
|
rotate_logs(LAST_LOG_FILE, LAST_KMSG_FILE);
|
||||||
|
|
||||||
// Copy logs to cache so the system can find out what happened.
|
// Copy logs to cache so the system can find out what happened.
|
||||||
copy_log_file(Paths::Get().temporary_log_file(), LOG_FILE, true);
|
copy_log_file(Paths::Get().temporary_log_file(), LOG_FILE, true, sehandle);
|
||||||
copy_log_file(Paths::Get().temporary_log_file(), LAST_LOG_FILE, false);
|
copy_log_file(Paths::Get().temporary_log_file(), LAST_LOG_FILE, false, sehandle);
|
||||||
copy_log_file(Paths::Get().temporary_install_file(), LAST_INSTALL_FILE, false);
|
copy_log_file(Paths::Get().temporary_install_file(), LAST_INSTALL_FILE, false, sehandle);
|
||||||
save_kernel_log(LAST_KMSG_FILE);
|
save_kernel_log(LAST_KMSG_FILE);
|
||||||
chmod(LOG_FILE, 0600);
|
chmod(LOG_FILE, 0600);
|
||||||
chown(LOG_FILE, AID_SYSTEM, AID_SYSTEM);
|
chown(LOG_FILE, AID_SYSTEM, AID_SYSTEM);
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
#include <metricslogger/metrics_logger.h>
|
#include <metricslogger/metrics_logger.h>
|
||||||
#include <private/android_logger.h> /* private pmsg functions */
|
#include <private/android_logger.h> /* private pmsg functions */
|
||||||
|
|
||||||
#include "logging.h"
|
#include "otautil/logging.h"
|
||||||
#include "otautil/parse_install_logs.h"
|
#include "otautil/parse_install_logs.h"
|
||||||
|
|
||||||
constexpr const char* LAST_LOG_FILE = "/data/misc/recovery/last_log";
|
constexpr const char* LAST_LOG_FILE = "/data/misc/recovery/last_log";
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
#include <private/android_logger.h> /* private pmsg functions */
|
#include <private/android_logger.h> /* private pmsg functions */
|
||||||
|
|
||||||
#include "logging.h"
|
#include "otautil/logging.h"
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
static const char filter[] = "recovery/";
|
static const char filter[] = "recovery/";
|
||||||
|
|||||||
+31
-186
@@ -27,7 +27,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@@ -55,30 +54,27 @@
|
|||||||
#include "install/fuse_sdcard_install.h"
|
#include "install/fuse_sdcard_install.h"
|
||||||
#include "install/install.h"
|
#include "install/install.h"
|
||||||
#include "install/package.h"
|
#include "install/package.h"
|
||||||
#include "logging.h"
|
#include "install/wipe_data.h"
|
||||||
#include "otautil/dirutil.h"
|
|
||||||
#include "otautil/error_code.h"
|
#include "otautil/error_code.h"
|
||||||
|
#include "otautil/logging.h"
|
||||||
#include "otautil/paths.h"
|
#include "otautil/paths.h"
|
||||||
#include "otautil/roots.h"
|
#include "otautil/roots.h"
|
||||||
#include "otautil/sysutil.h"
|
#include "otautil/sysutil.h"
|
||||||
#include "recovery_ui/screen_ui.h"
|
#include "recovery_ui/screen_ui.h"
|
||||||
#include "recovery_ui/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* COMMAND_FILE = "/cache/recovery/command";
|
||||||
static constexpr const char* LAST_KMSG_FILE = "/cache/recovery/last_kmsg";
|
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* LAST_LOG_FILE = "/cache/recovery/last_log";
|
||||||
static constexpr const char* LOCALE_FILE = "/cache/recovery/last_locale";
|
static constexpr const char* LOCALE_FILE = "/cache/recovery/last_locale";
|
||||||
|
|
||||||
static constexpr const char* CACHE_ROOT = "/cache";
|
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
|
// 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.
|
// 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_assert(kRecoveryApiVersion == RECOVERY_API_VERSION, "Mismatching recovery API versions.");
|
||||||
|
|
||||||
static bool modified_flash = false;
|
static bool save_current_log = false;
|
||||||
std::string stage;
|
std::string stage;
|
||||||
const char* reason = nullptr;
|
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.
|
// Reset to normal system boot so recovery won't cycle indefinitely.
|
||||||
std::string err;
|
std::string err;
|
||||||
@@ -167,110 +163,6 @@ static void finish_recovery() {
|
|||||||
sync(); // For good measure.
|
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<saved_log_file> 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<DIR, decltype(&closedir)> 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) {
|
static bool yes_no(Device* device, const char* question1, const char* question2) {
|
||||||
std::vector<std::string> headers{ question1, question2 };
|
std::vector<std::string> headers{ question1, question2 };
|
||||||
std::vector<std::string> items{ " No", " Yes" };
|
std::vector<std::string> items{ " No", " Yes" };
|
||||||
@@ -292,28 +184,6 @@ static bool ask_to_wipe_data(Device* device) {
|
|||||||
return (chosen_item == 1);
|
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) {
|
static InstallResult prompt_and_wipe_data(Device* device) {
|
||||||
// Use a single string and let ScreenRecoveryUI handles the wrapping.
|
// Use a single string and let ScreenRecoveryUI handles the wrapping.
|
||||||
std::vector<std::string> wipe_data_menu_headers{
|
std::vector<std::string> wipe_data_menu_headers{
|
||||||
@@ -341,7 +211,8 @@ static InstallResult prompt_and_wipe_data(Device* device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ask_to_wipe_data(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;
|
return INSTALL_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
return INSTALL_ERROR;
|
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
|
// Secure-wipe a given partition. It uses BLKSECDISCARD, if supported. Otherwise, it goes with
|
||||||
// BLKDISCARD (if device supports BLKDISCARDZEROES) or BLKZEROOUT.
|
// BLKDISCARD (if device supports BLKDISCARDZEROES) or BLKZEROOUT.
|
||||||
static bool secure_wipe_partition(const std::string& partition) {
|
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::REBOOT
|
||||||
: device->InvokeMenuItem(chosen_item);
|
: device->InvokeMenuItem(chosen_item);
|
||||||
|
|
||||||
bool should_wipe_cache = false;
|
|
||||||
switch (chosen_action) {
|
switch (chosen_action) {
|
||||||
case Device::NO_ACTION:
|
case Device::NO_ACTION:
|
||||||
break;
|
break;
|
||||||
@@ -666,41 +517,40 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) {
|
|||||||
return chosen_action;
|
return chosen_action;
|
||||||
|
|
||||||
case Device::WIPE_DATA:
|
case Device::WIPE_DATA:
|
||||||
|
save_current_log = true;
|
||||||
if (ui->IsTextVisible()) {
|
if (ui->IsTextVisible()) {
|
||||||
if (ask_to_wipe_data(device)) {
|
if (ask_to_wipe_data(device)) {
|
||||||
wipe_data(device);
|
WipeData(device, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wipe_data(device);
|
WipeData(device, false);
|
||||||
return Device::NO_ACTION;
|
return Device::NO_ACTION;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Device::WIPE_CACHE:
|
case Device::WIPE_CACHE: {
|
||||||
wipe_cache(ui->IsTextVisible(), device);
|
save_current_log = true;
|
||||||
|
std::function<bool()> 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;
|
if (!ui->IsTextVisible()) return Device::NO_ACTION;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case Device::APPLY_ADB_SIDELOAD:
|
case Device::APPLY_ADB_SIDELOAD:
|
||||||
case Device::APPLY_SDCARD: {
|
case Device::APPLY_SDCARD: {
|
||||||
modified_flash = true;
|
save_current_log = true;
|
||||||
bool adb = (chosen_action == Device::APPLY_ADB_SIDELOAD);
|
bool adb = (chosen_action == Device::APPLY_ADB_SIDELOAD);
|
||||||
if (adb) {
|
if (adb) {
|
||||||
status = apply_from_adb(&should_wipe_cache, ui);
|
status = apply_from_adb(ui);
|
||||||
} else {
|
} else {
|
||||||
status = ApplyFromSdcard(device, &should_wipe_cache, ui);
|
status = ApplyFromSdcard(device, ui);
|
||||||
}
|
|
||||||
|
|
||||||
if (status == INSTALL_SUCCESS && should_wipe_cache) {
|
|
||||||
if (!wipe_cache(false, device)) {
|
|
||||||
status = INSTALL_ERROR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != INSTALL_SUCCESS) {
|
if (status != INSTALL_SUCCESS) {
|
||||||
ui->SetBackground(RecoveryUI::ERROR);
|
ui->SetBackground(RecoveryUI::ERROR);
|
||||||
ui->Print("Installation aborted.\n");
|
ui->Print("Installation aborted.\n");
|
||||||
copy_logs(modified_flash, has_cache);
|
copy_logs(save_current_log, has_cache, sehandle);
|
||||||
} else if (!ui->IsTextVisible()) {
|
} else if (!ui->IsTextVisible()) {
|
||||||
return Device::NO_ACTION; // reboot if logs aren't visible
|
return Device::NO_ACTION; // reboot if logs aren't visible
|
||||||
} else {
|
} else {
|
||||||
@@ -987,7 +837,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
if (update_package != nullptr) {
|
if (update_package != nullptr) {
|
||||||
// It's not entirely true that we will modify the flash. But we want
|
// It's not entirely true that we will modify the flash. But we want
|
||||||
// to log the update attempt since update_package is non-NULL.
|
// to log the update attempt since update_package is non-NULL.
|
||||||
modified_flash = true;
|
save_current_log = true;
|
||||||
|
|
||||||
int required_battery_level;
|
int required_battery_level;
|
||||||
if (retry_count == 0 && !is_battery_ok(&required_battery_level)) {
|
if (retry_count == 0 && !is_battery_ok(&required_battery_level)) {
|
||||||
@@ -1009,11 +859,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
set_retry_bootloader_message(retry_count + 1, args);
|
set_retry_bootloader_message(retry_count + 1, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
modified_flash = true;
|
status = install_package(update_package, should_wipe_cache, true, retry_count, ui);
|
||||||
status = install_package(update_package, &should_wipe_cache, true, retry_count, ui);
|
|
||||||
if (status == INSTALL_SUCCESS && should_wipe_cache) {
|
|
||||||
wipe_cache(false, device);
|
|
||||||
}
|
|
||||||
if (status != INSTALL_SUCCESS) {
|
if (status != INSTALL_SUCCESS) {
|
||||||
ui->Print("Installation aborted.\n");
|
ui->Print("Installation aborted.\n");
|
||||||
|
|
||||||
@@ -1021,7 +867,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
// RETRY_LIMIT times before we abandon this OTA update.
|
// RETRY_LIMIT times before we abandon this OTA update.
|
||||||
static constexpr int RETRY_LIMIT = 4;
|
static constexpr int RETRY_LIMIT = 4;
|
||||||
if (status == INSTALL_RETRY && retry_count < RETRY_LIMIT) {
|
if (status == INSTALL_RETRY && retry_count < RETRY_LIMIT) {
|
||||||
copy_logs(modified_flash, has_cache);
|
copy_logs(save_current_log, has_cache, sehandle);
|
||||||
retry_count += 1;
|
retry_count += 1;
|
||||||
set_retry_bootloader_message(retry_count, args);
|
set_retry_bootloader_message(retry_count, args);
|
||||||
// Print retry count on screen.
|
// Print retry count on screen.
|
||||||
@@ -1045,12 +891,14 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (should_wipe_data) {
|
} else if (should_wipe_data) {
|
||||||
if (!wipe_data(device)) {
|
save_current_log = true;
|
||||||
|
bool convert_fbe = reason && strcmp(reason, "convert_fbe") == 0;
|
||||||
|
if (!WipeData(device, convert_fbe)) {
|
||||||
status = INSTALL_ERROR;
|
status = INSTALL_ERROR;
|
||||||
}
|
}
|
||||||
} else if (should_prompt_and_wipe_data) {
|
} else if (should_prompt_and_wipe_data) {
|
||||||
// Trigger the logging to capture the cause, even if user chooses to not wipe data.
|
// Trigger the logging to capture the cause, even if user chooses to not wipe data.
|
||||||
modified_flash = true;
|
save_current_log = true;
|
||||||
|
|
||||||
ui->ShowText(true);
|
ui->ShowText(true);
|
||||||
ui->SetBackground(RecoveryUI::ERROR);
|
ui->SetBackground(RecoveryUI::ERROR);
|
||||||
@@ -1059,7 +907,8 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
ui->ShowText(false);
|
ui->ShowText(false);
|
||||||
}
|
}
|
||||||
} else if (should_wipe_cache) {
|
} else if (should_wipe_cache) {
|
||||||
if (!wipe_cache(false, device)) {
|
save_current_log = true;
|
||||||
|
if (!WipeCache(ui, nullptr)) {
|
||||||
status = INSTALL_ERROR;
|
status = INSTALL_ERROR;
|
||||||
}
|
}
|
||||||
} else if (should_wipe_ab) {
|
} else if (should_wipe_ab) {
|
||||||
@@ -1073,15 +922,11 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
|
|||||||
// sideload finishes even if there are errors. Unless one turns on the
|
// sideload finishes even if there are errors. Unless one turns on the
|
||||||
// text display during the installation. This is to enable automated
|
// text display during the installation. This is to enable automated
|
||||||
// testing.
|
// testing.
|
||||||
|
save_current_log = true;
|
||||||
if (!sideload_auto_reboot) {
|
if (!sideload_auto_reboot) {
|
||||||
ui->ShowText(true);
|
ui->ShowText(true);
|
||||||
}
|
}
|
||||||
status = apply_from_adb(&should_wipe_cache, ui);
|
status = apply_from_adb(ui);
|
||||||
if (status == INSTALL_SUCCESS && should_wipe_cache) {
|
|
||||||
if (!wipe_cache(false, device)) {
|
|
||||||
status = INSTALL_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui->Print("\nInstall from ADB complete (status: %d).\n", status);
|
ui->Print("\nInstall from ADB complete (status: %d).\n", status);
|
||||||
if (sideload_auto_reboot) {
|
if (sideload_auto_reboot) {
|
||||||
ui->Print("Rebooting automatically.\n");
|
ui->Print("Rebooting automatically.\n");
|
||||||
|
|||||||
+4
-1
@@ -50,7 +50,8 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "fastboot/fastboot.h"
|
#include "fastboot/fastboot.h"
|
||||||
#include "logging.h"
|
#include "install/wipe_data.h"
|
||||||
|
#include "otautil/logging.h"
|
||||||
#include "otautil/paths.h"
|
#include "otautil/paths.h"
|
||||||
#include "otautil/roots.h"
|
#include "otautil/roots.h"
|
||||||
#include "otautil/sysutil.h"
|
#include "otautil/sysutil.h"
|
||||||
@@ -434,6 +435,8 @@ int main(int argc, char** argv) {
|
|||||||
ui->Print("Warning: No file_contexts\n");
|
ui->Print("Warning: No file_contexts\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetWipeDataSehandle(sehandle);
|
||||||
|
|
||||||
std::atomic<Device::BuiltinAction> action;
|
std::atomic<Device::BuiltinAction> action;
|
||||||
std::thread listener_thread(ListenRecoverySocket, ui, std::ref(action));
|
std::thread listener_thread(ListenRecoverySocket, ui, std::ref(action));
|
||||||
listener_thread.detach();
|
listener_thread.detach();
|
||||||
|
|||||||
Reference in New Issue
Block a user