Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5e79fd7b authored by Jing Wang's avatar Jing Wang Committed by Automerger Merge Worker
Browse files

Merge "init: Add a boot monitor for the second stage init" into main am: 2d69dd60

parents 0ce61913 2d69dd60
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ using namespace std::string_literals;
using android::base::boot_clock;
using android::base::ConsumePrefix;
using android::base::GetProperty;
using android::base::GetIntProperty;
using android::base::GetBoolProperty;
using android::base::ReadFileToString;
using android::base::SetProperty;
using android::base::StringPrintf;
@@ -108,6 +110,8 @@ using android::base::Trim;
using android::base::unique_fd;
using android::fs_mgr::AvbHandle;
using android::snapshot::SnapshotManager;
using android::base::WaitForProperty;
using android::base::WriteStringToFile;

namespace android {
namespace init {
@@ -919,6 +923,34 @@ static Result<void> ConnectEarlyStageSnapuserdAction(const BuiltinArguments& arg
    return {};
}

static void SecondStageBootMonitor(int timeout_sec) {
    auto cur_time = boot_clock::now().time_since_epoch();
    int cur_sec = std::chrono::duration_cast<std::chrono::seconds>(cur_time).count();
    int extra_sec = timeout_sec <= cur_sec? 0 : timeout_sec - cur_sec;
    auto boot_timeout = std::chrono::seconds(extra_sec);

    LOG(INFO) << "Started BootMonitorThread, expiring in "
              << timeout_sec
              << " seconds from boot-up";

    if (!WaitForProperty("sys.boot_completed", "1", boot_timeout)) {
        LOG(ERROR) << "BootMonitorThread: boot didn't complete in "
                   << timeout_sec
                   << " seconds. Trigger a panic!";

        // add a short delay for logs to be flushed out.
        std::this_thread::sleep_for(200ms);

        // trigger a kernel panic
        WriteStringToFile("c", PROC_SYSRQ);
    }
}

static void StartSecondStageBootMonitor(int timeout_sec) {
    std::thread monitor_thread(&SecondStageBootMonitor, timeout_sec);
    monitor_thread.detach();
}

int SecondStageMain(int argc, char** argv) {
    if (REBOOT_BOOTLOADER_ON_PANIC) {
        InstallRebootSignalHandlers();
@@ -1010,6 +1042,14 @@ int SecondStageMain(int argc, char** argv) {
    InstallInitNotifier(&epoll);
    StartPropertyService(&property_fd);

    // If boot_timeout property has been set in a debug build, start the boot monitor
    if (GetBoolProperty("ro.debuggable", false)) {
        int timeout = GetIntProperty("ro.boot.boot_timeout", 0);
        if (timeout > 0) {
            StartSecondStageBootMonitor(timeout);
        }
    }

    // Make the time that init stages started available for bootstat to log.
    RecordStageBoottimes(start_time);