init: Do full shutdown even for thermal shutdown
- Skipping SIGTERM / SIGKILL / umount brings race between block device driver and fs layer. Do umount before shutting down. - Reduce timeout to 1 sec for thermal shutdown and skip other time taking part like fsck. - Refactor waiting part to check time in ms so that 1 sec can have enough resolution. bug: 63686426 Test: adb shell setprop sys.powerctl thermal-shutdown, adb shell setprop sys.powerctl reboot and check dmesg Merged-In: I048bac767b328c8d656a97fe65dde5f2b5bf4ae5 Change-Id: I048bac767b328c8d656a97fe65dde5f2b5bf4ae5
This commit is contained in:
parent
c5aba9702e
commit
c111537f5d
|
@ -304,13 +304,6 @@ static UmountStat TryUmountAndFsck(bool runFsck, int timeoutMs) {
|
|||
return stat;
|
||||
}
|
||||
|
||||
static void __attribute__((noreturn)) DoThermalOff() {
|
||||
LOG(WARNING) << "Thermal system shutdown";
|
||||
sync();
|
||||
RebootSystem(ANDROID_RB_THERMOFF, "");
|
||||
abort();
|
||||
}
|
||||
|
||||
void DoReboot(unsigned int cmd, const std::string& reason, const std::string& rebootTarget,
|
||||
bool runFsck) {
|
||||
Timer t;
|
||||
|
@ -319,20 +312,25 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
|
|||
android::base::WriteStringToFile(StringPrintf("%s\n", reason.c_str()), LAST_REBOOT_REASON_FILE,
|
||||
S_IRUSR | S_IWUSR, AID_SYSTEM, AID_SYSTEM);
|
||||
|
||||
if (cmd == ANDROID_RB_THERMOFF) { // do not wait if it is thermal
|
||||
DoThermalOff();
|
||||
abort();
|
||||
bool is_thermal_shutdown = false;
|
||||
if (cmd == ANDROID_RB_THERMOFF) {
|
||||
is_thermal_shutdown = true;
|
||||
runFsck = false;
|
||||
}
|
||||
|
||||
constexpr unsigned int shutdownTimeoutDefault = 6;
|
||||
unsigned int shutdownTimeout = shutdownTimeoutDefault;
|
||||
if (SHUTDOWN_ZERO_TIMEOUT) { // eng build
|
||||
shutdownTimeout = 0;
|
||||
} else {
|
||||
shutdownTimeout =
|
||||
android::base::GetUintProperty("ro.build.shutdown_timeout", shutdownTimeoutDefault);
|
||||
unsigned int shutdown_timeout = 0; // ms
|
||||
if (!SHUTDOWN_ZERO_TIMEOUT) {
|
||||
if (is_thermal_shutdown) {
|
||||
constexpr unsigned int thermal_shutdown_timeout = 1; // sec
|
||||
shutdown_timeout = thermal_shutdown_timeout * 1000;
|
||||
} else {
|
||||
constexpr unsigned int shutdown_timeout_default = 6; // sec
|
||||
auto shutdown_timeout_property = android::base::GetUintProperty(
|
||||
"ro.build.shutdown_timeout", shutdown_timeout_default);
|
||||
shutdown_timeout = shutdown_timeout_property * 1000;
|
||||
}
|
||||
}
|
||||
LOG(INFO) << "Shutdown timeout: " << shutdownTimeout;
|
||||
LOG(INFO) << "Shutdown timeout: " << shutdown_timeout << " ms";
|
||||
|
||||
// keep debugging tools until non critical ones are all gone.
|
||||
const std::set<std::string> kill_after_apps{"tombstoned", "logd", "adbd"};
|
||||
|
@ -359,7 +357,7 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
|
|||
|
||||
// optional shutdown step
|
||||
// 1. terminate all services except shutdown critical ones. wait for delay to finish
|
||||
if (shutdownTimeout > 0) {
|
||||
if (shutdown_timeout > 0) {
|
||||
LOG(INFO) << "terminating init services";
|
||||
|
||||
// Ask all services to terminate except shutdown critical ones.
|
||||
|
@ -368,9 +366,9 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
|
|||
});
|
||||
|
||||
int service_count = 0;
|
||||
// Up to half as long as shutdownTimeout or 3 seconds, whichever is lower.
|
||||
unsigned int terminationWaitTimeout = std::min<unsigned int>((shutdownTimeout + 1) / 2, 3);
|
||||
while (t.duration_s() < terminationWaitTimeout) {
|
||||
// Only wait up to half of timeout here
|
||||
auto termination_wait_timeout = shutdown_timeout / 2;
|
||||
while (t.duration_ms() < termination_wait_timeout) {
|
||||
ServiceManager::GetInstance().ReapAnyOutstandingChildren();
|
||||
|
||||
service_count = 0;
|
||||
|
@ -418,10 +416,10 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
|
|||
});
|
||||
// 4. sync, try umount, and optionally run fsck for user shutdown
|
||||
sync();
|
||||
UmountStat stat = TryUmountAndFsck(runFsck, shutdownTimeout * 1000 - t.duration_ms());
|
||||
UmountStat stat = TryUmountAndFsck(runFsck, shutdown_timeout - t.duration_ms());
|
||||
// Follow what linux shutdown is doing: one more sync with little bit delay
|
||||
sync();
|
||||
std::this_thread::sleep_for(100ms);
|
||||
if (!is_thermal_shutdown) std::this_thread::sleep_for(100ms);
|
||||
LogShutdownTime(stat, &t);
|
||||
// Reboot regardless of umount status. If umount fails, fsck after reboot will fix it.
|
||||
RebootSystem(cmd, rebootTarget);
|
||||
|
|
Loading…
Reference in New Issue