|
|
a3e2b5 |
From 8da81d2aba2768ced497790cc05b9f73c6268833 Mon Sep 17 00:00:00 2001
|
|
|
a3e2b5 |
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
|
a3e2b5 |
Date: Tue, 22 Jan 2019 17:30:48 +0100
|
|
|
a3e2b5 |
Subject: [PATCH] journald: periodically drop cache for all dead PIDs
|
|
|
a3e2b5 |
|
|
|
a3e2b5 |
In normal use, this allow us to drop dead entries from the cache and reduces
|
|
|
a3e2b5 |
the cache size so that we don't evict entries unnecessarily. The time limit is
|
|
|
a3e2b5 |
there mostly to serve as a guard against malicious logging from many different
|
|
|
a3e2b5 |
PIDs.
|
|
|
a3e2b5 |
|
|
|
a3e2b5 |
(cherry-picked from commit 91714a7f427a6c9c5c3be8b3819fee45050028f3)
|
|
|
a3e2b5 |
|
|
|
a3e2b5 |
Related: #1664976
|
|
|
a3e2b5 |
---
|
|
|
a3e2b5 |
src/journal/journald-context.c | 28 ++++++++++++++++++++++++++--
|
|
|
a3e2b5 |
src/journal/journald-server.h | 2 ++
|
|
|
a3e2b5 |
2 files changed, 28 insertions(+), 2 deletions(-)
|
|
|
a3e2b5 |
|
|
|
a3e2b5 |
diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c
|
|
|
a3e2b5 |
index 0f0dc1de4d..51f79fd803 100644
|
|
|
a3e2b5 |
--- a/src/journal/journald-context.c
|
|
|
a3e2b5 |
+++ b/src/journal/journald-context.c
|
|
|
a3e2b5 |
@@ -541,15 +541,39 @@ refresh:
|
|
|
a3e2b5 |
}
|
|
|
a3e2b5 |
|
|
|
a3e2b5 |
static void client_context_try_shrink_to(Server *s, size_t limit) {
|
|
|
a3e2b5 |
+ ClientContext *c;
|
|
|
a3e2b5 |
+ usec_t t;
|
|
|
a3e2b5 |
+
|
|
|
a3e2b5 |
assert(s);
|
|
|
a3e2b5 |
|
|
|
a3e2b5 |
+ /* Flush any cache entries for PIDs that have already moved on. Don't do this
|
|
|
a3e2b5 |
+ * too often, since it's a slow process. */
|
|
|
a3e2b5 |
+ t = now(CLOCK_MONOTONIC);
|
|
|
a3e2b5 |
+ if (s->last_cache_pid_flush + MAX_USEC < t) {
|
|
|
a3e2b5 |
+ unsigned n = prioq_size(s->client_contexts_lru), idx = 0;
|
|
|
a3e2b5 |
+
|
|
|
a3e2b5 |
+ /* We do a number of iterations based on the initial size of the prioq. When we remove an
|
|
|
a3e2b5 |
+ * item, a new item is moved into its places, and items to the right might be reshuffled.
|
|
|
a3e2b5 |
+ */
|
|
|
a3e2b5 |
+ for (unsigned i = 0; i < n; i++) {
|
|
|
a3e2b5 |
+ c = prioq_peek_by_index(s->client_contexts_lru, idx);
|
|
|
a3e2b5 |
+
|
|
|
a3e2b5 |
+ assert(c->n_ref == 0);
|
|
|
a3e2b5 |
+
|
|
|
a3e2b5 |
+ if (!pid_is_unwaited(c->pid))
|
|
|
a3e2b5 |
+ client_context_free(s, c);
|
|
|
a3e2b5 |
+ else
|
|
|
a3e2b5 |
+ idx ++;
|
|
|
a3e2b5 |
+ }
|
|
|
a3e2b5 |
+
|
|
|
a3e2b5 |
+ s->last_cache_pid_flush = t;
|
|
|
a3e2b5 |
+ }
|
|
|
a3e2b5 |
+
|
|
|
a3e2b5 |
/* Bring the number of cache entries below the indicated limit, so that we can create a new entry without
|
|
|
a3e2b5 |
* breaching the limit. Note that we only flush out entries that aren't pinned here. This means the number of
|
|
|
a3e2b5 |
* cache entries may very well grow beyond the limit, if all entries stored remain pinned. */
|
|
|
a3e2b5 |
|
|
|
a3e2b5 |
while (hashmap_size(s->client_contexts) > limit) {
|
|
|
a3e2b5 |
- ClientContext *c;
|
|
|
a3e2b5 |
-
|
|
|
a3e2b5 |
c = prioq_pop(s->client_contexts_lru);
|
|
|
a3e2b5 |
if (!c)
|
|
|
a3e2b5 |
break; /* All remaining entries are pinned, give up */
|
|
|
a3e2b5 |
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
|
|
|
a3e2b5 |
index 983be8bb89..c6c9b1fb1d 100644
|
|
|
a3e2b5 |
--- a/src/journal/journald-server.h
|
|
|
a3e2b5 |
+++ b/src/journal/journald-server.h
|
|
|
a3e2b5 |
@@ -163,6 +163,8 @@ struct Server {
|
|
|
a3e2b5 |
Hashmap *client_contexts;
|
|
|
a3e2b5 |
Prioq *client_contexts_lru;
|
|
|
a3e2b5 |
|
|
|
a3e2b5 |
+ usec_t last_cache_pid_flush;
|
|
|
a3e2b5 |
+
|
|
|
a3e2b5 |
ClientContext *my_context; /* the context of journald itself */
|
|
|
a3e2b5 |
ClientContext *pid1_context; /* the context of PID 1 */
|
|
|
a3e2b5 |
};
|