base: kernel logging get pre-opened /dev/kmsg from environment

If the environment has an instance of /dev/kmsg pre-opened, pick up.
This happens when an init script has 'file w /dev/kmsg' in the
daemon's recipe.

libcutils android_get_control_file operations are open-coded to
prevent a dependency on libcutils itself.  Also check that /dev/kmsg
file descriptor is valid and open'd for write only.

Test: check to make sure init() kernel logging still works
Bug: 77541952
Bug: 77661605
Change-Id: I007553acd594ef0815d23f32f8aa2867518570ba
This commit is contained in:
Mark Salyzyn 2018-04-06 09:40:26 -07:00
parent 0289f35b83
commit 2507a048ab

View file

@ -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 @@ const char* getprogname() {
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 @@ void KernelLogger(android::base::LogId, android::base::LogSeverity severity,
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];