Optimize log daemon

This commit is contained in:
topjohnwu 2018-07-03 22:25:39 +08:00
parent 70243d7a47
commit 52a2c6958b

View File

@ -17,7 +17,6 @@
int loggable = 1; int loggable = 1;
static int sockfd; static int sockfd;
static pthread_t thread = -1;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
enum { enum {
@ -38,7 +37,7 @@ static int magisk_log_filter(const char *log) {
return !am_proc_start_filter(log); return !am_proc_start_filter(log);
} }
static struct log_listener log_events[] = { static struct log_listener events[] = {
{ /* HIDE_EVENT */ { /* HIDE_EVENT */
.fd = -1, .fd = -1,
.filter = am_proc_start_filter .filter = am_proc_start_filter
@ -48,7 +47,7 @@ static struct log_listener log_events[] = {
.filter = magisk_log_filter .filter = magisk_log_filter
} }
}; };
#define EVENT_NUM (sizeof(log_events) / sizeof(struct log_listener)) #define EVENT_NUM (sizeof(events) / sizeof(struct log_listener))
static void test_logcat() { static void test_logcat() {
int log_fd = -1, log_pid; int log_fd = -1, log_pid;
@ -56,28 +55,28 @@ static void test_logcat() {
log_pid = exec_command(0, &log_fd, NULL, "logcat", NULL); log_pid = exec_command(0, &log_fd, NULL, "logcat", NULL);
if (read(log_fd, buf, sizeof(buf)) != sizeof(buf)) { if (read(log_fd, buf, sizeof(buf)) != sizeof(buf)) {
loggable = 0; loggable = 0;
LOGD("log_monitor: cannot read from logcat, disable logging"); LOGD("magisklogd: cannot read from logcat, disable logging");
} }
kill(log_pid, SIGTERM); kill(log_pid, SIGTERM);
waitpid(log_pid, NULL, 0); waitpid(log_pid, NULL, 0);
} }
static void sigpipe_handler(int sig) { static void sigpipe_handler(int sig) {
close(log_events[HIDE_EVENT].fd); close(events[HIDE_EVENT].fd);
log_events[HIDE_EVENT].fd = -1; events[HIDE_EVENT].fd = -1;
} }
static void *socket_thread(void *args) { static void *socket_thread(void *args) {
/* This would block, so separate thread */ /* This would block, so separate thread */
while(1) { while(1) {
int fd = accept4(sockfd, NULL, NULL, SOCK_CLOEXEC); int fd = xaccept4(sockfd, NULL, NULL, SOCK_CLOEXEC);
switch(read_int(fd)) { switch(read_int(fd)) {
case HIDE_CONNECT: case HIDE_CONNECT:
pthread_mutex_lock(&lock); pthread_mutex_lock(&lock);
log_events[HIDE_EVENT].fd = fd; close(events[HIDE_EVENT].fd);
events[HIDE_EVENT].fd = fd;
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
thread = -1; break;
return NULL;
default: default:
close(fd); close(fd);
break; break;
@ -107,20 +106,20 @@ static void *monitor_thread(void *args) {
void log_daemon() { void log_daemon() {
setsid(); setsid();
strcpy(argv0, "magisklogd");
struct sockaddr_un sun; struct sockaddr_un sun;
sockfd = setup_socket(&sun, LOG_DAEMON); sockfd = setup_socket(&sun, LOG_DAEMON);
if (xbind(sockfd, (struct sockaddr*) &sun, sizeof(sun))) if (xbind(sockfd, (struct sockaddr*) &sun, sizeof(sun)))
exit(1); exit(1);
xlisten(sockfd, 1); xlisten(sockfd, 10);
LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") logger started\n"); LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") logger started\n");
strcpy(argv0, "magisklogd");
// Start invincible mode monitor // Start worker threads
// TODO: Remove this when all crashes are fixed
pthread_t t; pthread_t t;
pthread_create(&t, NULL, monitor_thread, NULL); pthread_create(&t, NULL, monitor_thread, NULL);
pthread_detach(t); pthread_detach(t);
xpthread_create(&t, NULL, socket_thread, NULL);
pthread_detach(t);
// Set SIGPIPE handler // Set SIGPIPE handler
struct sigaction act; struct sigaction act;
@ -130,21 +129,12 @@ void log_daemon() {
// Setup log dumps // Setup log dumps
rename(LOGFILE, LOGFILE ".bak"); rename(LOGFILE, LOGFILE ".bak");
log_events[LOG_EVENT].fd = xopen(LOGFILE, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0644); events[LOG_EVENT].fd = xopen(LOGFILE, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0644);
int log_fd = -1, log_pid; int log_fd = -1, log_pid;
char line[PIPE_BUF]; char line[PIPE_BUF];
while (1) { while (1) {
if (!loggable) {
// Disable all services
for (int i = 0; i < EVENT_NUM; ++i) {
close(log_events[i].fd);
log_events[i].fd = -1;
}
return;
}
// Start logcat // Start logcat
log_pid = exec_command(0, &log_fd, NULL, log_pid = exec_command(0, &log_fd, NULL,
"/system/bin/logcat", "/system/bin/logcat",
@ -159,25 +149,20 @@ void log_daemon() {
size_t len = strlen(line); size_t len = strlen(line);
pthread_mutex_lock(&lock); pthread_mutex_lock(&lock);
for (int i = 0; i < EVENT_NUM; ++i) { for (int i = 0; i < EVENT_NUM; ++i) {
if (log_events[i].fd > 0 && log_events[i].filter(line)) if (events[i].fd > 0 && events[i].filter(line))
write(log_events[i].fd, line, len); write(events[i].fd, line, len);
}
if (thread < 0 && log_events[HIDE_EVENT].fd < 0) {
// New thread to handle connection to main daemon
xpthread_create(&thread, NULL, socket_thread, NULL);
pthread_detach(thread);
} }
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
if (kill(log_pid, 0))
break;
} }
// Cleanup
fclose(logs); fclose(logs);
log_fd = -1; log_fd = -1;
kill(log_pid, SIGTERM); kill(log_pid, SIGTERM);
waitpid(log_pid, NULL, 0); waitpid(log_pid, NULL, 0);
test_logcat();
LOGI("magisklogd: logcat output EOF");
// Clear buffer
exec_command_sync("logcat", "-b", "events", "-b", "main", "-b", "crash", "-c", NULL);
} }
} }