X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fjournal%2Fjournald.c;h=1ec1542a14d7e92268503b721d2baa815e53a599;hp=22ac7d9a6ebe4ada8c036a9b21e8854b611548ae;hb=effb1102d3f1d6bc2d0bda5328d3ce2139af9850;hpb=33eb8abfa51d5bffbf8819215fafdd1123a4a8c0 diff --git a/src/journal/journald.c b/src/journal/journald.c index 22ac7d9a6..1ec1542a1 100644 --- a/src/journal/journald.c +++ b/src/journal/journald.c @@ -47,6 +47,7 @@ #include "journal-internal.h" #include "conf-parser.h" #include "journald.h" +#include "virt.h" #define USER_JOURNALS_MAX 1024 #define STDOUT_STREAMS_MAX 4096 @@ -58,14 +59,14 @@ #define RECHECK_VAR_AVAILABLE_USEC (30*USEC_PER_SEC) -#define SYSLOG_TIMEOUT_USEC (5*USEC_PER_SEC) +#define SYSLOG_TIMEOUT_USEC (250*USEC_PER_MSEC) #define N_IOVEC_META_FIELDS 16 typedef enum StdoutStreamState { - STDOUT_STREAM_TAG, + STDOUT_STREAM_IDENTIFIER, STDOUT_STREAM_PRIORITY, - STDOUT_STREAM_PRIORITY_PREFIX, + STDOUT_STREAM_LEVEL_PREFIX, STDOUT_STREAM_FORWARD_TO_SYSLOG, STDOUT_STREAM_FORWARD_TO_KMSG, STDOUT_STREAM_FORWARD_TO_CONSOLE, @@ -80,9 +81,9 @@ struct StdoutStream { struct ucred ucred; - char *tag; + char *identifier; int priority; - bool priority_prefix:1; + bool level_prefix:1; bool forward_to_syslog:1; bool forward_to_kmsg:1; bool forward_to_console:1; @@ -733,13 +734,13 @@ static void forward_syslog_raw(Server *s, const char *buffer, struct ucred *ucre forward_syslog_iovec(s, &iovec, 1, ucred, tv); } -static void forward_syslog(Server *s, int priority, const char *tag, const char *message, struct ucred *ucred, struct timeval *tv) { +static void forward_syslog(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred, struct timeval *tv) { struct iovec iovec[5]; char header_priority[6], header_time[64], header_pid[16]; int n = 0; time_t t; struct tm *tm; - char *tag_buf = NULL; + char *ident_buf = NULL; assert(s); assert(priority >= 0); @@ -760,22 +761,22 @@ static void forward_syslog(Server *s, int priority, const char *tag, const char return; IOVEC_SET_STRING(iovec[n++], header_time); - /* Third: tag and PID */ + /* Third: identifier and PID */ if (ucred) { - if (!tag) { - get_process_comm(ucred->pid, &tag_buf); - tag = tag_buf; + if (!identifier) { + get_process_comm(ucred->pid, &ident_buf); + identifier = ident_buf; } snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid); char_array_0(header_pid); - if (tag) - IOVEC_SET_STRING(iovec[n++], tag); + if (identifier) + IOVEC_SET_STRING(iovec[n++], identifier); IOVEC_SET_STRING(iovec[n++], header_pid); - } else if (tag) { - IOVEC_SET_STRING(iovec[n++], tag); + } else if (identifier) { + IOVEC_SET_STRING(iovec[n++], identifier); IOVEC_SET_STRING(iovec[n++], ": "); } @@ -784,7 +785,7 @@ static void forward_syslog(Server *s, int priority, const char *tag, const char forward_syslog_iovec(s, iovec, n, ucred, tv); - free(tag_buf); + free(ident_buf); } static int fixup_priority(int priority) { @@ -795,11 +796,11 @@ static int fixup_priority(int priority) { return priority; } -static void forward_kmsg(Server *s, int priority, const char *tag, const char *message, struct ucred *ucred) { +static void forward_kmsg(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred) { struct iovec iovec[5]; char header_priority[6], header_pid[16]; int n = 0; - char *tag_buf = NULL; + char *ident_buf = NULL; int fd; assert(s); @@ -816,22 +817,22 @@ static void forward_kmsg(Server *s, int priority, const char *tag, const char *m char_array_0(header_priority); IOVEC_SET_STRING(iovec[n++], header_priority); - /* Second: tag and PID */ + /* Second: identifier and PID */ if (ucred) { - if (!tag) { - get_process_comm(ucred->pid, &tag_buf); - tag = tag_buf; + if (!identifier) { + get_process_comm(ucred->pid, &ident_buf); + identifier = ident_buf; } snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid); char_array_0(header_pid); - if (tag) - IOVEC_SET_STRING(iovec[n++], tag); + if (identifier) + IOVEC_SET_STRING(iovec[n++], identifier); IOVEC_SET_STRING(iovec[n++], header_pid); - } else if (tag) { - IOVEC_SET_STRING(iovec[n++], tag); + } else if (identifier) { + IOVEC_SET_STRING(iovec[n++], identifier); IOVEC_SET_STRING(iovec[n++], ": "); } @@ -851,34 +852,34 @@ static void forward_kmsg(Server *s, int priority, const char *tag, const char *m close_nointr_nofail(fd); finish: - free(tag_buf); + free(ident_buf); } -static void forward_console(Server *s, const char *tag, const char *message, struct ucred *ucred) { +static void forward_console(Server *s, const char *identifier, const char *message, struct ucred *ucred) { struct iovec iovec[4]; char header_pid[16]; int n = 0, fd; - char *tag_buf = NULL; + char *ident_buf = NULL; assert(s); assert(message); - /* First: tag and PID */ + /* First: identifier and PID */ if (ucred) { - if (!tag) { - get_process_comm(ucred->pid, &tag_buf); - tag = tag_buf; + if (!identifier) { + get_process_comm(ucred->pid, &ident_buf); + identifier = ident_buf; } snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid); char_array_0(header_pid); - if (tag) - IOVEC_SET_STRING(iovec[n++], tag); + if (identifier) + IOVEC_SET_STRING(iovec[n++], identifier); IOVEC_SET_STRING(iovec[n++], header_pid); - } else if (tag) { - IOVEC_SET_STRING(iovec[n++], tag); + } else if (identifier) { + IOVEC_SET_STRING(iovec[n++], identifier); IOVEC_SET_STRING(iovec[n++], ": "); } @@ -898,16 +899,16 @@ static void forward_console(Server *s, const char *tag, const char *message, str close_nointr_nofail(fd); finish: - free(tag_buf); + free(ident_buf); } -static void read_tag(const char **buf, char **tag) { +static void read_identifier(const char **buf, char **identifier) { const char *p; char *t; size_t l, e; assert(buf); - assert(tag); + assert(identifier); p = *buf; @@ -940,18 +941,18 @@ static void read_tag(const char **buf, char **tag) { t = strndup(p, l); if (t) - *tag = t; + *identifier = t; *buf = p + e; *buf += strspn(*buf, WHITESPACE); } static void process_syslog_message(Server *s, const char *buf, struct ucred *ucred, struct timeval *tv) { - char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_tag = NULL; + char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL; struct iovec iovec[N_IOVEC_META_FIELDS + 5]; unsigned n = 0; int priority = LOG_USER | LOG_INFO; - char *tag = NULL; + char *identifier = NULL; assert(s); assert(buf); @@ -961,13 +962,13 @@ static void process_syslog_message(Server *s, const char *buf, struct ucred *ucr parse_syslog_priority((char**) &buf, &priority); skip_syslog_date((char**) &buf); - read_tag(&buf, &tag); + read_identifier(&buf, &identifier); if (s->forward_to_kmsg) - forward_kmsg(s, priority, tag, buf, ucred); + forward_kmsg(s, priority, identifier, buf, ucred); if (s->forward_to_console) - forward_console(s, tag, buf, ucred); + forward_console(s, identifier, buf, ucred); IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog"); @@ -978,10 +979,10 @@ static void process_syslog_message(Server *s, const char *buf, struct ucred *ucr if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0) IOVEC_SET_STRING(iovec[n++], syslog_facility); - if (tag) { - syslog_tag = strappend("SYSLOG_TAG=", tag); - if (syslog_tag) - IOVEC_SET_STRING(iovec[n++], syslog_tag); + if (identifier) { + syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier); + if (syslog_identifier) + IOVEC_SET_STRING(iovec[n++], syslog_identifier); } message = strappend("MESSAGE=", buf); @@ -991,10 +992,10 @@ static void process_syslog_message(Server *s, const char *buf, struct ucred *ucr dispatch_message(s, iovec, n, ELEMENTSOF(iovec), ucred, tv, priority); free(message); - free(tag); + free(identifier); free(syslog_priority); free(syslog_facility); - free(syslog_tag); + free(syslog_identifier); } static bool valid_user_field(const char *p, size_t l) { @@ -1038,7 +1039,7 @@ static void process_native_message(Server *s, const void *buffer, size_t buffer_ const char *p; size_t remaining; int priority = LOG_INFO; - char *tag = NULL, *message = NULL; + char *identifier = NULL, *message = NULL; assert(s); assert(buffer || n == 0); @@ -1128,13 +1129,13 @@ static void process_native_message(Server *s, const void *buffer, size_t buffer_ priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3); else if (l >= 12 && - memcmp(p, "SYSLOG_TAG=", 11) == 0) { + memcmp(p, "SYSLOG_IDENTIFIER=", 11) == 0) { char *t; t = strndup(p + 11, l - 11); if (t) { - free(tag); - tag = t; + free(identifier); + identifier = t; } } else if (l >= 8 && memcmp(p, "MESSAGE=", 8) == 0) { @@ -1199,13 +1200,13 @@ static void process_native_message(Server *s, const void *buffer, size_t buffer_ if (message) { if (s->forward_to_syslog) - forward_syslog(s, priority, tag, message, ucred, tv); + forward_syslog(s, priority, identifier, message, ucred, tv); if (s->forward_to_kmsg) - forward_kmsg(s, priority, tag, message, ucred); + forward_kmsg(s, priority, identifier, message, ucred); if (s->forward_to_console) - forward_console(s, tag, message, ucred); + forward_console(s, identifier, message, ucred); } dispatch_message(s, iovec, n, m, ucred, tv, priority); @@ -1220,13 +1221,13 @@ finish: free(iovec[j].iov_base); } - free(tag); + free(identifier); free(message); } static int stdout_stream_log(StdoutStream *s, const char *p) { struct iovec iovec[N_IOVEC_META_FIELDS + 5]; - char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_tag = NULL; + char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL; unsigned n = 0; int priority; @@ -1235,17 +1236,17 @@ static int stdout_stream_log(StdoutStream *s, const char *p) { priority = s->priority; - if (s->priority_prefix) + if (s->level_prefix) parse_syslog_priority((char**) &p, &priority); if (s->forward_to_syslog || s->server->forward_to_syslog) - forward_syslog(s->server, fixup_priority(priority), s->tag, p, &s->ucred, NULL); + forward_syslog(s->server, fixup_priority(priority), s->identifier, p, &s->ucred, NULL); if (s->forward_to_kmsg || s->server->forward_to_kmsg) - forward_kmsg(s->server, priority, s->tag, p, &s->ucred); + forward_kmsg(s->server, priority, s->identifier, p, &s->ucred); if (s->forward_to_console || s->server->forward_to_console) - forward_console(s->server, s->tag, p, &s->ucred); + forward_console(s->server, s->identifier, p, &s->ucred); IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout"); @@ -1256,10 +1257,10 @@ static int stdout_stream_log(StdoutStream *s, const char *p) { if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0) IOVEC_SET_STRING(iovec[n++], syslog_facility); - if (s->tag) { - syslog_tag = strappend("SYSLOG_TAG=", s->tag); - if (syslog_tag) - IOVEC_SET_STRING(iovec[n++], syslog_tag); + if (s->identifier) { + syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier); + if (syslog_identifier) + IOVEC_SET_STRING(iovec[n++], syslog_identifier); } message = strappend("MESSAGE=", p); @@ -1271,7 +1272,7 @@ static int stdout_stream_log(StdoutStream *s, const char *p) { free(message); free(syslog_priority); free(syslog_facility); - free(syslog_tag); + free(syslog_identifier); return 0; } @@ -1286,9 +1287,9 @@ static int stdout_stream_line(StdoutStream *s, char *p) { switch (s->state) { - case STDOUT_STREAM_TAG: - s->tag = strdup(p); - if (!s->tag) { + case STDOUT_STREAM_IDENTIFIER: + s->identifier = strdup(p); + if (!s->identifier) { log_error("Out of memory"); return -ENOMEM; } @@ -1303,17 +1304,17 @@ static int stdout_stream_line(StdoutStream *s, char *p) { return -EINVAL; } - s->state = STDOUT_STREAM_PRIORITY_PREFIX; + s->state = STDOUT_STREAM_LEVEL_PREFIX; return 0; - case STDOUT_STREAM_PRIORITY_PREFIX: + case STDOUT_STREAM_LEVEL_PREFIX: r = parse_boolean(p); if (r < 0) { - log_warning("Failed to parse priority prefix line."); + log_warning("Failed to parse level prefix line."); return -EINVAL; } - s->priority_prefix = !!r; + s->level_prefix = !!r; s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG; return 0; @@ -1456,7 +1457,7 @@ static void stdout_stream_free(StdoutStream *s) { close_nointr_nofail(s->fd); } - free(s->tag); + free(s->identifier); free(s); } @@ -2057,6 +2058,59 @@ static int open_signalfd(Server *s) { return 0; } +static int server_parse_proc_cmdline(Server *s) { + char *line, *w, *state; + int r; + size_t l; + + if (detect_container(NULL) > 0) + return 0; + + r = read_one_line_file("/proc/cmdline", &line); + if (r < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + FOREACH_WORD_QUOTED(w, l, line, state) { + char *word; + + word = strndup(w, l); + if (!word) { + r = -ENOMEM; + goto finish; + } + + if (startswith(word, "systemd_journald.forward_to_syslog=")) { + r = parse_boolean(word + 35); + if (r < 0) + log_warning("Failed to parse forward to syslog switch %s. Ignoring.", word + 35); + else + s->forward_to_syslog = r; + } else if (startswith(word, "systemd_journald.forward_to_kmsg=")) { + r = parse_boolean(word + 33); + if (r < 0) + log_warning("Failed to parse forward to kmsg switch %s. Ignoring.", word + 33); + else + s->forward_to_kmsg = r; + } else if (startswith(word, "systemd_journald.forward_to_console=")) { + r = parse_boolean(word + 36); + if (r < 0) + log_warning("Failed to parse forward to console switch %s. Ignoring.", word + 36); + else + s->forward_to_console = r; + } + + free(word); + } + + r = 0; + +finish: + free(line); + return r; +} + static int server_parse_config_file(Server *s) { FILE *f; const char *fn; @@ -2101,6 +2155,7 @@ static int server_init(Server *s) { memset(&s->runtime_metrics, 0xFF, sizeof(s->runtime_metrics)); server_parse_config_file(s); + server_parse_proc_cmdline(s); s->user_journals = hashmap_new(trivial_hash_func, trivial_compare_func); if (!s->user_journals) {