diff options
Diffstat (limited to 'src/journal/journald-context.c')
-rw-r--r-- | src/journal/journald-context.c | 73 |
1 files changed, 58 insertions, 15 deletions
diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c index ce07de1bfb..8253a45128 100644 --- a/src/journal/journald-context.c +++ b/src/journal/journald-context.c @@ -13,6 +13,8 @@ #include "io-util.h" #include "journal-util.h" #include "journald-context.h" +#include "parse-util.h" +#include "path-util.h" #include "process-util.h" #include "string-util.h" #include "syslog-util.h" @@ -62,18 +64,13 @@ static int client_context_compare(const void *a, const void *b) { const ClientContext *x = a, *y = b; + int r; - if (x->timestamp < y->timestamp) - return -1; - if (x->timestamp > y->timestamp) - return 1; - - if (x->pid < y->pid) - return -1; - if (x->pid > y->pid) - return 1; + r = CMP(x->timestamp, y->timestamp); + if (r != 0) + return r; - return 0; + return CMP(x->pid, y->pid); } static int client_context_new(Server *s, pid_t pid, ClientContext **ret) { @@ -107,6 +104,8 @@ static int client_context_new(Server *s, pid_t pid, ClientContext **ret) { c->timestamp = USEC_INFINITY; c->extra_fields_mtime = NSEC_INFINITY; c->log_level_max = -1; + c->log_rate_limit_interval = s->rate_limit_interval; + c->log_rate_limit_burst = s->rate_limit_burst; r = hashmap_put(s->client_contexts, PID_TO_PTR(pid), c); if (r < 0) { @@ -118,7 +117,8 @@ static int client_context_new(Server *s, pid_t pid, ClientContext **ret) { return 0; } -static void client_context_reset(ClientContext *c) { +static void client_context_reset(Server *s, ClientContext *c) { + assert(s); assert(c); c->timestamp = USEC_INFINITY; @@ -153,6 +153,9 @@ static void client_context_reset(ClientContext *c) { c->extra_fields_mtime = NSEC_INFINITY; c->log_level_max = -1; + + c->log_rate_limit_interval = s->rate_limit_interval; + c->log_rate_limit_burst = s->rate_limit_burst; } static ClientContext* client_context_free(Server *s, ClientContext *c) { @@ -166,7 +169,7 @@ static ClientContext* client_context_free(Server *s, ClientContext *c) { if (c->in_lru) assert_se(prioq_remove(s->client_contexts_lru, c, &c->lru_index) >= 0); - client_context_reset(c); + client_context_reset(s, c); return mfree(c); } @@ -250,9 +253,11 @@ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *u /* Try to acquire the current cgroup path */ r = cg_pid_get_path_shifted(c->pid, s->cgroup_root, &t); - if (r < 0) { + if (r < 0 || empty_or_root(t)) { - /* If that didn't work, we use the unit ID passed in as fallback, if we have nothing cached yet */ + /* We use the unit ID passed in as fallback if we have nothing cached yet and cg_pid_get_path_shifted() + * failed or process is running in a root cgroup. Zombie processes are automatically migrated to root cgroup + * on cgroupsv1 and we want to be able to map log messages from them too. */ if (unit_id && !c->unit) { c->unit = strdup(unit_id); if (c->unit) @@ -429,6 +434,42 @@ static int client_context_read_extra_fields( return 0; } +static int client_context_read_log_rate_limit_interval(ClientContext *c) { + _cleanup_free_ char *value = NULL; + const char *p; + int r; + + assert(c); + + if (!c->unit) + return 0; + + p = strjoina("/run/systemd/units/log-rate-limit-interval:", c->unit); + r = readlink_malloc(p, &value); + if (r < 0) + return r; + + return safe_atou64(value, &c->log_rate_limit_interval); +} + +static int client_context_read_log_rate_limit_burst(ClientContext *c) { + _cleanup_free_ char *value = NULL; + const char *p; + int r; + + assert(c); + + if (!c->unit) + return 0; + + p = strjoina("/run/systemd/units/log-rate-limit-burst:", c->unit); + r = readlink_malloc(p, &value); + if (r < 0) + return r; + + return safe_atou(value, &c->log_rate_limit_burst); +} + static void client_context_really_refresh( Server *s, ClientContext *c, @@ -455,6 +496,8 @@ static void client_context_really_refresh( (void) client_context_read_invocation_id(s, c); (void) client_context_read_log_level_max(s, c); (void) client_context_read_extra_fields(s, c); + (void) client_context_read_log_rate_limit_interval(c); + (void) client_context_read_log_rate_limit_burst(c); c->timestamp = timestamp; @@ -485,7 +528,7 @@ void client_context_maybe_refresh( /* If the data isn't pinned and if the cashed data is older than the upper limit, we flush it out * entirely. This follows the logic that as long as an entry is pinned the PID reuse is unlikely. */ if (c->n_ref == 0 && c->timestamp + MAX_USEC < timestamp) { - client_context_reset(c); + client_context_reset(s, c); goto refresh; } |