Log pid for writes to sys.powerctl

Unless a process logs that it is requesting a device to reboot, there
are no logs to show which process triggered a reboot.  This change
introduces such a log in property service such that system initiated
reboots can be clearly blamed back to a calling process.

Bug: 64214361
Test: reboot and check kernel log for reboot string
Change-Id: I18de33d2a0933d20bdb581025b78020c88c5c6eb
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 8c592cb..5f5ed40 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -45,6 +45,7 @@
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/properties.h>
+#include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <bootimg.h>
 #include <fs_mgr.h>
@@ -56,6 +57,7 @@
 #include "persistent_properties.h"
 #include "util.h"
 
+using android::base::StringPrintf;
 using android::base::Timer;
 
 #define RECOVERY_MOUNT_POINT "/recovery"
@@ -418,6 +420,20 @@
     }
   } else {
     if (check_mac_perms(name, source_ctx, &cr)) {
+      // sys.powerctl is a special property that is used to make the device reboot.  We want to log
+      // any process that sets this property to be able to accurately blame the cause of a shutdown.
+      if (name == "sys.powerctl") {
+        std::string cmdline_path = StringPrintf("proc/%d/cmdline", cr.pid);
+        std::string process_cmdline;
+        std::string process_log_string;
+        if (android::base::ReadFileToString(cmdline_path, &process_cmdline)) {
+          // Since cmdline is null deliminated, .c_str() conveniently gives us just the process path.
+          process_log_string = StringPrintf(" (%s)", process_cmdline.c_str());
+        }
+        LOG(INFO) << "Received sys.powerctl='" << value << "' from pid: " << cr.pid
+                  << process_log_string;
+      }
+
       uint32_t result = property_set(name, value);
       if (!legacy_protocol) {
         socket.SendUint32(result);