init: change kill order and fix error reporting in KillProcessGroup()

First kill the process group before killing the cgroup to catch
the hopeful case that killing the cgroup becomes a no-op as all of its
processes have already been killed.

Do not report an error if kill fails due to ESRCH, as this happens
often when reaping processes due to the order in which we call
waitpid() and kill().

Do not call killProcessGroup in libprocessgroup if we have already
successfully killed and removed a process group.

Bug: 36661364
Bug: 36701253
Bug: 37540956

Test: Reboot bullhead
Test: Start and stop services
Test: Init unit tests
Change-Id: I172acf0f8e00189f910f865f4635a7b1782fc7e3
diff --git a/init/service.cpp b/init/service.cpp
index 3a9f622..881825f 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -209,21 +209,33 @@
 }
 
 void Service::KillProcessGroup(int signal) {
-    LOG(INFO) << "Sending signal " << signal
-              << " to service '" << name_
-              << "' (pid " << pid_ << ") process group...";
-    int r;
-    if (signal == SIGTERM) {
-        r = killProcessGroupOnce(uid_, pid_, signal);
-    } else {
-        r = killProcessGroup(uid_, pid_, signal);
-    }
-    if (r == -1) {
-        LOG(ERROR) << "killProcessGroup(" << uid_ << ", " << pid_ << ", " << signal << ") failed";
-    }
-    if (kill(-pid_, signal) == -1) {
+    // We ignore reporting errors of ESRCH as this commonly happens in the below case,
+    // 1) Terminate() is called, which sends SIGTERM to the process
+    // 2) The process successfully exits
+    // 3) ReapOneProcess() is called, which calls waitpid(-1, ...) which removes the pid entry.
+    // 4) Reap() is called, which sends SIGKILL, but the pid no longer exists.
+    // TODO: sigaction for SIGCHLD reports the pid of the exiting process,
+    // we should do this kill with that pid first before calling waitpid().
+    if (kill(-pid_, signal) == -1 && errno != ESRCH) {
         PLOG(ERROR) << "kill(" << pid_ << ", " << signal << ") failed";
     }
+
+    // If we've already seen a successful result from killProcessGroup*(), then we have removed
+    // the cgroup already and calling these functions a second time will simply result in an error.
+    // This is true regardless of which signal was sent.
+    // These functions handle their own logging, so no additional logging is needed.
+    if (!process_cgroup_empty_) {
+        LOG(INFO) << "Sending signal " << signal << " to service '" << name_ << "' (pid " << pid_
+                  << ") process group...";
+        int r;
+        if (signal == SIGTERM) {
+            r = killProcessGroupOnce(uid_, pid_, signal);
+        } else {
+            r = killProcessGroup(uid_, pid_, signal);
+        }
+
+        if (r == 0) process_cgroup_empty_ = true;
+    }
 }
 
 void Service::SetProcessAttributes() {
@@ -736,6 +748,7 @@
     time_started_ = boot_clock::now();
     pid_ = pid;
     flags_ |= SVC_RUNNING;
+    process_cgroup_empty_ = false;
 
     errno = -createProcessGroup(uid_, pid_);
     if (errno != 0) {