init: make reboot_on_failure not apply to manually stopped services
Add a new service flag SVC_STOPPING which tracks whether a service is
being manually stopped by init, and make the "reboot_on_failure" service
setting not apply when SVC_STOPPING is set.
This is needed for devices that use FDE, because otherwise the device
reboots during the following init script fragment:
on property:vold.decrypt=trigger_shutdown_framework
class_reset late_start
class_reset main
class_reset_post_data core
class_reset_post_data hal
... because that stops all services, including apexd which has been
marked with reboot_on_failure since
https://android-review.googlesource.com/c/platform/system/apex/+/1325212.
So init was killing apexd, then rebooting the device because apexd
"failed" due to having been killed. Making reboot_on_failure not apply
when init stops a service itself fixes the problem.
This is one of a set of changes that is needed to get FDE working again
so that devices that launched with FDE can be upgraded to Android 12.
Bug: 186165644
Test: Tested FDE on Cuttlefish
Change-Id: I599f7ba107e6c126e8f31d0ae659f0ae672a25e4
diff --git a/init/service.cpp b/init/service.cpp
index c3069f5..5af81bf 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -194,6 +194,8 @@
<< ") process group...";
int max_processes = 0;
int r;
+
+ flags_ |= SVC_STOPPING;
if (signal == SIGTERM) {
r = killProcessGroupOnce(proc_attr_.uid, pid_, signal, &max_processes);
} else {
@@ -277,7 +279,8 @@
f(siginfo);
}
- if ((siginfo.si_code != CLD_EXITED || siginfo.si_status != 0) && on_failure_reboot_target_) {
+ if ((siginfo.si_code != CLD_EXITED || siginfo.si_status != 0) && on_failure_reboot_target_ &&
+ !(flags_ & SVC_STOPPING)) {
LOG(ERROR) << "Service with 'reboot_on_failure' option failed, shutting down system.";
trigger_shutdown(*on_failure_reboot_target_);
}
@@ -287,7 +290,7 @@
if (flags_ & SVC_TEMPORARY) return;
pid_ = 0;
- flags_ &= (~SVC_RUNNING);
+ flags_ &= ~(SVC_RUNNING | SVC_STOPPING);
start_order_ = 0;
// Oneshot processes go into the disabled state on exit,
@@ -411,7 +414,8 @@
bool disabled = (flags_ & (SVC_DISABLED | SVC_RESET));
// Starting a service removes it from the disabled or reset state and
// immediately takes it out of the restarting state if it was in there.
- flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
+ flags_ &= (~(SVC_DISABLED | SVC_RESTARTING | SVC_RESET | SVC_RESTART | SVC_DISABLED_START |
+ SVC_STOPPING));
// Running processes require no additional work --- if they're in the
// process of exiting, we've ensured that they will immediately restart