diff options
author | Mark Salyzyn <salyzyn@google.com> | 2015-03-10 16:45:17 -0700 |
---|---|---|
committer | Mark Salyzyn <salyzyn@google.com> | 2015-03-12 12:24:47 -0700 |
commit | 11e55cb9c1e5efe553e36f1b5c04ab21883f66e1 (patch) | |
tree | c1b58bc0ec2de3c0b2a84c26a7f796f56891785d | |
parent | 7e9fe7d86de665bcb2615d8c24de39416c48cdec (diff) | |
download | core-11e55cb9c1e5efe553e36f1b5c04ab21883f66e1.tar.gz core-11e55cb9c1e5efe553e36f1b5c04ab21883f66e1.tar.bz2 core-11e55cb9c1e5efe553e36f1b5c04ab21883f66e1.zip |
logd: add reinit command
- respond to SIGHUP
- respond to logd command "reinit"
- respond to logd --reinit
- reopens files on /data, eg: re-read of persistent properties
Bug: 19681572
Change-Id: Iadac58e6653f027cb7355497bd675eef376ce0a8
-rw-r--r-- | logd/CommandListener.cpp | 16 | ||||
-rw-r--r-- | logd/CommandListener.h | 11 | ||||
-rw-r--r-- | logd/LogBuffer.cpp | 12 | ||||
-rw-r--r-- | logd/LogBuffer.h | 1 | ||||
-rw-r--r-- | logd/main.cpp | 122 |
5 files changed, 143 insertions, 19 deletions
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp index d7088b4db..561ea3e50 100644 --- a/logd/CommandListener.cpp +++ b/logd/CommandListener.cpp @@ -44,6 +44,7 @@ CommandListener::CommandListener(LogBuffer *buf, LogReader * /*reader*/, registerCmd(new GetStatisticsCmd(buf)); registerCmd(new SetPruneListCmd(buf)); registerCmd(new GetPruneListCmd(buf)); + registerCmd(new ReinitCmd()); } CommandListener::ShutdownCmd::ShutdownCmd(LogBuffer *buf, LogReader *reader, @@ -296,6 +297,21 @@ int CommandListener::SetPruneListCmd::runCommand(SocketClient *cli, return 0; } +CommandListener::ReinitCmd::ReinitCmd() + : LogCommand("reinit") +{ } + +int CommandListener::ReinitCmd::runCommand(SocketClient *cli, + int /*argc*/, char ** /*argv*/) { + setname(); + + reinit_signal_handler(SIGHUP); + + cli->sendMsg("success"); + + return 0; +} + int CommandListener::getLogSocket() { static const char socketName[] = "logd"; int sock = android_get_control_socket(socketName); diff --git a/logd/CommandListener.h b/logd/CommandListener.h index cd1c306ba..83e06b4b0 100644 --- a/logd/CommandListener.h +++ b/logd/CommandListener.h @@ -23,6 +23,9 @@ #include "LogReader.h" #include "LogListener.h" +// See main.cpp for implementation +void reinit_signal_handler(int /*signal*/); + class CommandListener : public FrameworkListener { LogBuffer &mBuf; @@ -60,6 +63,14 @@ private: LogBufferCmd(GetStatistics) LogBufferCmd(GetPruneList) LogBufferCmd(SetPruneList) + + class ReinitCmd : public LogCommand { + public: + ReinitCmd(); + virtual ~ReinitCmd() {} + int runCommand(SocketClient *c, int argc, char ** argv); + }; + }; #endif diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index edda6c4e2..2b495abfd 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -92,10 +92,7 @@ static unsigned long property_get_size(const char *key) { return value; } -LogBuffer::LogBuffer(LastLogTimes *times) - : mTimes(*times) { - pthread_mutex_init(&mLogElementsLock, NULL); - +void LogBuffer::init() { static const char global_tuneable[] = "persist.logd.size"; // Settings App static const char global_default[] = "ro.logd.size"; // BoardConfig.mk @@ -131,6 +128,13 @@ LogBuffer::LogBuffer(LastLogTimes *times) } } +LogBuffer::LogBuffer(LastLogTimes *times) + : mTimes(*times) { + pthread_mutex_init(&mLogElementsLock, NULL); + + init(); +} + void LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char *msg, unsigned short len) { diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h index b0003ded2..86a2a2a68 100644 --- a/logd/LogBuffer.h +++ b/logd/LogBuffer.h @@ -46,6 +46,7 @@ public: LastLogTimes &mTimes; LogBuffer(LastLogTimes *times); + void init(); void log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, diff --git a/logd/main.cpp b/logd/main.cpp index 243bee4cd..2d799bf7a 100644 --- a/logd/main.cpp +++ b/logd/main.cpp @@ -17,7 +17,10 @@ #include <dirent.h> #include <errno.h> #include <fcntl.h> +#include <poll.h> #include <sched.h> +#include <semaphore.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -30,6 +33,7 @@ #include <cutils/properties.h> #include <cutils/sched_policy.h> +#include <cutils/sockets.h> #include "private/android_filesystem_config.h" #include "CommandListener.h" @@ -127,17 +131,100 @@ static bool property_get_bool(const char *key, bool def) { return def; } -// Foreground waits for exit of the three main persistent threads that -// are started here. The three threads are created to manage UNIX -// domain client sockets for writing, reading and controlling the user -// space logger. Additional transitory per-client threads are created -// for each reader once they register. -int main() { - bool auditd = property_get_bool("logd.auditd", true); +static sem_t reinit; +static bool reinit_running = false; +static LogBuffer *logBuf = NULL; + +static void *reinit_thread_start(void * /*obj*/) { + prctl(PR_SET_NAME, "logd.daemon"); + set_sched_policy(0, SP_BACKGROUND); - int fdDmesg = -1; - if (auditd && property_get_bool("logd.auditd.dmesg", true)) { - fdDmesg = open("/dev/kmsg", O_WRONLY); + setgid(AID_LOGD); + setuid(AID_LOGD); + + while (reinit_running && !sem_wait(&reinit) && reinit_running) { + // Anything that reads persist.<property> + if (logBuf) { + logBuf->init(); + } + } + + return NULL; +} + +// Serves as a global method to trigger reinitialization +// and as a function that can be provided to signal(). +void reinit_signal_handler(int /*signal*/) { + sem_post(&reinit); +} + +// Remove the static, and use this variable +// globally for debugging if necessary. eg: +// write(fdDmesg, "I am here\n", 10); +static int fdDmesg = -1; + +// Foreground waits for exit of the main persistent threads +// that are started here. The threads are created to manage +// UNIX domain client sockets for writing, reading and +// controlling the user space logger, and for any additional +// logging plugins like auditd and restart control. Additional +// transitory per-client threads are created for each reader. +int main(int argc, char *argv[]) { + fdDmesg = open("/dev/kmsg", O_WRONLY); + + // issue reinit command. KISS argument parsing. + if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) { + int sock = TEMP_FAILURE_RETRY( + socket_local_client("logd", + ANDROID_SOCKET_NAMESPACE_RESERVED, + SOCK_STREAM)); + if (sock < 0) { + return -errno; + } + static const char reinit[] = "reinit"; + ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinit, sizeof(reinit))); + if (ret < 0) { + return -errno; + } + struct pollfd p; + memset(&p, 0, sizeof(p)); + p.fd = sock; + p.events = POLLIN; + ret = TEMP_FAILURE_RETRY(poll(&p, 1, 100)); + if (ret < 0) { + return -errno; + } + if ((ret == 0) || !(p.revents & POLLIN)) { + return -ETIME; + } + static const char success[] = "success"; + char buffer[sizeof(success) - 1]; + memset(buffer, 0, sizeof(buffer)); + ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer))); + if (ret < 0) { + return -errno; + } + return strncmp(buffer, success, sizeof(success) - 1) != 0; + } + + // Reinit Thread + sem_init(&reinit, 0, 0); + pthread_attr_t attr; + if (!pthread_attr_init(&attr)) { + struct sched_param param; + + memset(¶m, 0, sizeof(param)); + pthread_attr_setschedparam(&attr, ¶m); + pthread_attr_setschedpolicy(&attr, SCHED_BATCH); + if (!pthread_attr_setdetachstate(&attr, + PTHREAD_CREATE_DETACHED)) { + pthread_t thread; + reinit_running = true; + if (pthread_create(&thread, &attr, reinit_thread_start, NULL)) { + reinit_running = false; + } + } + pthread_attr_destroy(&attr); } if (drop_privs() != 0) { @@ -153,7 +240,9 @@ int main() { // LogBuffer is the object which is responsible for holding all // log entries. - LogBuffer *logBuf = new LogBuffer(times); + logBuf = new LogBuffer(times); + + signal(SIGHUP, reinit_signal_handler); { char property[PROPERTY_VALUE_MAX]; @@ -195,9 +284,13 @@ int main() { // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. + bool auditd = property_get_bool("logd.auditd", true); + if (auditd) { + bool dmesg = property_get_bool("logd.auditd.dmesg", true); + // failure is an option ... messages are in dmesg (required by standard) - LogAudit *al = new LogAudit(logBuf, reader, fdDmesg); + LogAudit *al = new LogAudit(logBuf, reader, dmesg ? fdDmesg : -1); int len = klogctl(KLOG_SIZE_BUFFER, NULL, 0); if (len > 0) { @@ -217,11 +310,10 @@ int main() { if (al->startListener()) { delete al; - close(fdDmesg); } } - pause(); + TEMP_FAILURE_RETRY(pause()); + exit(0); } - |