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

Commit 18278d2e authored by Tom Cherry's avatar Tom Cherry
Browse files

init: make triggering shutdown from vendor_init better

Previously, we assumed that TriggerShutdown() should never be called
from vendor_init and used property service as a back up in case it
ever did.  We have since then found out that vendor_init may indeed
call TriggerShutdown() and we want to make it just as strict as it is
in init, wherein it will immediately start the shutdown sequence
without executing any further commands.

Test: init unit tests, trigger shuttdown from init and vendor_init
Change-Id: I1f44dae801a28269eb8127879a8b7d6adff6f353
parent e91c76b2
Loading
Loading
Loading
Loading
+4 −11
Original line number Diff line number Diff line
@@ -140,14 +140,7 @@ static Result<void> reboot_into_recovery(const std::vector<std::string>& options
    if (!write_bootloader_message(options, &err)) {
        return Error() << "Failed to set bootloader message: " << err;
    }
    // This function should only be reached from init and not from vendor_init, and we want to
    // immediately trigger reboot instead of relaying through property_service.  Older devices may
    // still have paths that reach here from vendor_init, so we keep the property_set as a fallback.
    if (getpid() == 1) {
        TriggerShutdown("reboot,recovery");
    } else {
        property_set("sys.powerctl", "reboot,recovery");
    }
    trigger_shutdown("reboot,recovery");
    return {};
}

@@ -554,7 +547,7 @@ static Result<void> queue_fs_event(int code, bool userdata_remount) {
            // support userdata remount on FDE devices, this should never been triggered. Time to
            // panic!
            LOG(ERROR) << "Userdata remount is not supported on FDE devices. How did you get here?";
            TriggerShutdown("reboot,requested-userdata-remount-on-fde-device");
            trigger_shutdown("reboot,requested-userdata-remount-on-fde-device");
        }
        ActionManager::GetInstance().QueueEventTrigger("encrypt");
        return {};
@@ -564,7 +557,7 @@ static Result<void> queue_fs_event(int code, bool userdata_remount) {
            // don't support userdata remount on FDE devices, this should never been triggered.
            // Time to panic!
            LOG(ERROR) << "Userdata remount is not supported on FDE devices. How did you get here?";
            TriggerShutdown("reboot,requested-userdata-remount-on-fde-device");
            trigger_shutdown("reboot,requested-userdata-remount-on-fde-device");
        }
        property_set("ro.crypto.state", "encrypted");
        property_set("ro.crypto.type", "block");
@@ -1148,7 +1141,7 @@ static Result<void> do_remount_userdata(const BuiltinArguments& args) {
    }
    // TODO(b/135984674): check that fstab contains /data.
    if (auto rc = fs_mgr_remount_userdata_into_checkpointing(&fstab); rc < 0) {
        TriggerShutdown("reboot,mount-userdata-failed");
        trigger_shutdown("reboot,mount-userdata-failed");
    }
    if (auto result = queue_fs_event(initial_mount_fstab_return_code, true); !result) {
        return Error() << "queue_fs_event() failed: " << result.error();
+0 −5
Original line number Diff line number Diff line
@@ -35,11 +35,6 @@
namespace android {
namespace init {

// init.h
inline void TriggerShutdown(const std::string&) {
    abort();
}

// property_service.h
inline bool CanReadProperty(const std::string&, const std::string&) {
    return true;
+3 −1
Original line number Diff line number Diff line
@@ -180,7 +180,7 @@ void ResetWaitForProp() {
    waiting_for_prop.reset();
}

void TriggerShutdown(const std::string& command) {
static void TriggerShutdown(const std::string& command) {
    // We can't call HandlePowerctlMessage() directly in this function,
    // because it modifies the contents of the action queue, which can cause the action queue
    // to get into a bad state if this function is called from a command being executed by the
@@ -681,6 +681,8 @@ int SecondStageMain(int argc, char** argv) {

    boot_clock::time_point start_time = boot_clock::now();

    trigger_shutdown = TriggerShutdown;

    SetStdioToDevNull(argv);
    InitKernelLogging(argv);
    LOG(INFO) << "init second stage started!";
+0 −2
Original line number Diff line number Diff line
@@ -31,8 +31,6 @@ namespace init {
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list);
Parser CreateServiceOnlyParser(ServiceList& service_list);

void TriggerShutdown(const std::string& command);

bool start_waiting_for_property(const char *name, const char *value);

void DumpState();
+1 −1
Original line number Diff line number Diff line
@@ -731,7 +731,7 @@ static Result<void> DoUserspaceReboot() {
    auto guard = android::base::make_scope_guard([] {
        // Leave shutdown so that we can handle a full reboot.
        LeaveShutdown();
        TriggerShutdown("reboot,abort-userspace-reboot");
        trigger_shutdown("reboot,abort-userspace-reboot");
    });
    // Triggering userspace-reboot-requested will result in a bunch of set_prop
    // actions. We should make sure, that all of them are propagated before
Loading