22
22
#include < linux/loop.h>
23
23
#include < mntent.h>
24
24
#include < semaphore.h>
25
+ #include < stdlib.h>
25
26
#include < sys/cdefs.h>
26
27
#include < sys/ioctl.h>
27
28
#include < sys/mount.h>
31
32
#include < sys/types.h>
32
33
#include < sys/wait.h>
33
34
35
+ #include < chrono>
34
36
#include < memory>
35
37
#include < set>
36
38
#include < thread>
41
43
#include < android-base/logging.h>
42
44
#include < android-base/macros.h>
43
45
#include < android-base/properties.h>
46
+ #include < android-base/scopeguard.h>
44
47
#include < android-base/strings.h>
45
48
#include < android-base/unique_fd.h>
46
49
#include < bootloader_message/bootloader_message.h>
59
62
#include " service.h"
60
63
#include " service_list.h"
61
64
#include " sigchld_handler.h"
65
+ #include " util.h"
62
66
63
67
#define PROC_SYSRQ " /proc/sysrq-trigger"
64
68
@@ -75,6 +79,19 @@ namespace init {
75
79
76
80
static bool shutting_down = false ;
77
81
82
+ static const std::set<std::string> kDebuggingServices {" tombstoned" , " logd" , " adbd" , " console" };
83
+
84
+ static std::vector<Service*> GetDebuggingServices (bool only_post_data) {
85
+ std::vector<Service*> ret;
86
+ ret.reserve (kDebuggingServices .size ());
87
+ for (const auto & s : ServiceList::GetInstance ()) {
88
+ if (kDebuggingServices .count (s->name ()) && (!only_post_data || s->is_post_data ())) {
89
+ ret.push_back (s.get ());
90
+ }
91
+ }
92
+ return ret;
93
+ }
94
+
78
95
// represents umount status during reboot / shutdown.
79
96
enum UmountStat {
80
97
/* umount succeeded. */
@@ -446,6 +463,49 @@ static void KillZramBackingDevice() {
446
463
LOG (INFO) << " zram_backing_dev: `" << backing_dev << " ` is cleared successfully." ;
447
464
}
448
465
466
+ // Stops given services, waits for them to be stopped for |timeout| ms.
467
+ // If terminate is true, then SIGTERM is sent to services, otherwise SIGKILL is sent.
468
+ static void StopServices (const std::vector<Service*>& services, std::chrono::milliseconds timeout,
469
+ bool terminate) {
470
+ LOG (INFO) << " Stopping " << services.size () << " services by sending "
471
+ << (terminate ? " SIGTERM" : " SIGKILL" );
472
+ std::vector<pid_t > pids;
473
+ pids.reserve (services.size ());
474
+ for (const auto & s : services) {
475
+ if (s->pid () > 0 ) {
476
+ pids.push_back (s->pid ());
477
+ }
478
+ if (terminate) {
479
+ s->Terminate ();
480
+ } else {
481
+ s->Stop ();
482
+ }
483
+ }
484
+ if (timeout > 0ms) {
485
+ WaitToBeReaped (pids, timeout);
486
+ } else {
487
+ // Even if we don't to wait for services to stop, we still optimistically reap zombies.
488
+ ReapAnyOutstandingChildren ();
489
+ }
490
+ }
491
+
492
+ // Like StopServices, but also logs all the services that failed to stop after the provided timeout.
493
+ // Returns number of violators.
494
+ static int StopServicesAndLogViolations (const std::vector<Service*>& services,
495
+ std::chrono::milliseconds timeout, bool terminate) {
496
+ StopServices (services, timeout, terminate);
497
+ int still_running = 0 ;
498
+ for (const auto & s : services) {
499
+ if (s->IsRunning ()) {
500
+ LOG (ERROR) << " [service-misbehaving] : service '" << s->name () << " ' is still running "
501
+ << timeout.count () << " ms after receiving "
502
+ << (terminate ? " SIGTERM" : " SIGKILL" );
503
+ still_running++;
504
+ }
505
+ }
506
+ return still_running;
507
+ }
508
+
449
509
// * Reboot / shutdown the system.
450
510
// cmd ANDROID_RB_* as defined in android_reboot.h
451
511
// reason Reason string like "reboot", "shutdown,userrequested"
@@ -510,12 +570,13 @@ static void DoReboot(unsigned int cmd, const std::string& reason, const std::str
510
570
// Start reboot monitor thread
511
571
sem_post (&reboot_semaphore);
512
572
513
- // keep debugging tools until non critical ones are all gone.
514
- const std::set<std::string> kill_after_apps{" tombstoned" , " logd" , " adbd" };
515
573
// watchdogd is a vendor specific component but should be alive to complete shutdown safely.
516
574
const std::set<std::string> to_starts{" watchdogd" };
575
+ std::vector<Service*> stop_first;
576
+ stop_first.reserve (ServiceList::GetInstance ().services ().size ());
517
577
for (const auto & s : ServiceList::GetInstance ()) {
518
- if (kill_after_apps.count (s->name ())) {
578
+ if (kDebuggingServices .count (s->name ())) {
579
+ // keep debugging tools until non critical ones are all gone.
519
580
s->SetShutdownCritical ();
520
581
} else if (to_starts.count (s->name ())) {
521
582
if (auto result = s->Start (); !result) {
@@ -529,6 +590,8 @@ static void DoReboot(unsigned int cmd, const std::string& reason, const std::str
529
590
LOG (ERROR) << " Could not start shutdown critical service '" << s->name ()
530
591
<< " ': " << result.error ();
531
592
}
593
+ } else {
594
+ stop_first.push_back (s.get ());
532
595
}
533
596
}
534
597
@@ -571,49 +634,12 @@ static void DoReboot(unsigned int cmd, const std::string& reason, const std::str
571
634
// optional shutdown step
572
635
// 1. terminate all services except shutdown critical ones. wait for delay to finish
573
636
if (shutdown_timeout > 0ms) {
574
- LOG (INFO) << " terminating init services" ;
575
-
576
- // Ask all services to terminate except shutdown critical ones.
577
- for (const auto & s : ServiceList::GetInstance ().services_in_shutdown_order ()) {
578
- if (!s->IsShutdownCritical ()) s->Terminate ();
579
- }
580
-
581
- int service_count = 0 ;
582
- // Only wait up to half of timeout here
583
- auto termination_wait_timeout = shutdown_timeout / 2 ;
584
- while (t.duration () < termination_wait_timeout) {
585
- ReapAnyOutstandingChildren ();
586
-
587
- service_count = 0 ;
588
- for (const auto & s : ServiceList::GetInstance ()) {
589
- // Count the number of services running except shutdown critical.
590
- // Exclude the console as it will ignore the SIGTERM signal
591
- // and not exit.
592
- // Note: SVC_CONSOLE actually means "requires console" but
593
- // it is only used by the shell.
594
- if (!s->IsShutdownCritical () && s->pid () != 0 && (s->flags () & SVC_CONSOLE) == 0 ) {
595
- service_count++;
596
- }
597
- }
598
-
599
- if (service_count == 0 ) {
600
- // All terminable services terminated. We can exit early.
601
- break ;
602
- }
603
-
604
- // Wait a bit before recounting the number or running services.
605
- std::this_thread::sleep_for (50ms);
606
- }
607
- LOG (INFO) << " Terminating running services took " << t
608
- << " with remaining services:" << service_count;
609
- }
610
-
611
- // minimum safety steps before restarting
612
- // 2. kill all services except ones that are necessary for the shutdown sequence.
613
- for (const auto & s : ServiceList::GetInstance ().services_in_shutdown_order ()) {
614
- if (!s->IsShutdownCritical ()) s->Stop ();
637
+ StopServicesAndLogViolations (stop_first, shutdown_timeout / 2 , true /* SIGTERM */ );
615
638
}
639
+ // Send SIGKILL to ones that didn't terminate cleanly.
640
+ StopServicesAndLogViolations (stop_first, 0ms, false /* SIGKILL */ );
616
641
SubcontextTerminate ();
642
+ // Reap subcontext pids.
617
643
ReapAnyOutstandingChildren ();
618
644
619
645
// 3. send volume shutdown to vold
@@ -625,9 +651,7 @@ static void DoReboot(unsigned int cmd, const std::string& reason, const std::str
625
651
LOG (INFO) << " vold not running, skipping vold shutdown" ;
626
652
}
627
653
// logcat stopped here
628
- for (const auto & s : ServiceList::GetInstance ().services_in_shutdown_order ()) {
629
- if (kill_after_apps.count (s->name ())) s->Stop ();
630
- }
654
+ StopServices (GetDebuggingServices (false /* only_post_data */ ), 0ms, false /* SIGKILL */ );
631
655
// 4. sync, try umount, and optionally run fsck for user shutdown
632
656
{
633
657
Timer sync_timer;
@@ -660,6 +684,7 @@ static void DoReboot(unsigned int cmd, const std::string& reason, const std::str
660
684
}
661
685
662
686
static void EnterShutdown () {
687
+ LOG (INFO) << " Entering shutdown mode" ;
663
688
shutting_down = true ;
664
689
// Skip wait for prop if it is in progress
665
690
ResetWaitForProp ();
@@ -675,32 +700,69 @@ static void EnterShutdown() {
675
700
}
676
701
677
702
static void LeaveShutdown () {
703
+ LOG (INFO) << " Leaving shutdown mode" ;
678
704
shutting_down = false ;
679
705
SendStartSendingMessagesMessage ();
680
706
}
681
707
682
- static void DoUserspaceReboot () {
708
+ static Result<void > DoUserspaceReboot () {
709
+ LOG (INFO) << " Userspace reboot initiated" ;
710
+ auto guard = android::base::make_scope_guard ([] {
711
+ // Leave shutdown so that we can handle a full reboot.
712
+ LeaveShutdown ();
713
+ property_set (" sys.powerctl" , " reboot,abort-userspace-reboot" );
714
+ });
683
715
// Triggering userspace-reboot-requested will result in a bunch of set_prop
684
716
// actions. We should make sure, that all of them are propagated before
685
717
// proceeding with userspace reboot.
686
718
// TODO(b/135984674): implement proper synchronization logic.
687
719
std::this_thread::sleep_for (500ms);
688
720
EnterShutdown ();
689
- // TODO(b/135984674): tear down post-data services
690
- LeaveShutdown ();
721
+ std::vector<Service*> stop_first;
722
+ // Remember the services that were enabled. We will need to manually enable them again otherwise
723
+ // triggers like class_start won't restart them.
724
+ std::vector<Service*> were_enabled;
725
+ stop_first.reserve (ServiceList::GetInstance ().services ().size ());
726
+ for (const auto & s : ServiceList::GetInstance ().services_in_shutdown_order ()) {
727
+ if (s->is_post_data () && !kDebuggingServices .count (s->name ())) {
728
+ stop_first.push_back (s);
729
+ }
730
+ if (s->is_post_data () && s->IsEnabled ()) {
731
+ were_enabled.push_back (s);
732
+ }
733
+ }
734
+ // TODO(b/135984674): do we need shutdown animation for userspace reboot?
735
+ // TODO(b/135984674): control userspace timeout via read-only property?
736
+ StopServicesAndLogViolations (stop_first, 10s, true /* SIGTERM */ );
737
+ if (int r = StopServicesAndLogViolations (stop_first, 20s, false /* SIGKILL */ ); r > 0 ) {
738
+ // TODO(b/135984674): store information about offending services for debugging.
739
+ return Error () << r << " post-data services are still running" ;
740
+ }
691
741
// TODO(b/135984674): remount userdata
742
+ if (int r = StopServicesAndLogViolations (GetDebuggingServices (true /* only_post_data */ ), 5s,
743
+ false /* SIGKILL */ );
744
+ r > 0 ) {
745
+ // TODO(b/135984674): store information about offending services for debugging.
746
+ return Error () << r << " debugging services are still running" ;
747
+ }
748
+ // TODO(b/135984674): deactivate APEX modules and switch back to bootstrap namespace.
749
+ // Re-enable services
750
+ for (const auto & s : were_enabled) {
751
+ LOG (INFO) << " Re-enabling service '" << s->name () << " '" ;
752
+ s->Enable ();
753
+ }
754
+ LeaveShutdown ();
692
755
ActionManager::GetInstance ().QueueEventTrigger (" userspace-reboot-resume" );
756
+ guard.Disable (); // Go on with userspace reboot.
757
+ return {};
693
758
}
694
759
695
760
static void HandleUserspaceReboot () {
696
761
LOG (INFO) << " Clearing queue and starting userspace-reboot-requested trigger" ;
697
762
auto & am = ActionManager::GetInstance ();
698
763
am.ClearQueue ();
699
764
am.QueueEventTrigger (" userspace-reboot-requested" );
700
- auto handler = [](const BuiltinArguments&) {
701
- DoUserspaceReboot ();
702
- return Result<void >{};
703
- };
765
+ auto handler = [](const BuiltinArguments&) { return DoUserspaceReboot (); };
704
766
am.QueueBuiltinAction (handler, " userspace-reboot" );
705
767
}
706
768
0 commit comments