Fallback to hard reboot if userspace reboot hasn't started in time
Similarly to other recovery mechanisms, timeout is controlled by a
read-only property that can be configured per-device.
Test: adb root
Test: adb shell setprop init.userspace_reboot.started.timeoutmillis 2
Test: adb reboot userspace
Bug: 152803929
Change-Id: Id70710b46da798945ac5422ef7d69265911ea5ef
Merged-In: Id70710b46da798945ac5422ef7d69265911ea5ef
(cherry picked from commit d05535485f7a818cda3bfa4b61bfd071be56b36f)
diff --git a/init/reboot.cpp b/init/reboot.cpp
index d2dc6d3..2f91663 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -838,20 +838,25 @@
}
static void UserspaceRebootWatchdogThread() {
- if (!WaitForProperty("sys.init.userspace_reboot.in_progress", "1", 20s)) {
- // TODO(b/135984674): should we reboot instead?
- LOG(WARNING) << "Userspace reboot didn't start in 20 seconds. Stopping watchdog";
- return;
+ auto started_timeout = GetMillisProperty("init.userspace_reboot.started.timeoutmillis", 10s);
+ if (!WaitForProperty("sys.init.userspace_reboot.in_progress", "1", started_timeout)) {
+ LOG(ERROR) << "Userspace reboot didn't start in " << started_timeout.count()
+ << "ms. Switching to full reboot";
+ // Init might be wedged, don't try to write reboot reason into a persistent property and do
+ // a dirty reboot.
+ PersistRebootReason("userspace_failed,watchdog_triggered,failed_to_start", false);
+ RebootSystem(ANDROID_RB_RESTART2, "userspace_failed,watchdog_triggered,failed_to_start");
}
LOG(INFO) << "Starting userspace reboot watchdog";
- 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";
+ auto watchdog_timeout = GetMillisProperty("init.userspace_reboot.watchdog.timeoutmillis", 5min);
+ LOG(INFO) << "UserspaceRebootWatchdog timeout: " << watchdog_timeout.count() << "ms";
+ if (!WaitForProperty("sys.boot_completed", "1", watchdog_timeout)) {
+ LOG(ERROR) << "Failed to boot in " << watchdog_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.
// Since init might be wedged, don't try to write reboot reason into a persistent property.
- PersistRebootReason("userspace_failed,watchdog_triggered", false);
- RebootSystem(ANDROID_RB_RESTART2, "userspace_failed,watchdog_triggered");
+ PersistRebootReason("userspace_failed,watchdog_triggered,failed_to_boot", false);
+ RebootSystem(ANDROID_RB_RESTART2, "userspace_failed,watchdog_triggered,failed_to_boot");
}
LOG(INFO) << "Device booted, stopping userspace reboot watchdog";
}