Merge "init: handle sys.powerctl immediately"
am: 14ed55bae8
Change-Id: Ide932edcca1b076665448e465a785abfc1a1cb4c
This commit is contained in:
commit
e6bfb53196
8 changed files with 64 additions and 64 deletions
|
|
@ -370,10 +370,6 @@ Commands
|
||||||
_options_ include "barrier=1", "noauto\_da\_alloc", "discard", ... as
|
_options_ include "barrier=1", "noauto\_da\_alloc", "discard", ... as
|
||||||
a comma separated string, eg: barrier=1,noauto\_da\_alloc
|
a comma separated string, eg: barrier=1,noauto\_da\_alloc
|
||||||
|
|
||||||
`powerctl`
|
|
||||||
> Internal implementation detail used to respond to changes to the
|
|
||||||
"sys.powerctl" system property, used to implement rebooting.
|
|
||||||
|
|
||||||
`restart <service>`
|
`restart <service>`
|
||||||
> Stops and restarts a running service, does nothing if the service is currently
|
> Stops and restarts a running service, does nothing if the service is currently
|
||||||
restarting, otherwise, it just starts the service.
|
restarting, otherwise, it just starts the service.
|
||||||
|
|
|
||||||
|
|
@ -598,58 +598,6 @@ static int do_restart(const std::vector<std::string>& args) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_powerctl(const std::vector<std::string>& args) {
|
|
||||||
const std::string& command = args[1];
|
|
||||||
unsigned int cmd = 0;
|
|
||||||
std::vector<std::string> cmd_params = android::base::Split(command, ",");
|
|
||||||
std::string reason_string = cmd_params[0];
|
|
||||||
std::string reboot_target = "";
|
|
||||||
bool runFsck = false;
|
|
||||||
bool commandInvalid = false;
|
|
||||||
|
|
||||||
if (cmd_params.size() > 3) {
|
|
||||||
commandInvalid = true;
|
|
||||||
} else if (cmd_params[0] == "shutdown") {
|
|
||||||
cmd = ANDROID_RB_POWEROFF;
|
|
||||||
if (cmd_params.size() == 2 && cmd_params[1] == "userrequested") {
|
|
||||||
// The shutdown reason is PowerManager.SHUTDOWN_USER_REQUESTED.
|
|
||||||
// Run fsck once the file system is remounted in read-only mode.
|
|
||||||
runFsck = true;
|
|
||||||
reason_string = cmd_params[1];
|
|
||||||
}
|
|
||||||
} else if (cmd_params[0] == "reboot") {
|
|
||||||
cmd = ANDROID_RB_RESTART2;
|
|
||||||
if (cmd_params.size() >= 2) {
|
|
||||||
reboot_target = cmd_params[1];
|
|
||||||
// When rebooting to the bootloader notify the bootloader writing
|
|
||||||
// also the BCB.
|
|
||||||
if (reboot_target == "bootloader") {
|
|
||||||
std::string err;
|
|
||||||
if (!write_reboot_bootloader(&err)) {
|
|
||||||
LOG(ERROR) << "reboot-bootloader: Error writing "
|
|
||||||
"bootloader_message: "
|
|
||||||
<< err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If there is an additional bootloader parameter, pass it along
|
|
||||||
if (cmd_params.size() == 3) {
|
|
||||||
reboot_target += "," + cmd_params[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (command == "thermal-shutdown") { // no additional parameter allowed
|
|
||||||
cmd = ANDROID_RB_THERMOFF;
|
|
||||||
} else {
|
|
||||||
commandInvalid = true;
|
|
||||||
}
|
|
||||||
if (commandInvalid) {
|
|
||||||
LOG(ERROR) << "powerctl: unrecognized command '" << command << "'";
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
DoReboot(cmd, reason_string, reboot_target, runFsck);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_trigger(const std::vector<std::string>& args) {
|
static int do_trigger(const std::vector<std::string>& args) {
|
||||||
ActionManager::GetInstance().QueueEventTrigger(args[1]);
|
ActionManager::GetInstance().QueueEventTrigger(args[1]);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -919,7 +867,6 @@ BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
|
||||||
{"mount_all", {1, kMax, do_mount_all}},
|
{"mount_all", {1, kMax, do_mount_all}},
|
||||||
{"mount", {3, kMax, do_mount}},
|
{"mount", {3, kMax, do_mount}},
|
||||||
{"umount", {1, 1, do_umount}},
|
{"umount", {1, 1, do_umount}},
|
||||||
{"powerctl", {1, 1, do_powerctl}},
|
|
||||||
{"restart", {1, 1, do_restart}},
|
{"restart", {1, 1, do_restart}},
|
||||||
{"restorecon", {1, kMax, do_restorecon}},
|
{"restorecon", {1, kMax, do_restorecon}},
|
||||||
{"restorecon_recursive", {1, kMax, do_restorecon_recursive}},
|
{"restorecon_recursive", {1, kMax, do_restorecon_recursive}},
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@
|
||||||
#include "keychords.h"
|
#include "keychords.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "property_service.h"
|
#include "property_service.h"
|
||||||
|
#include "reboot.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
#include "signal_handler.h"
|
#include "signal_handler.h"
|
||||||
#include "ueventd.h"
|
#include "ueventd.h"
|
||||||
|
|
@ -153,8 +154,13 @@ bool start_waiting_for_property(const char *name, const char *value)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void property_changed(const char *name, const char *value)
|
void property_changed(const std::string& name, const std::string& value) {
|
||||||
{
|
// If the property is sys.powerctl, we bypass the event queue and immediately handle it.
|
||||||
|
// This is to ensure that init will always and immediately shutdown/reboot, regardless of
|
||||||
|
// if there are other pending events to process or if init is waiting on an exec service or
|
||||||
|
// waiting on a property.
|
||||||
|
if (name == "sys.powerctl") HandlePowerctlMessage(value);
|
||||||
|
|
||||||
if (property_triggers_enabled)
|
if (property_triggers_enabled)
|
||||||
ActionManager::GetInstance().QueuePropertyTrigger(name, value);
|
ActionManager::GetInstance().QueuePropertyTrigger(name, value);
|
||||||
if (waiting_for_prop) {
|
if (waiting_for_prop) {
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ extern struct selabel_handle *sehandle_prop;
|
||||||
|
|
||||||
void handle_control_message(const std::string& msg, const std::string& arg);
|
void handle_control_message(const std::string& msg, const std::string& arg);
|
||||||
|
|
||||||
void property_changed(const char *name, const char *value);
|
void property_changed(const std::string& name, const std::string& value);
|
||||||
|
|
||||||
void register_epoll_handler(int fd, void (*fn)());
|
void register_epoll_handler(int fd, void (*fn)());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ uint32_t property_set(const std::string& name, const std::string& value) {
|
||||||
if (persistent_properties_loaded && android::base::StartsWith(name, "persist.")) {
|
if (persistent_properties_loaded && android::base::StartsWith(name, "persist.")) {
|
||||||
write_persistent_property(name.c_str(), value.c_str());
|
write_persistent_property(name.c_str(), value.c_str());
|
||||||
}
|
}
|
||||||
property_changed(name.c_str(), value.c_str());
|
property_changed(name, value);
|
||||||
return PROP_SUCCESS;
|
return PROP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -425,3 +425,54 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
|
||||||
RebootSystem(cmd, rebootTarget);
|
RebootSystem(cmd, rebootTarget);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HandlePowerctlMessage(const std::string& command) {
|
||||||
|
unsigned int cmd = 0;
|
||||||
|
std::vector<std::string> cmd_params = android::base::Split(command, ",");
|
||||||
|
std::string reason_string = cmd_params[0];
|
||||||
|
std::string reboot_target = "";
|
||||||
|
bool run_fsck = false;
|
||||||
|
bool command_invalid = false;
|
||||||
|
|
||||||
|
if (cmd_params.size() > 3) {
|
||||||
|
command_invalid = true;
|
||||||
|
} else if (cmd_params[0] == "shutdown") {
|
||||||
|
cmd = ANDROID_RB_POWEROFF;
|
||||||
|
if (cmd_params.size() == 2 && cmd_params[1] == "userrequested") {
|
||||||
|
// The shutdown reason is PowerManager.SHUTDOWN_USER_REQUESTED.
|
||||||
|
// Run fsck once the file system is remounted in read-only mode.
|
||||||
|
run_fsck = true;
|
||||||
|
reason_string = cmd_params[1];
|
||||||
|
}
|
||||||
|
} else if (cmd_params[0] == "reboot") {
|
||||||
|
cmd = ANDROID_RB_RESTART2;
|
||||||
|
if (cmd_params.size() >= 2) {
|
||||||
|
reboot_target = cmd_params[1];
|
||||||
|
// When rebooting to the bootloader notify the bootloader writing
|
||||||
|
// also the BCB.
|
||||||
|
if (reboot_target == "bootloader") {
|
||||||
|
std::string err;
|
||||||
|
if (!write_reboot_bootloader(&err)) {
|
||||||
|
LOG(ERROR) << "reboot-bootloader: Error writing "
|
||||||
|
"bootloader_message: "
|
||||||
|
<< err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If there is an additional bootloader parameter, pass it along
|
||||||
|
if (cmd_params.size() == 3) {
|
||||||
|
reboot_target += "," + cmd_params[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (command == "thermal-shutdown") { // no additional parameter allowed
|
||||||
|
cmd = ANDROID_RB_THERMOFF;
|
||||||
|
} else {
|
||||||
|
command_invalid = true;
|
||||||
|
}
|
||||||
|
if (command_invalid) {
|
||||||
|
LOG(ERROR) << "powerctl: unrecognized command '" << command << "'";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DoReboot(cmd, reason_string, reboot_target, run_fsck);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,4 +29,7 @@
|
||||||
void DoReboot(unsigned int cmd, const std::string& reason, const std::string& rebootTarget,
|
void DoReboot(unsigned int cmd, const std::string& reason, const std::string& rebootTarget,
|
||||||
bool runFsck) __attribute__((__noreturn__));
|
bool runFsck) __attribute__((__noreturn__));
|
||||||
|
|
||||||
|
// Parses and handles a setprop sys.powerctl message.
|
||||||
|
bool HandlePowerctlMessage(const std::string& command);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -638,9 +638,6 @@ on property:vold.decrypt=trigger_shutdown_framework
|
||||||
class_reset late_start
|
class_reset late_start
|
||||||
class_reset main
|
class_reset main
|
||||||
|
|
||||||
on property:sys.powerctl=*
|
|
||||||
powerctl ${sys.powerctl}
|
|
||||||
|
|
||||||
on property:sys.boot_completed=1
|
on property:sys.boot_completed=1
|
||||||
bootchart stop
|
bootchart stop
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue