init: trigger shutdown directly from builtins
Especially now that property_service is a thread, there may be some delay between when init sets sys.powerctl and when the main thread of init receives this and triggers shutdown. It's possible that outstanding init commands are run during this gap and that is not desirable. Instead, have builtins call TriggerShutdown() directly, so we can be sure that the next action that init runs will be to shutdown the device. Test: reboot works Test: reboot into recovery due to bad /data works Change-Id: I26fb9f4f57f46c7451b8b58187138cfedd6fd9eb
This commit is contained in:
parent
6b0e789a21
commit
0dbfea7b07
6 changed files with 16 additions and 9 deletions
|
|
@ -138,7 +138,14 @@ 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;
|
||||
}
|
||||
property_set("sys.powerctl", "reboot,recovery");
|
||||
// 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");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace android {
|
|||
namespace init {
|
||||
|
||||
// init.h
|
||||
inline void EnterShutdown(const std::string&) {
|
||||
inline void TriggerShutdown(const std::string&) {
|
||||
abort();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ void ResetWaitForProp() {
|
|||
waiting_for_prop.reset();
|
||||
}
|
||||
|
||||
void EnterShutdown(const std::string& command) {
|
||||
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
|
||||
|
|
@ -197,7 +197,7 @@ void property_changed(const std::string& name, const std::string& value) {
|
|||
// In non-thermal-shutdown case, 'shutdown' trigger will be fired to let device specific
|
||||
// commands to be executed.
|
||||
if (name == "sys.powerctl") {
|
||||
EnterShutdown(value);
|
||||
TriggerShutdown(value);
|
||||
}
|
||||
|
||||
if (property_triggers_enabled) ActionManager::GetInstance().QueuePropertyChange(name, value);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace init {
|
|||
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list);
|
||||
Parser CreateServiceOnlyParser(ServiceList& service_list);
|
||||
|
||||
void EnterShutdown(const std::string& command);
|
||||
void TriggerShutdown(const std::string& command);
|
||||
|
||||
bool start_waiting_for_property(const char *name, const char *value);
|
||||
|
||||
|
|
|
|||
|
|
@ -710,7 +710,7 @@ static Result<void> DoUserspaceReboot() {
|
|||
auto guard = android::base::make_scope_guard([] {
|
||||
// Leave shutdown so that we can handle a full reboot.
|
||||
LeaveShutdown();
|
||||
property_set("sys.powerctl", "reboot,abort-userspace-reboot");
|
||||
TriggerShutdown("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
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ void Service::Reap(const siginfo_t& siginfo) {
|
|||
|
||||
if ((siginfo.si_code != CLD_EXITED || siginfo.si_status != 0) && on_failure_reboot_target_) {
|
||||
LOG(ERROR) << "Service with 'reboot_on_failure' option failed, shutting down system.";
|
||||
EnterShutdown(*on_failure_reboot_target_);
|
||||
TriggerShutdown(*on_failure_reboot_target_);
|
||||
}
|
||||
|
||||
if (flags_ & SVC_EXEC) UnSetExec();
|
||||
|
|
@ -335,7 +335,7 @@ void Service::DumpState() const {
|
|||
Result<void> Service::ExecStart() {
|
||||
auto reboot_on_failure = make_scope_guard([this] {
|
||||
if (on_failure_reboot_target_) {
|
||||
EnterShutdown(*on_failure_reboot_target_);
|
||||
TriggerShutdown(*on_failure_reboot_target_);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -366,7 +366,7 @@ Result<void> Service::ExecStart() {
|
|||
Result<void> Service::Start() {
|
||||
auto reboot_on_failure = make_scope_guard([this] {
|
||||
if (on_failure_reboot_target_) {
|
||||
EnterShutdown(*on_failure_reboot_target_);
|
||||
TriggerShutdown(*on_failure_reboot_target_);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue