init: Shutdown services and umount partitions
This would gracefully terminate the services which are preventing partition unmount.
All the pending services which weren't terminated will receive SIGTERM.
With this patch:
1: Unmount partitions cleanly and not fallback to killing all processes
because of timeout.
2: During user requested device poweroff, fsck would be run as partitions are successfully unmounted.
3: The shutdown / reboot cycle cuts down to ~4 seconds compared to 6 seconds improving the end-to-end reboot.
Bug: 398083419
Test: adb reboot / power-off cycles on Pixel
Average shutdown time after 15 reboot cycles:
With this patch: 4.169 seconds
Without this patch: 6.3 seconds
Change-Id: Idf22145cbc86d090e4982f3e22ef76f92ddd92e5
Signed-off-by: Akilesh Kailash <akailash@google.com>
diff --git a/init/reboot.cpp b/init/reboot.cpp
index d7ad861..a26149f 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -268,6 +268,19 @@
}
static UmountStat UmountPartitions(std::chrono::milliseconds timeout) {
+ // Terminate (SIGTERM) the services before unmounting partitions.
+ // If the processes block the signal, then partitions will eventually fail
+ // to unmount and then we fallback to SIGKILL the services.
+ //
+ // Hence, give the services a chance for a graceful shutdown before sending SIGKILL.
+ for (const auto& s : ServiceList::GetInstance()) {
+ if (s->IsShutdownCritical()) {
+ LOG(INFO) << "Shutdown service: " << s->name();
+ s->Terminate();
+ }
+ }
+ ReapAnyOutstandingChildren();
+
Timer t;
/* data partition needs all pending writes to be completed and all emulated partitions
* umounted.If the current waiting is not good enough, give
@@ -815,6 +828,7 @@
if (IsDataMounted("f2fs")) {
uint32_t flag = F2FS_GOING_DOWN_FULLSYNC;
unique_fd fd(TEMP_FAILURE_RETRY(open("/data", O_RDONLY)));
+ LOG(INFO) << "Invoking F2FS_IOC_SHUTDOWN during shutdown";
int ret = ioctl(fd.get(), F2FS_IOC_SHUTDOWN, &flag);
if (ret) {
PLOG(ERROR) << "Shutdown /data: ";