X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fjournald.c;h=47fe6edb0cad2ac85ca42f972837551937c41595;hb=e91af489a25e8bb65016a63f533ae28a505119ef;hp=78ccb4e05a958bfbe39631c872b58593d27ba963;hpb=dc1ecd78e9f046880d10ddb45cf9b06df1084b10;p=elogind.git diff --git a/src/journal/journald.c b/src/journal/journald.c index 78ccb4e05..47fe6edb0 100644 --- a/src/journal/journald.c +++ b/src/journal/journald.c @@ -41,6 +41,7 @@ #include "list.h" #include "journal-rate-limit.h" #include "sd-journal.h" +#include "sd-login.h" #include "journal-internal.h" #define USER_JOURNALS_MAX 1024 @@ -75,7 +76,9 @@ typedef struct Server { JournalRateLimit *rate_limit; - JournalMetrics metrics; + JournalMetrics runtime_metrics; + JournalMetrics system_metrics; + bool compress; uint64_t cached_available_space; @@ -117,15 +120,17 @@ struct StdoutStream { static int server_flush_to_var(Server *s); static uint64_t available_space(Server *s) { - char ids[33]; - sd_id128_t machine; - char *p; + char ids[33], *p; const char *f; + sd_id128_t machine; struct statvfs ss; uint64_t sum = 0, avail = 0, ss_avail = 0; int r; DIR *d; - usec_t ts = now(CLOCK_MONOTONIC); + usec_t ts; + JournalMetrics *m; + + ts = now(CLOCK_MONOTONIC); if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts) return s->cached_available_space; @@ -134,10 +139,15 @@ static uint64_t available_space(Server *s) { if (r < 0) return 0; - if (s->system_journal) + if (s->system_journal) { f = "/var/log/journal/"; - else + m = &s->system_metrics; + } else { f = "/run/log/journal/"; + m = &s->runtime_metrics; + } + + assert(m); p = strappend(f, sd_id128_to_string(machine, ids)); if (!p) @@ -175,11 +185,11 @@ static uint64_t available_space(Server *s) { sum += (uint64_t) st.st_blocks * (uint64_t) st.st_blksize; } - avail = sum >= s->metrics.max_use ? 0 : s->metrics.max_use - sum; + avail = sum >= m->max_use ? 0 : m->max_use - sum; ss_avail = ss.f_bsize * ss.f_bavail; - ss_avail = ss_avail < s->metrics.keep_free ? 0 : ss_avail - s->metrics.keep_free; + ss_avail = ss_avail < m->keep_free ? 0 : ss_avail - m->keep_free; if (ss_avail < avail) avail = ss_avail; @@ -284,7 +294,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) { return s->system_journal; fix_perms(f, uid); - f->metrics = s->metrics; + f->metrics = s->system_metrics; f->compress = s->compress; r = hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f); @@ -296,14 +306,11 @@ static JournalFile* find_journal(Server *s, uid_t uid) { return f; } -static void server_vacuum(Server *s) { - Iterator i; +static void server_rotate(Server *s) { + JournalFile *f; void *k; - char *p; - char ids[33]; - sd_id128_t machine; + Iterator i; int r; - JournalFile *f; log_info("Rotating..."); @@ -326,6 +333,13 @@ static void server_vacuum(Server *s) { else hashmap_replace(s->user_journals, k, f); } +} + +static void server_vacuum(Server *s) { + char *p; + char ids[33]; + sd_id128_t machine; + int r; log_info("Vacuuming..."); @@ -335,25 +349,32 @@ static void server_vacuum(Server *s) { return; } - if (asprintf(&p, "/var/log/journal/%s", sd_id128_to_string(machine, ids)) < 0) { - log_error("Out of memory."); - return; - } + sd_id128_to_string(machine, ids); - r = journal_directory_vacuum(p, s->metrics.max_use, s->metrics.keep_free); - if (r < 0 && r != -ENOENT) - log_error("Failed to vacuum %s: %s", p, strerror(-r)); - free(p); + if (s->system_journal) { + if (asprintf(&p, "/var/log/journal/%s", ids) < 0) { + log_error("Out of memory."); + return; + } - if (asprintf(&p, "/run/log/journal/%s", ids) < 0) { - log_error("Out of memory."); - return; + r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free); + if (r < 0 && r != -ENOENT) + log_error("Failed to vacuum %s: %s", p, strerror(-r)); + free(p); } - r = journal_directory_vacuum(p, s->metrics.max_use, s->metrics.keep_free); - if (r < 0 && r != -ENOENT) - log_error("Failed to vacuum %s: %s", p, strerror(-r)); - free(p); + + if (s->runtime_journal) { + if (asprintf(&p, "/run/log/journal/%s", ids) < 0) { + log_error("Out of memory."); + return; + } + + r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free); + if (r < 0 && r != -ENOENT) + log_error("Failed to vacuum %s: %s", p, strerror(-r)); + free(p); + } s->cached_available_space_timestamp = 0; } @@ -374,7 +395,9 @@ static char *shortened_cgroup_path(pid_t pid) { return NULL; } - if (streq(init_path, "/")) + if (endswith(init_path, "/system")) + init_path[strlen(init_path) - 7] = 0; + else if (streq(init_path, "/")) init_path[0] = 0; if (startswith(process_path, init_path)) { @@ -407,7 +430,8 @@ static void dispatch_message_real(Server *s, *source_time = NULL, *boot_id = NULL, *machine_id = NULL, *comm = NULL, *cmdline = NULL, *hostname = NULL, *audit_session = NULL, *audit_loginuid = NULL, - *exe = NULL, *cgroup = NULL; + *exe = NULL, *cgroup = NULL, *session = NULL, + *owner_uid = NULL, *service = NULL; char idbuf[33]; sd_id128_t id; @@ -420,11 +444,11 @@ static void dispatch_message_real(Server *s, assert(s); assert(iovec); assert(n > 0); - assert(n + 13 <= m); + assert(n + 16 <= m); if (ucred) { - uint32_t session; - char *path; + uint32_t audit; + uid_t owner; realuid = ucred->uid; @@ -440,30 +464,33 @@ static void dispatch_message_real(Server *s, r = get_process_comm(ucred->pid, &t); if (r >= 0) { comm = strappend("_COMM=", t); + free(t); + if (comm) IOVEC_SET_STRING(iovec[n++], comm); - free(t); } r = get_process_exe(ucred->pid, &t); if (r >= 0) { exe = strappend("_EXE=", t); + free(t); + if (comm) IOVEC_SET_STRING(iovec[n++], exe); - free(t); } r = get_process_cmdline(ucred->pid, LINE_MAX, false, &t); if (r >= 0) { cmdline = strappend("_CMDLINE=", t); + free(t); + if (cmdline) IOVEC_SET_STRING(iovec[n++], cmdline); - free(t); } - r = audit_session_from_pid(ucred->pid, &session); + r = audit_session_from_pid(ucred->pid, &audit); if (r >= 0) - if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) session) >= 0) + if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit) >= 0) IOVEC_SET_STRING(iovec[n++], audit_session); r = audit_loginuid_from_pid(ucred->pid, &loginuid); @@ -471,14 +498,34 @@ static void dispatch_message_real(Server *s, if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0) IOVEC_SET_STRING(iovec[n++], audit_loginuid); - path = shortened_cgroup_path(ucred->pid); - if (path) { - cgroup = strappend("_SYSTEMD_CGROUP=", path); + t = shortened_cgroup_path(ucred->pid); + if (t) { + cgroup = strappend("_SYSTEMD_CGROUP=", t); + free(t); + if (cgroup) IOVEC_SET_STRING(iovec[n++], cgroup); + } - free(path); + if (sd_pid_get_session(ucred->pid, &t) >= 0) { + session = strappend("_SYSTEMD_SESSION=", t); + free(t); + + if (session) + IOVEC_SET_STRING(iovec[n++], session); } + + if (sd_pid_get_service(ucred->pid, &t) >= 0) { + service = strappend("_SYSTEMD_SERVICE=", t); + free(t); + + if (service) + IOVEC_SET_STRING(iovec[n++], service); + } + + if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0) + if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0) + IOVEC_SET_STRING(iovec[n++], owner_uid); } if (tv) { @@ -503,9 +550,9 @@ static void dispatch_message_real(Server *s, t = gethostname_malloc(); if (t) { hostname = strappend("_HOSTNAME=", t); + free(t); if (hostname) IOVEC_SET_STRING(iovec[n++], hostname); - free(t); } assert(n <= m); @@ -522,6 +569,7 @@ retry: if (r == -E2BIG && !vacuumed) { log_info("Allocation limit reached."); + server_rotate(s); server_vacuum(s); vacuumed = true; @@ -546,6 +594,9 @@ retry: free(audit_session); free(audit_loginuid); free(cgroup); + free(session); + free(owner_uid); + free(service); } static void dispatch_message(Server *s, @@ -595,7 +646,7 @@ static void dispatch_message(Server *s, if (rl > 1) { int j = 0; char suppress_message[LINE_MAX]; - struct iovec suppress_iovec[15]; + struct iovec suppress_iovec[18]; /* Write a suppression message if we suppressed something */ @@ -616,7 +667,7 @@ finish: 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; - struct iovec iovec[16]; + struct iovec iovec[19]; unsigned n = 0; int priority = LOG_USER | LOG_INFO; @@ -723,11 +774,11 @@ static void process_native_message(Server *s, const void *buffer, size_t buffer_ /* A property follows */ - if (n+13 >= m) { + if (n+16 >= m) { struct iovec *c; unsigned u; - u = MAX((n+13U) * 2U, 4U); + u = MAX((n+16U) * 2U, 4U); c = realloc(iovec, u * sizeof(struct iovec)); if (!c) { log_error("Out of memory"); @@ -811,7 +862,7 @@ static void process_native_message(Server *s, const void *buffer, size_t buffer_ } static int stdout_stream_log(StdoutStream *s, const char *p, size_t l) { - struct iovec iovec[15]; + struct iovec iovec[18]; char *message = NULL, *syslog_priority = NULL; unsigned n = 0; size_t tag_len; @@ -1144,18 +1195,18 @@ static int system_journal_open(Server *s) { free(fn); if (r >= 0) { - s->system_journal->metrics = s->metrics; + journal_default_metrics(&s->system_metrics, s->system_journal->fd); + + s->system_journal->metrics = s->system_metrics; s->system_journal->compress = s->compress; fix_perms(s->system_journal, 0); } else if (r < 0) { - if (r == -ENOENT) - r = 0; - else { - log_error("Failed to open system journal: %s", strerror(-r)); - return r; - } + if (r != -ENOENT && r != -EROFS) + log_warning("Failed to open system journal: %s", strerror(-r)); + + r = 0; } } @@ -1175,13 +1226,10 @@ static int system_journal_open(Server *s) { free(fn); if (r < 0) { + if (r != -ENOENT) + log_warning("Failed to open runtime journal: %s", strerror(-r)); - if (r == -ENOENT) - r = 0; - else { - log_error("Failed to open runtime journal: %s", strerror(-r)); - return r; - } + r = 0; } } else { @@ -1200,7 +1248,9 @@ static int system_journal_open(Server *s) { } if (s->runtime_journal) { - s->runtime_journal->metrics = s->metrics; + journal_default_metrics(&s->runtime_metrics, s->runtime_journal->fd); + + s->runtime_journal->metrics = s->runtime_metrics; s->runtime_journal->compress = s->compress; fix_perms(s->runtime_journal, 0); @@ -1263,6 +1313,7 @@ static int server_flush_to_var(Server *s) { log_info("Allocation limit reached."); journal_file_post_change(s->system_journal); + server_rotate(s); server_vacuum(s); r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL); @@ -1717,12 +1768,11 @@ static int server_init(Server *s) { zero(*s); s->syslog_fd = s->native_fd = s->stdout_fd = s->signal_fd = s->epoll_fd = -1; - s->metrics.max_size = DEFAULT_MAX_SIZE; - s->metrics.min_size = DEFAULT_MIN_SIZE; - s->metrics.keep_free = DEFAULT_KEEP_FREE; - s->metrics.max_use = DEFAULT_MAX_USE; s->compress = true; + memset(&s->system_metrics, 0xFF, sizeof(s->system_metrics)); + memset(&s->runtime_metrics, 0xFF, sizeof(s->runtime_metrics)); + s->user_journals = hashmap_new(trivial_hash_func, trivial_compare_func); if (!s->user_journals) { log_error("Out of memory.");