From f0ab5b17f6b145c7ea25fd4f90b3ae1c0472ca14 Mon Sep 17 00:00:00 2001 From: Nikita Ioffe Date: Wed, 25 Mar 2020 00:06:51 +0000 Subject: [PATCH] Use properties for various userspace reboot timeouts Test: adb reboot userspace Bug: 146560409 Change-Id: I435e4f93a8769ff7d30cf781e0b48fa3e96121ef Merged-In: I435e4f93a8769ff7d30cf781e0b48fa3e96121ef (cherry picked from commit 7b41a1558d003084f201c361c8a4f12058f533a9) --- fs_mgr/fs_mgr.cpp | 10 ++++++++-- init/reboot.cpp | 26 ++++++++++++++++++-------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index 46018b955..12aa1f092 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -96,6 +96,7 @@ using android::base::Basename; using android::base::GetBoolProperty; +using android::base::GetUintProperty; using android::base::Readlink; using android::base::Realpath; using android::base::SetProperty; @@ -1566,11 +1567,16 @@ int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab) { return ret; } +static std::chrono::milliseconds GetMillisProperty(const std::string& name, + std::chrono::milliseconds default_value) { + auto value = GetUintProperty(name, static_cast(default_value.count())); + return std::chrono::milliseconds(std::move(value)); +} + static bool fs_mgr_unmount_all_data_mounts(const std::string& block_device) { LINFO << __FUNCTION__ << "(): about to umount everything on top of " << block_device; Timer t; - // TODO(b/135984674): should be configured via a read-only property. - std::chrono::milliseconds timeout = 5s; + auto timeout = GetMillisProperty("init.userspace_reboot.userdata_remount.timeoutmillis", 5s); while (true) { bool umount_done = true; Fstab proc_mounts; diff --git a/init/reboot.cpp b/init/reboot.cpp index f006df3a3..081f6953a 100644 --- a/init/reboot.cpp +++ b/init/reboot.cpp @@ -72,6 +72,7 @@ using namespace std::literals; using android::base::boot_clock; using android::base::GetBoolProperty; +using android::base::GetUintProperty; using android::base::SetProperty; using android::base::Split; using android::base::Timer; @@ -732,6 +733,12 @@ static Result UnmountAllApexes() { return Error() << "'/system/bin/apexd --unmount-all' failed : " << status; } +static std::chrono::milliseconds GetMillisProperty(const std::string& name, + std::chrono::milliseconds default_value) { + auto value = GetUintProperty(name, static_cast(default_value.count())); + return std::chrono::milliseconds(std::move(value)); +} + static Result DoUserspaceReboot() { LOG(INFO) << "Userspace reboot initiated"; auto guard = android::base::make_scope_guard([] { @@ -769,10 +776,13 @@ static Result DoUserspaceReboot() { sync(); LOG(INFO) << "sync() took " << sync_timer; } - // TODO(b/135984674): do we need shutdown animation for userspace reboot? - // TODO(b/135984674): control userspace timeout via read-only property? - StopServicesAndLogViolations(stop_first, 10s, true /* SIGTERM */); - if (int r = StopServicesAndLogViolations(stop_first, 20s, false /* SIGKILL */); r > 0) { + auto sigterm_timeout = GetMillisProperty("init.userspace_reboot.sigterm.timeoutmillis", 5s); + auto sigkill_timeout = GetMillisProperty("init.userspace_reboot.sigkill.timeoutmillis", 10s); + LOG(INFO) << "Timeout to terminate services : " << sigterm_timeout.count() << "ms" + << "Timeout to kill services: " << sigkill_timeout.count() << "ms"; + StopServicesAndLogViolations(stop_first, sigterm_timeout, true /* SIGTERM */); + if (int r = StopServicesAndLogViolations(stop_first, sigkill_timeout, false /* SIGKILL */); + r > 0) { // TODO(b/135984674): store information about offending services for debugging. return Error() << r << " post-data services are still running"; } @@ -782,8 +792,8 @@ static Result DoUserspaceReboot() { if (auto result = CallVdc("volume", "reset"); !result.ok()) { return result; } - if (int r = StopServicesAndLogViolations(GetDebuggingServices(true /* only_post_data */), 5s, - false /* SIGKILL */); + if (int r = StopServicesAndLogViolations(GetDebuggingServices(true /* only_post_data */), + sigkill_timeout, false /* SIGKILL */); r > 0) { // TODO(b/135984674): store information about offending services for debugging. return Error() << r << " debugging services are still running"; @@ -827,8 +837,8 @@ static void UserspaceRebootWatchdogThread() { return; } LOG(INFO) << "Starting userspace reboot watchdog"; - // TODO(b/135984674): this should be configured via a read-only sysprop. - std::chrono::milliseconds timeout = 60s; + auto timeout = GetMillisProperty("init.userspace_reboot.watchdog.timeoutmillis", 5min); + LOG(INFO) << "UserspaceRebootWatchdog timeout: " << timeout.count() << "ms"; if (!WaitForProperty("sys.boot_completed", "1", timeout)) { LOG(ERROR) << "Failed to boot in " << timeout.count() << "ms. Switching to full reboot"; // In this case device is in a boot loop. Only way to recover is to do dirty reboot.