Merge "base: kernel logging get pre-opened /dev/kmsg from environment" am: 7ff06150c1
am: 86c931c5f3

Change-Id: I67b4462a3c06b59060d2db6b8811158778ae5088
diff --git a/base/logging.cpp b/base/logging.cpp
index 30d7f8d..a33da22 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -54,6 +54,7 @@
 #endif
 
 #include <android-base/macros.h>
+#include <android-base/parseint.h>
 #include <android-base/strings.h>
 #include <android-base/threads.h>
 
@@ -82,6 +83,23 @@
   return progname;
 }
 #endif
+
+#if defined(__linux__)
+int OpenKmsg() {
+#if defined(__ANDROID__)
+  // pick up 'file w /dev/kmsg' environment from daemon's init rc file
+  const auto val = getenv("ANDROID_FILE__dev_kmsg");
+  if (val != nullptr) {
+    int fd;
+    if (android::base::ParseInt(val, &fd, 0)) {
+      auto flags = fcntl(fd, F_GETFL);
+      if ((flags != -1) && ((flags & O_ACCMODE) == O_WRONLY)) return fd;
+    }
+  }
+#endif
+  return TEMP_FAILURE_RETRY(open("/dev/kmsg", O_WRONLY | O_CLOEXEC));
+}
+#endif
 } // namespace
 
 namespace android {
@@ -150,7 +168,7 @@
   static_assert(arraysize(kLogSeverityToKernelLogLevel) == android::base::FATAL + 1,
                 "Mismatch in size of kLogSeverityToKernelLogLevel and values in LogSeverity");
 
-  static int klog_fd = TEMP_FAILURE_RETRY(open("/dev/kmsg", O_WRONLY | O_CLOEXEC));
+  static int klog_fd = OpenKmsg();
   if (klog_fd == -1) return;
 
   int level = kLogSeverityToKernelLogLevel[severity];