init: Issue a wipe on boot if trade-in mode was active.
This modifies first-stage init to check for /metadata/tradeinmode/wipe as soon as /metadata is mounted. If the file exists, we issue a request to the bootloader to reboot to recovery and wipe /data. Since this also wipes /metadata, the wipe indicator will be removed too. In case some kind of failure happens in recovery, this also implements a quick-and-dirty counter mechanism to fallback to the recovery menu. Bug: 307713521 Test: touch /metadata/tradeinmode/wipe && adb reboot Change-Id: I2d05903cadcdadf9c05f6736454db790a9e6b5bb
This commit is contained in:
parent
47ec15c928
commit
6f451a9c8c
3 changed files with 59 additions and 0 deletions
|
|
@ -390,6 +390,7 @@ init_first_stage_cc_defaults {
|
|||
"libsnapshot_init",
|
||||
"update_metadata-protos",
|
||||
"libprocinfo",
|
||||
"libbootloader_message",
|
||||
],
|
||||
|
||||
static_executable: true,
|
||||
|
|
|
|||
|
|
@ -32,9 +32,12 @@
|
|||
#include <android-base/chrono_utils.h>
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/parseint.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/strings.h>
|
||||
#include <android/avf_cc_flags.h>
|
||||
#include <bootloader_message/bootloader_message.h>
|
||||
#include <cutils/android_reboot.h>
|
||||
#include <fs_avb/fs_avb.h>
|
||||
#include <fs_mgr.h>
|
||||
#include <fs_mgr_dm_linear.h>
|
||||
|
|
@ -46,6 +49,7 @@
|
|||
|
||||
#include "block_dev_initializer.h"
|
||||
#include "devices.h"
|
||||
#include "reboot_utils.h"
|
||||
#include "result.h"
|
||||
#include "snapuserd_transition.h"
|
||||
#include "switch_root.h"
|
||||
|
|
@ -111,6 +115,8 @@ class FirstStageMountVBootV2 : public FirstStageMount {
|
|||
bool GetDmVerityDevices(std::set<std::string>* devices);
|
||||
bool SetUpDmVerity(FstabEntry* fstab_entry);
|
||||
|
||||
void RequestTradeInModeWipeIfNeeded();
|
||||
|
||||
bool InitAvbHandle();
|
||||
|
||||
bool need_dm_verity_;
|
||||
|
|
@ -263,6 +269,8 @@ bool FirstStageMountVBootV2::DoCreateDevices() {
|
|||
}
|
||||
|
||||
bool FirstStageMountVBootV2::DoFirstStageMount() {
|
||||
RequestTradeInModeWipeIfNeeded();
|
||||
|
||||
if (!IsDmLinearEnabled() && fstab_.empty()) {
|
||||
// Nothing to mount.
|
||||
LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
|
||||
|
|
@ -883,6 +891,55 @@ bool FirstStageMountVBootV2::InitAvbHandle() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void FirstStageMountVBootV2::RequestTradeInModeWipeIfNeeded() {
|
||||
static constexpr const char* kWipeIndicator = "/metadata/tradeinmode/wipe";
|
||||
static constexpr size_t kWipeAttempts = 3;
|
||||
|
||||
if (access(kWipeIndicator, R_OK) == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Write a counter to the wipe indicator, to try and prevent boot loops if
|
||||
// recovery fails to wipe data.
|
||||
uint32_t counter = 0;
|
||||
std::string contents;
|
||||
if (ReadFileToString(kWipeIndicator, &contents)) {
|
||||
android::base::ParseUint(contents, &counter);
|
||||
contents = std::to_string(++counter);
|
||||
if (android::base::WriteStringToFile(contents, kWipeIndicator)) {
|
||||
sync();
|
||||
} else {
|
||||
PLOG(ERROR) << "Failed to update " << kWipeIndicator;
|
||||
}
|
||||
} else {
|
||||
PLOG(ERROR) << "Failed to read " << kWipeIndicator;
|
||||
}
|
||||
|
||||
std::string err;
|
||||
auto misc_device = get_misc_blk_device(&err);
|
||||
if (misc_device.empty()) {
|
||||
LOG(FATAL) << "Could not find misc device: " << err;
|
||||
}
|
||||
|
||||
auto misc_name = android::base::Basename(misc_device);
|
||||
if (!block_dev_init_.InitDevices({misc_name})) {
|
||||
LOG(FATAL) << "Could not find misc device: " << misc_device;
|
||||
}
|
||||
|
||||
// If we've failed to wipe three times, don't include the wipe command. This
|
||||
// will force us to boot into the recovery menu instead where a manual wipe
|
||||
// can be attempted.
|
||||
std::vector<std::string> options;
|
||||
if (counter <= kWipeAttempts) {
|
||||
options.emplace_back("--wipe_data");
|
||||
options.emplace_back("--reason=tradeinmode");
|
||||
}
|
||||
if (!write_bootloader_message(options, &err)) {
|
||||
LOG(FATAL) << "Could not issue wipe: " << err;
|
||||
}
|
||||
RebootSystem(ANDROID_RB_RESTART2, "recovery", "reboot,tradeinmode,wipe");
|
||||
}
|
||||
|
||||
void SetInitAvbVersionInRecovery() {
|
||||
if (!IsRecoveryMode()) {
|
||||
LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not in recovery mode)";
|
||||
|
|
|
|||
|
|
@ -644,6 +644,7 @@ on post-fs
|
|||
mkdir /metadata/ota 0750 root system
|
||||
mkdir /metadata/ota/snapshots 0750 root system
|
||||
mkdir /metadata/watchdog 0770 root system
|
||||
mkdir /metadata/tradeinmode 0770 root system
|
||||
|
||||
mkdir /metadata/apex 0700 root system
|
||||
mkdir /metadata/apex/sessions 0700 root system
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue