init: reboot immediately if /data isn't mounted
All of the logic in reboot.cpp is meant to safely shutdown services, safely unmount emulated RW file systems, then finally unmount the remaining RW file systems, particularly /data. If /data hasn't been mounted, then none of this logic is required. Running this logic caused a lock up when shutting down blueline from early-init. Vold, or potentially a related HAL, locked up during the ShutdownVold() calls. debuggerd separately locked up in the watchdog thread. Therefore, this change immediately reboots if /data is not mounted. It also removes the lines to call into debuggerd. debuggerd will not run due to SELinux in any case, so it can only be used when hands-on debugging a device. Bug: 141082587 Test: shutdown with /data mounted continues as normal Test: shutdown from early-init immediately shuts the device down Change-Id: I79c72346b17c7dfe57e955d9739bcaf559badc14
This commit is contained in:
parent
bac7609c48
commit
2436e6b15a
|
@ -60,6 +60,8 @@
|
|||
|
||||
#define PROC_SYSRQ "/proc/sysrq-trigger"
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
using android::base::GetBoolProperty;
|
||||
using android::base::Split;
|
||||
using android::base::Timer;
|
||||
|
@ -170,9 +172,23 @@ static void LogShutdownTime(UmountStat stat, Timer* t) {
|
|||
<< stat;
|
||||
}
|
||||
|
||||
/* Find all read+write block devices and emulated devices in /proc/mounts
|
||||
* and add them to correpsponding list.
|
||||
*/
|
||||
static bool IsDataMounted() {
|
||||
std::unique_ptr<std::FILE, int (*)(std::FILE*)> fp(setmntent("/proc/mounts", "re"), endmntent);
|
||||
if (fp == nullptr) {
|
||||
PLOG(ERROR) << "Failed to open /proc/mounts";
|
||||
return false;
|
||||
}
|
||||
mntent* mentry;
|
||||
while ((mentry = getmntent(fp.get())) != nullptr) {
|
||||
if (mentry->mnt_dir == "/data"s) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find all read+write block devices and emulated devices in /proc/mounts and add them to
|
||||
// the correpsponding list.
|
||||
static bool FindPartitionsToUmount(std::vector<MountEntry>* blockDevPartitions,
|
||||
std::vector<MountEntry>* emulatedPartitions, bool dump) {
|
||||
std::unique_ptr<std::FILE, int (*)(std::FILE*)> fp(setmntent("/proc/mounts", "re"), endmntent);
|
||||
|
@ -295,12 +311,15 @@ void RebootMonitorThread(unsigned int cmd, const std::string& rebootTarget, sem_
|
|||
LOG(ERROR) << "Reboot thread timed out";
|
||||
|
||||
if (android::base::GetBoolProperty("ro.debuggable", false) == true) {
|
||||
LOG(INFO) << "Try to dump init process call trace:";
|
||||
const char* vdc_argv[] = {"/system/bin/debuggerd", "-b", "1"};
|
||||
int status;
|
||||
android_fork_execvp_ext(arraysize(vdc_argv), (char**)vdc_argv, &status, true,
|
||||
LOG_KLOG, true, nullptr, nullptr, 0);
|
||||
|
||||
if (false) {
|
||||
// SEPolicy will block debuggerd from running and this is intentional.
|
||||
// But these lines are left to be enabled during debugging.
|
||||
LOG(INFO) << "Try to dump init process call trace:";
|
||||
const char* vdc_argv[] = {"/system/bin/debuggerd", "-b", "1"};
|
||||
int status;
|
||||
android_fork_execvp_ext(arraysize(vdc_argv), (char**)vdc_argv, &status, true,
|
||||
LOG_KLOG, true, nullptr, nullptr, 0);
|
||||
}
|
||||
LOG(INFO) << "Show stack for all active CPU:";
|
||||
WriteStringToFile("l", PROC_SYSRQ);
|
||||
|
||||
|
@ -436,6 +455,14 @@ static void DoReboot(unsigned int cmd, const std::string& reason, const std::str
|
|||
Timer t;
|
||||
LOG(INFO) << "Reboot start, reason: " << reason << ", rebootTarget: " << rebootTarget;
|
||||
|
||||
// If /data isn't mounted then we can skip the extra reboot steps below, since we don't need to
|
||||
// worry about unmounting it.
|
||||
if (!IsDataMounted()) {
|
||||
sync();
|
||||
RebootSystem(cmd, rebootTarget);
|
||||
abort();
|
||||
}
|
||||
|
||||
// Ensure last reboot reason is reduced to canonical
|
||||
// alias reported in bootloader or system boot reason.
|
||||
size_t skip = 0;
|
||||
|
|
Loading…
Reference in New Issue