]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journald: move all config entries from Manager to JournalConfig
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 13 Jul 2025 06:29:22 +0000 (15:29 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 18 Jul 2025 06:27:35 +0000 (15:27 +0900)
Previously, only config entries controlled by multiple sources were located in
JournalConfig, and still other config entries were in Manager.
That's hard to maintain. Let's move all config entries to JournalConfig.

This also makes JournalConfig.forward_to_kmsg and friends tristate.
Otherwise, even if a higher precedence config source disables the
feature, it may be enabled by a lower precedence config.

12 files changed:
src/journal/journald-audit.c
src/journal/journald-config.c
src/journal/journald-config.h
src/journal/journald-console.c
src/journal/journald-context.c
src/journal/journald-gperf.gperf
src/journal/journald-kmsg.c
src/journal/journald-manager.c
src/journal/journald-manager.h
src/journal/journald-stream.c
src/journal/journald.c
src/journal/test-journald-config.c

index ebf401c4c2ca6b36e214ab134bc099149e39dcd5..479a4d27919940e15bdd9446a61679d4173a9146 100644 (file)
@@ -544,12 +544,12 @@ int manager_open_audit(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to add audit fd to event loop: %m");
 
-        if (m->set_audit >= 0) {
+        if (m->config.set_audit >= 0) {
                 /* We are listening now, try to enable audit if configured so */
-                r = enable_audit(m->audit_fd, m->set_audit);
+                r = enable_audit(m->audit_fd, m->config.set_audit);
                 if (r < 0)
                         log_warning_errno(r, "Failed to issue audit enable call: %m");
-                else if (m->set_audit > 0)
+                else if (m->config.set_audit > 0)
                         log_debug("Auditing in kernel turned on.");
                 else
                         log_debug("Auditing in kernel turned off.");
index 648ac55d7ec697176519032b8efb3c9dad68fe3f..cece07411f47771ac81854d7ebe57a6605fd5906 100644 (file)
  * for a bit of additional metadata. */
 #define DEFAULT_LINE_MAX            (48*1024)
 
-#define JOURNAL_CONFIG_INIT                                                                     \
-        (JournalConfig) {                                                                       \
-                .forward_to_socket = (SocketAddress) { .sockaddr.sa.sa_family = AF_UNSPEC },    \
-                .storage = _STORAGE_INVALID,                                                    \
-                .max_level_store = -1,                                                          \
-                .max_level_syslog = -1,                                                         \
-                .max_level_kmsg = -1,                                                           \
-                .max_level_console = -1,                                                        \
-                .max_level_wall = -1,                                                           \
-                .max_level_socket = -1,                                                         \
-        }
-
-static void manager_set_defaults(Manager *m) {
-        assert(m);
-
-        m->compress.enabled = true;
-        m->compress.threshold_bytes = UINT64_MAX;
-
-        m->seal = true;
-
-        /* By default, only read from /dev/kmsg if are the main namespace */
-        m->read_kmsg = !m->namespace;
-
-        /* By default, kernel auditing is enabled by the main namespace instance, and not controlled by
-         * non-default namespace instances. */
-        m->set_audit = m->namespace ? -1 : true;
-
-        m->sync_interval_usec = DEFAULT_SYNC_INTERVAL_USEC;
-
-        m->ratelimit_interval = DEFAULT_RATE_LIMIT_INTERVAL;
-        m->ratelimit_burst = DEFAULT_RATE_LIMIT_BURST;
-
-        m->system_storage.name = "System Journal";
-        journal_reset_metrics(&m->system_storage.metrics);
-
-        m->runtime_storage.name = "Runtime Journal";
-        journal_reset_metrics(&m->runtime_storage.metrics);
-
-        m->max_file_usec = DEFAULT_MAX_FILE_USEC;
+void journal_config_done(JournalConfig *c) {
+        assert(c);
 
-        m->config.forward_to_wall = true;
+        free(c->tty_path);
+}
 
-        m->config.max_level_store = LOG_DEBUG;
-        m->config.max_level_syslog = LOG_DEBUG;
-        m->config.max_level_kmsg = LOG_NOTICE;
-        m->config.max_level_console = LOG_INFO;
-        m->config.max_level_wall = LOG_EMERG;
-        m->config.max_level_socket = LOG_DEBUG;
+static void journal_config_set_defaults(JournalConfig *c) {
+        assert(c);
 
-        m->line_max = DEFAULT_LINE_MAX;
+        journal_config_done(c);
+
+        *c = (JournalConfig) {
+                .storage = _STORAGE_INVALID,
+                .compress.enabled = -1,
+                .compress.threshold_bytes = UINT64_MAX,
+                .seal = -1,
+                .read_kmsg = -1,
+                .set_audit = -1,
+                .ratelimit_interval = DEFAULT_RATE_LIMIT_INTERVAL,
+                .ratelimit_burst = DEFAULT_RATE_LIMIT_BURST,
+                .forward_to_syslog = -1,
+                .forward_to_kmsg = -1,
+                .forward_to_console = -1,
+                .forward_to_wall = -1,
+                .max_level_store = -1,
+                .max_level_syslog = -1,
+                .max_level_kmsg = -1,
+                .max_level_console = -1,
+                .max_level_wall = -1,
+                .max_level_socket = -1,
+        };
+
+        journal_reset_metrics(&c->system_storage_metrics);
+        journal_reset_metrics(&c->runtime_storage_metrics);
 }
 
-static void manager_reset_configs(Manager *m) {
+static void manager_merge_journal_compress_options(Manager *m) {
         assert(m);
 
-        m->config_by_cmdline = JOURNAL_CONFIG_INIT;
-        m->config_by_conf = JOURNAL_CONFIG_INIT;
-        m->config_by_cred = JOURNAL_CONFIG_INIT;
+        if (m->config_by_cmdline.compress.enabled >= 0)
+                m->config.compress = m->config_by_cmdline.compress;
+        else if (m->config_by_conf.compress.enabled >= 0)
+                m->config.compress = m->config_by_conf.compress;
+        else if (m->config_by_cred.compress.enabled >= 0)
+                m->config.compress = m->config_by_cred.compress;
+        else
+                m->config.compress = (JournalCompressOptions) {
+                        .enabled = true,
+                        .threshold_bytes = UINT64_MAX,
+                };
 }
 
 static void manager_merge_forward_to_socket(Manager *m) {
         assert(m);
 
-        /* Conf file takes precedence over credentials. */
-        if (m->config_by_conf.forward_to_socket.sockaddr.sa.sa_family != AF_UNSPEC)
+        if (m->config_by_cmdline.forward_to_socket.sockaddr.sa.sa_family != AF_UNSPEC)
+                m->config.forward_to_socket = m->config_by_cmdline.forward_to_socket;
+        else if (m->config_by_conf.forward_to_socket.sockaddr.sa.sa_family != AF_UNSPEC)
                 m->config.forward_to_socket = m->config_by_conf.forward_to_socket;
         else if (m->config_by_cred.forward_to_socket.sockaddr.sa.sa_family != AF_UNSPEC)
                 m->config.forward_to_socket = m->config_by_cred.forward_to_socket;
         else
-                m->config.forward_to_socket = (SocketAddress) { .sockaddr.sa.sa_family = AF_UNSPEC };
-}
-
-static void manager_merge_storage(Manager *m) {
-        assert(m);
-
-        /* Conf file takes precedence over credentials. */
-        if (m->config_by_conf.storage != _STORAGE_INVALID)
-                m->config.storage = m->config_by_conf.storage;
-        else if (m->config_by_cred.storage != _STORAGE_INVALID)
-                m->config.storage = m->config_by_cred.storage;
-        else
-                m->config.storage = m->namespace ? STORAGE_PERSISTENT : STORAGE_AUTO;
+                m->config.forward_to_socket = (SocketAddress) {};
 }
 
-#define MERGE_BOOL(name, default_value)                                                 \
-    (m->config.name = (m->config_by_cmdline.name  ? m->config_by_cmdline.name :         \
-                       m->config_by_conf.name     ? m->config_by_conf.name     :        \
-                       m->config_by_cred.name     ? m->config_by_cred.name     :        \
-                       default_value))
+#define MERGE_NON_NEGATIVE(name, default_value)                         \
+        m->config.name =                                                \
+                m->config_by_cmdline.name >= 0 ? m->config_by_cmdline.name : \
+                m->config_by_conf.name >= 0 ? m->config_by_conf.name :  \
+                m->config_by_cred.name >= 0 ? m->config_by_cred.name :  \
+                default_value
 
-#define MERGE_NON_NEGATIVE(name, default_value)                                         \
-        (m->config.name = (m->config_by_cmdline.name >= 0 ? m->config_by_cmdline.name : \
-                           m->config_by_conf.name >= 0    ? m->config_by_conf.name :    \
-                           m->config_by_cred.name >= 0    ? m->config_by_cred.name :    \
-                           default_value))
+#define MERGE_NON_ZERO(name, default_value)                             \
+        m->config.name =                                                \
+                m->config_by_cmdline.name ?:                            \
+                m->config_by_conf.name ?:                               \
+                m->config_by_cred.name ?:                               \
+                default_value
 
 static void manager_merge_configs(Manager *m) {
         assert(m);
 
-        /*
-         * From highest to lowest priority: cmdline, conf, cred
-         */
-        manager_merge_storage(m);
+        /* From highest to lowest priority: cmdline, conf, cred */
+
+        journal_config_done(&m->config);
+
+        MERGE_NON_NEGATIVE(storage, STORAGE_AUTO);
+        manager_merge_journal_compress_options(m);
+        MERGE_NON_NEGATIVE(seal, true);
+        /* By default, /dev/kmsg is read only by the main namespace instance. */
+        MERGE_NON_NEGATIVE(read_kmsg, !m->namespace);
+        /* By default, kernel auditing is enabled by the main namespace instance, and not controlled by
+         * non-default namespace instances. */
+        MERGE_NON_NEGATIVE(set_audit, m->namespace ? -1 : true);
+        MERGE_NON_ZERO(sync_interval_usec, DEFAULT_SYNC_INTERVAL_USEC);
+
+        /* TODO: also merge them when comdline or credentials support to configure them. */
+        m->config.ratelimit_interval = m->config_by_conf.ratelimit_interval;
+        m->config.ratelimit_burst = m->config_by_conf.ratelimit_burst;
+        m->config.system_storage_metrics = m->config_by_conf.system_storage_metrics;
+        m->config.runtime_storage_metrics = m->config_by_conf.runtime_storage_metrics;
+
+        MERGE_NON_ZERO(max_retention_usec, 0);
+        MERGE_NON_ZERO(max_file_usec, DEFAULT_MAX_FILE_USEC);
+        MERGE_NON_NEGATIVE(forward_to_syslog, false);
+        MERGE_NON_NEGATIVE(forward_to_kmsg, false);
+        MERGE_NON_NEGATIVE(forward_to_console, false);
+        MERGE_NON_NEGATIVE(forward_to_wall, true);
         manager_merge_forward_to_socket(m);
 
-        MERGE_BOOL(forward_to_syslog, false);
-        MERGE_BOOL(forward_to_kmsg, false);
-        MERGE_BOOL(forward_to_console, false);
-        MERGE_BOOL(forward_to_wall, true);
+        if (strdup_to(&m->config.tty_path,
+                      m->config_by_cmdline.tty_path ?:
+                      m->config_by_conf.tty_path ?:
+                      m->config_by_cred.tty_path) < 0)
+                log_oom_debug();
 
         MERGE_NON_NEGATIVE(max_level_store, LOG_DEBUG);
         MERGE_NON_NEGATIVE(max_level_syslog, LOG_DEBUG);
@@ -142,17 +148,24 @@ static void manager_merge_configs(Manager *m) {
         MERGE_NON_NEGATIVE(max_level_console, LOG_INFO);
         MERGE_NON_NEGATIVE(max_level_wall, LOG_EMERG);
         MERGE_NON_NEGATIVE(max_level_socket, LOG_DEBUG);
+        MERGE_NON_NEGATIVE(split_mode, SPLIT_UID);
+        MERGE_NON_ZERO(line_max, DEFAULT_LINE_MAX);
 }
 
 static void manager_adjust_configs(Manager *m) {
         assert(m);
 
-        if (!!m->ratelimit_interval != !!m->ratelimit_burst) { /* One set to 0 and the other not? */
+        if ((m->config.ratelimit_interval == 0) != (m->config.ratelimit_burst == 0)) { /* One set to 0 and the other not? */
                 log_debug("Setting both rate limit interval and burst from %s/%u to 0/0",
-                          FORMAT_TIMESPAN(m->ratelimit_interval, USEC_PER_SEC),
-                          m->ratelimit_burst);
-                m->ratelimit_interval = m->ratelimit_burst = 0;
+                          FORMAT_TIMESPAN(m->config.ratelimit_interval, USEC_PER_SEC),
+                          m->config.ratelimit_burst);
+                m->config.ratelimit_interval = 0;
+                m->config.ratelimit_burst = 0;
         }
+
+        /* copy metrics to manager */
+        m->system_storage.metrics = m->config.system_storage_metrics;
+        m->runtime_storage.metrics = m->config.runtime_storage_metrics;
 }
 
 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
@@ -280,7 +293,7 @@ static void manager_parse_config_file(Manager *m) {
                         config_item_perf_lookup,
                         journald_gperf_lookup,
                         CONFIG_PARSE_WARN,
-                        m);
+                        &m->config_by_conf);
 }
 
 static void manager_load_credentials(JournalConfig *c) {
@@ -317,8 +330,9 @@ void manager_load_config(Manager *m) {
 
         assert(m);
 
-        manager_set_defaults(m);
-        manager_reset_configs(m);
+        journal_config_set_defaults(&m->config_by_conf);
+        journal_config_set_defaults(&m->config_by_cred);
+        journal_config_set_defaults(&m->config_by_cmdline);
 
         manager_load_credentials(&m->config_by_cred);
         manager_parse_config_file(m);
@@ -331,18 +345,14 @@ void manager_load_config(Manager *m) {
         }
 
         manager_merge_configs(m);
-
         manager_adjust_configs(m);
 }
 
 static void manager_reload_config(Manager *m) {
         assert(m);
 
-        manager_set_defaults(m);
-
-        m->config_by_conf = JOURNAL_CONFIG_INIT;
+        journal_config_set_defaults(&m->config_by_conf);
         manager_parse_config_file(m);
-
         manager_merge_configs(m);
         manager_adjust_configs(m);
 }
@@ -449,7 +459,7 @@ int config_parse_compress(
         int r;
 
         if (isempty(rvalue)) {
-                compress->enabled = true;
+                compress->enabled = -1;
                 compress->threshold_bytes = UINT64_MAX;
                 return 0;
         }
index ffa6c5f2b87433e714d53d7b0669190cd964d64a..31077acba2dc452a86481b2567df036cf737410c 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
+#include "journal-file.h"
 #include "journald-forward.h"
 #include "socket-util.h"
 
@@ -22,28 +23,66 @@ typedef enum SplitMode {
 } SplitMode;
 
 typedef struct JournalCompressOptions {
-        bool enabled;
+        int enabled;
         uint64_t threshold_bytes;
 } JournalCompressOptions;
 
 typedef struct JournalConfig {
+        /* Storage=, cred: journal.storage */
         Storage storage;
-
-        bool forward_to_kmsg;
-        bool forward_to_syslog;
-        bool forward_to_console;
-        bool forward_to_wall;
-
+        /* Compress= */
+        JournalCompressOptions compress;
+        /* Seal= */
+        int seal;
+        /* ReadKMsg= */
+        int read_kmsg;
+        /* Audit= */
+        int set_audit;
+        /* SyncIntervalSec= */
+        usec_t sync_interval_usec;
+        /* RateLimitIntervalSec= */
+        usec_t ratelimit_interval;
+        /* RateLimitBurst= */
+        unsigned ratelimit_burst;
+        /* SystemMaxUse=, SystemMaxFileSize=, SystemKeepFree=, SystemMaxFiles= */
+        JournalMetrics system_storage_metrics;
+        /* RuntimeMaxUse=, RuntimeMaxFileSize=, RuntimeKeepFree=, RuntimeMaxFiles= */
+        JournalMetrics runtime_storage_metrics;
+        /* MaxRetentionSec= */
+        usec_t max_retention_usec;
+        /* MaxFileSec= */
+        usec_t max_file_usec;
+        /* ForwardToSyslog=, proc: systemd.journald.forward_to_syslog */
+        int forward_to_syslog;
+        /* ForwardToKMsg=, proc: systemd.journald.forward_to_kmsg */
+        int forward_to_kmsg;
+        /* ForwardToConsole=, proc: systemd.journald.forward_to_console */
+        int forward_to_console;
+        /* ForwardToWall=, proc: systemd.journald.forward_to_wall */
+        int forward_to_wall;
+        /* ForwardToSocket=, cred: journal.forward_to_socket */
         SocketAddress forward_to_socket;
-
+        /* TTYPath= */
+        char *tty_path;
+        /* MaxLevelStore=, proc: systemd.journald.max_level_store */
         int max_level_store;
+        /* MaxLevelSyslog=, proc: systemd.journald.max_level_syslog */
         int max_level_syslog;
+        /* MaxLevelKMsg=, proc: systemd.journald.max_level_kmsg */
         int max_level_kmsg;
+        /* MaxLevelConsole=, proc: systemd.journald.max_level_console */
         int max_level_console;
+        /* MaxLevelWall=, systemd.journald.max_level_wall */
         int max_level_wall;
+        /* MaxLevelSocket=, systemd.journald.max_level_socket */
         int max_level_socket;
+        /* SplitMode= */
+        SplitMode split_mode;
+        /* LineMax= */
+        size_t line_max;
 } JournalConfig;
 
+void journal_config_done(JournalConfig *c);
 void manager_load_config(Manager *m);
 int manager_dispatch_reload_signal(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata);
 
index 73cccb4da980980a389afd6fa3b2b72818ce462a..0f376f9e5a45cd43a1dca6ec19578a4cf9155163 100644 (file)
@@ -91,7 +91,7 @@ void manager_forward_console(
         iovec[n++] = IOVEC_MAKE_STRING(color_off);
         iovec[n++] = IOVEC_MAKE_STRING("\n");
 
-        tty = m->tty_path ?: "/dev/console";
+        tty = m->config.tty_path ?: "/dev/console";
 
         /* Before you ask: yes, on purpose we open/close the console for each log line we write individually. This is a
          * good strategy to avoid journald getting killed by the kernel's SAK concept (it doesn't fix this entirely,
index a6b34f14e410e1a5becdab813b8e6a76dde01e79..e6d0c70e020bd17de636ca4d2d72d4c96d99b92a 100644 (file)
@@ -139,8 +139,8 @@ static int client_context_new(Manager *m, pid_t pid, ClientContext **ret) {
                 .timestamp = USEC_INFINITY,
                 .extra_fields_mtime = NSEC_INFINITY,
                 .log_level_max = -1,
-                .log_ratelimit_interval = m->ratelimit_interval,
-                .log_ratelimit_burst = m->ratelimit_burst,
+                .log_ratelimit_interval = m->config.ratelimit_interval,
+                .log_ratelimit_burst = m->config.ratelimit_burst,
                 .capability_quintet = CAPABILITY_QUINTET_NULL,
         };
 
@@ -188,8 +188,8 @@ static void client_context_reset(Manager *m, ClientContext *c) {
 
         c->log_level_max = -1;
 
-        c->log_ratelimit_interval = m->ratelimit_interval;
-        c->log_ratelimit_burst = m->ratelimit_burst;
+        c->log_ratelimit_interval = m->config.ratelimit_interval;
+        c->log_ratelimit_burst = m->config.ratelimit_burst;
 
         c->log_filter_allowed_patterns = set_free(c->log_filter_allowed_patterns);
         c->log_filter_denied_patterns = set_free(c->log_filter_denied_patterns);
index 26cd08b384508e57e9c8fd597112fffe8dc309cb..23caa287ffd6460938092cbb9435fcc1b8bcbe04 100644 (file)
@@ -6,7 +6,7 @@ _Pragma("GCC diagnostic ignored \"-Wzero-as-null-pointer-constant\"")
 #endif
 #include <stddef.h>
 #include "conf-parser.h"
-#include "journald-manager.h"
+#include "journald-config.h"
 %}
 struct ConfigPerfItem;
 %null_strings
@@ -19,37 +19,37 @@ struct ConfigPerfItem;
 %struct-type
 %includes
 %%
-Journal.Storage,            config_parse_storage,           0, offsetof(Manager, config_by_conf.storage)
-Journal.Compress,           config_parse_compress,          0, offsetof(Manager, compress)
-Journal.Seal,               config_parse_bool,              0, offsetof(Manager, seal)
-Journal.ReadKMsg,           config_parse_bool,              0, offsetof(Manager, read_kmsg)
-Journal.Audit,              config_parse_tristate,          0, offsetof(Manager, set_audit)
-Journal.SyncIntervalSec,    config_parse_sec,               0, offsetof(Manager, sync_interval_usec)
+Journal.Storage,              config_parse_storage,           0, offsetof(JournalConfig, storage)
+Journal.Compress,             config_parse_compress,          0, offsetof(JournalConfig, compress)
+Journal.Seal,                 config_parse_tristate,          0, offsetof(JournalConfig, seal)
+Journal.ReadKMsg,             config_parse_tristate,          0, offsetof(JournalConfig, read_kmsg)
+Journal.Audit,                config_parse_tristate,          0, offsetof(JournalConfig, set_audit)
+Journal.SyncIntervalSec,      config_parse_sec,               0, offsetof(JournalConfig, sync_interval_usec)
 # The following is a legacy name for compatibility
-Journal.RateLimitInterval,  config_parse_sec,               0, offsetof(Manager, ratelimit_interval)
-Journal.RateLimitIntervalSec,config_parse_sec,              0, offsetof(Manager, ratelimit_interval)
-Journal.RateLimitBurst,     config_parse_unsigned,          0, offsetof(Manager, ratelimit_burst)
-Journal.SystemMaxUse,       config_parse_iec_uint64,        0, offsetof(Manager, system_storage.metrics.max_use)
-Journal.SystemMaxFileSize,  config_parse_iec_uint64,        0, offsetof(Manager, system_storage.metrics.max_size)
-Journal.SystemKeepFree,     config_parse_iec_uint64,        0, offsetof(Manager, system_storage.metrics.keep_free)
-Journal.SystemMaxFiles,     config_parse_uint64,            0, offsetof(Manager, system_storage.metrics.n_max_files)
-Journal.RuntimeMaxUse,      config_parse_iec_uint64,        0, offsetof(Manager, runtime_storage.metrics.max_use)
-Journal.RuntimeMaxFileSize, config_parse_iec_uint64,        0, offsetof(Manager, runtime_storage.metrics.max_size)
-Journal.RuntimeKeepFree,    config_parse_iec_uint64,        0, offsetof(Manager, runtime_storage.metrics.keep_free)
-Journal.RuntimeMaxFiles,    config_parse_uint64,            0, offsetof(Manager, runtime_storage.metrics.n_max_files)
-Journal.MaxRetentionSec,    config_parse_sec,               0, offsetof(Manager, max_retention_usec)
-Journal.MaxFileSec,         config_parse_sec,               0, offsetof(Manager, max_file_usec)
-Journal.ForwardToSyslog,    config_parse_bool,              0, offsetof(Manager, config_by_conf.forward_to_syslog)
-Journal.ForwardToKMsg,      config_parse_bool,              0, offsetof(Manager, config_by_conf.forward_to_kmsg)
-Journal.ForwardToConsole,   config_parse_bool,              0, offsetof(Manager, config_by_conf.forward_to_console)
-Journal.ForwardToWall,      config_parse_bool,              0, offsetof(Manager, config_by_conf.forward_to_wall)
-Journal.ForwardToSocket,    config_parse_forward_to_socket, 0, offsetof(Manager, config_by_conf.forward_to_socket)
-Journal.TTYPath,            config_parse_path,              0, offsetof(Manager, tty_path)
-Journal.MaxLevelStore,      config_parse_log_level,         0, offsetof(Manager, config_by_conf.max_level_store)
-Journal.MaxLevelSyslog,     config_parse_log_level,         0, offsetof(Manager, config_by_conf.max_level_syslog)
-Journal.MaxLevelKMsg,       config_parse_log_level,         0, offsetof(Manager, config_by_conf.max_level_kmsg)
-Journal.MaxLevelConsole,    config_parse_log_level,         0, offsetof(Manager, config_by_conf.max_level_console)
-Journal.MaxLevelWall,       config_parse_log_level,         0, offsetof(Manager, config_by_conf.max_level_wall)
-Journal.MaxLevelSocket,     config_parse_log_level,         0, offsetof(Manager, config_by_conf.max_level_socket)
-Journal.SplitMode,          config_parse_split_mode,        0, offsetof(Manager, split_mode)
-Journal.LineMax,            config_parse_line_max,          0, offsetof(Manager, line_max)
+Journal.RateLimitInterval,    config_parse_sec,               0, offsetof(JournalConfig, ratelimit_interval)
+Journal.RateLimitIntervalSec, config_parse_sec,               0, offsetof(JournalConfig, ratelimit_interval)
+Journal.RateLimitBurst,       config_parse_unsigned,          0, offsetof(JournalConfig, ratelimit_burst)
+Journal.SystemMaxUse,         config_parse_iec_uint64,        0, offsetof(JournalConfig, system_storage_metrics.max_use)
+Journal.SystemMaxFileSize,    config_parse_iec_uint64,        0, offsetof(JournalConfig, system_storage_metrics.max_size)
+Journal.SystemKeepFree,       config_parse_iec_uint64,        0, offsetof(JournalConfig, system_storage_metrics.keep_free)
+Journal.SystemMaxFiles,       config_parse_uint64,            0, offsetof(JournalConfig, system_storage_metrics.n_max_files)
+Journal.RuntimeMaxUse,        config_parse_iec_uint64,        0, offsetof(JournalConfig, runtime_storage_metrics.max_use)
+Journal.RuntimeMaxFileSize,   config_parse_iec_uint64,        0, offsetof(JournalConfig, runtime_storage_metrics.max_size)
+Journal.RuntimeKeepFree,      config_parse_iec_uint64,        0, offsetof(JournalConfig, runtime_storage_metrics.keep_free)
+Journal.RuntimeMaxFiles,      config_parse_uint64,            0, offsetof(JournalConfig, runtime_storage_metrics.n_max_files)
+Journal.MaxRetentionSec,      config_parse_sec,               0, offsetof(JournalConfig, max_retention_usec)
+Journal.MaxFileSec,           config_parse_sec,               0, offsetof(JournalConfig, max_file_usec)
+Journal.ForwardToSyslog,      config_parse_tristate,          0, offsetof(JournalConfig, forward_to_syslog)
+Journal.ForwardToKMsg,        config_parse_tristate,          0, offsetof(JournalConfig, forward_to_kmsg)
+Journal.ForwardToConsole,     config_parse_tristate,          0, offsetof(JournalConfig, forward_to_console)
+Journal.ForwardToWall,        config_parse_tristate,          0, offsetof(JournalConfig, forward_to_wall)
+Journal.ForwardToSocket,      config_parse_forward_to_socket, 0, offsetof(JournalConfig, forward_to_socket)
+Journal.TTYPath,              config_parse_path,              0, offsetof(JournalConfig, tty_path)
+Journal.MaxLevelStore,        config_parse_log_level,         0, offsetof(JournalConfig, max_level_store)
+Journal.MaxLevelSyslog,       config_parse_log_level,         0, offsetof(JournalConfig, max_level_syslog)
+Journal.MaxLevelKMsg,         config_parse_log_level,         0, offsetof(JournalConfig, max_level_kmsg)
+Journal.MaxLevelConsole,      config_parse_log_level,         0, offsetof(JournalConfig, max_level_console)
+Journal.MaxLevelWall,         config_parse_log_level,         0, offsetof(JournalConfig, max_level_wall)
+Journal.MaxLevelSocket,       config_parse_log_level,         0, offsetof(JournalConfig, max_level_socket)
+Journal.SplitMode,            config_parse_split_mode,        0, offsetof(JournalConfig, split_mode)
+Journal.LineMax,              config_parse_line_max,          0, offsetof(JournalConfig, line_max)
index 926cc823db5d4956b32bd9ce64980b69269d4d38..ec05e1f1b486eb4273a24099f70cf05b3378b0f1 100644 (file)
@@ -332,7 +332,7 @@ static int manager_read_dev_kmsg(Manager *m) {
 
         assert(m);
         assert(m->dev_kmsg_fd >= 0);
-        assert(m->read_kmsg);
+        assert(m->config.read_kmsg);
 
         l = read(m->dev_kmsg_fd, buffer, sizeof(buffer) - 1);
         if (l == 0)
@@ -356,7 +356,7 @@ int manager_flush_dev_kmsg(Manager *m) {
         if (m->dev_kmsg_fd < 0)
                 return 0;
 
-        if (!m->read_kmsg)
+        if (!m->config.read_kmsg)
                 return 0;
 
         log_debug("Flushing /dev/kmsg...");
@@ -400,7 +400,7 @@ int manager_open_dev_kmsg(Manager *m) {
         assert(m->dev_kmsg_fd < 0);
         assert(!m->dev_kmsg_event_source);
 
-        mode_t mode = manager_kmsg_mode(m->read_kmsg);
+        mode_t mode = manager_kmsg_mode(m->config.read_kmsg);
 
         _cleanup_close_ int fd = open("/dev/kmsg", mode);
         if (fd < 0) {
@@ -409,7 +409,7 @@ int manager_open_dev_kmsg(Manager *m) {
                 return 0;
         }
 
-        if (!m->read_kmsg) {
+        if (!m->config.read_kmsg) {
                 m->dev_kmsg_fd = TAKE_FD(fd);
                 return 0;
         }
@@ -436,7 +436,7 @@ int manager_open_kernel_seqnum(Manager *m) {
         /* We store the seqnum we last read in an mmapped file. That way we can just use it like a variable,
          * but it is persistent and automatically flushed at reboot. */
 
-        if (!m->read_kmsg)
+        if (!m->config.read_kmsg)
                 return 0;
 
         r = manager_map_seqnum_file(m, "kernel-seqnum", sizeof(uint64_t), (void**) &m->kernel_seqnum);
@@ -455,7 +455,7 @@ int manager_reload_dev_kmsg(Manager *m) {
         if (m->dev_kmsg_fd < 0)
                 return manager_open_dev_kmsg(m);
 
-        mode_t mode = manager_kmsg_mode(m->read_kmsg);
+        mode_t mode = manager_kmsg_mode(m->config.read_kmsg);
         int flags = fcntl(m->dev_kmsg_fd, F_GETFL);
         if (flags < 0)
                 /* Proceed with reload in case the flags have changed. */
index 3be6296cea3605fe56676c423d3d451e51a7534f..727425225ff46aa2f8f5bc1e7502097c59d3ac77 100644 (file)
@@ -263,7 +263,7 @@ static void manager_add_acls(JournalFile *f, uid_t uid) {
 static JournalFileFlags manager_get_file_flags(Manager *m, bool seal) {
         assert(m);
 
-        return (m->compress.enabled ? JOURNAL_COMPRESS : 0) |
+        return (m->config.compress.enabled ? JOURNAL_COMPRESS : 0) |
                 (seal ? JOURNAL_SEAL : 0) |
                 JOURNAL_STRICT_ORDER;
 }
@@ -295,7 +295,7 @@ static int manager_open_journal(
                                 open_flags,
                                 file_flags,
                                 0640,
-                                m->compress.threshold_bytes,
+                                m->config.compress.threshold_bytes,
                                 metrics,
                                 m->mmap,
                                 &f);
@@ -306,7 +306,7 @@ static int manager_open_journal(
                                 open_flags,
                                 file_flags,
                                 0640,
-                                m->compress.threshold_bytes,
+                                m->config.compress.threshold_bytes,
                                 metrics,
                                 m->mmap,
                                 /* template= */ NULL,
@@ -378,7 +378,7 @@ static int manager_system_journal_open(
                                 /* reliably= */ true,
                                 fn,
                                 O_RDWR|O_CREAT,
-                                m->seal,
+                                m->config.seal,
                                 &m->system_storage.metrics,
                                 &m->system_journal);
                 if (r >= 0) {
@@ -486,7 +486,7 @@ static int manager_find_user_journal(Manager *m, uid_t uid, JournalFile **ret) {
                         /* reliably= */ true,
                         p,
                         O_RDWR|O_CREAT,
-                        m->seal,
+                        m->config.seal,
                         &m->system_storage.metrics,
                         &f);
         if (r < 0)
@@ -558,7 +558,7 @@ static int manager_do_rotate(
         if (!*f)
                 return -EINVAL;
 
-        r = journal_file_rotate(f, m->mmap, manager_get_file_flags(m, seal), m->compress.threshold_bytes, m->deferred_closes);
+        r = journal_file_rotate(f, m->mmap, manager_get_file_flags(m, seal), m->config.compress.threshold_bytes, m->deferred_closes);
         if (r < 0) {
                 if (*f)
                         return log_ratelimit_error_errno(r, JOURNAL_LOG_RATELIMIT,
@@ -668,9 +668,9 @@ static int manager_archive_offline_user_journals(Manager *m) {
                                 fd,
                                 full,
                                 O_RDWR,
-                                manager_get_file_flags(m, m->seal) & ~JOURNAL_STRICT_ORDER, /* strict order does not matter here */
+                                manager_get_file_flags(m, m->config.seal) & ~JOURNAL_STRICT_ORDER, /* strict order does not matter here */
                                 0640,
-                                m->compress.threshold_bytes,
+                                m->config.compress.threshold_bytes,
                                 &m->system_storage.metrics,
                                 m->mmap,
                                 /* template= */ NULL,
@@ -713,11 +713,11 @@ void manager_rotate(Manager *m) {
 
         /* First, rotate the system journal (either in its runtime flavour or in its runtime flavour) */
         (void) manager_do_rotate(m, &m->runtime_journal, "runtime", /* seal= */ false, /* uid= */ 0);
-        (void) manager_do_rotate(m, &m->system_journal, "system", m->seal, /* uid= */ 0);
+        (void) manager_do_rotate(m, &m->system_journal, "system", m->config.seal, /* uid= */ 0);
 
         /* Then, rotate all user journals we have open (keeping them open) */
         ORDERED_HASHMAP_FOREACH_KEY(f, k, m->user_journals) {
-                r = manager_do_rotate(m, &f, "user", m->seal, PTR_TO_UID(k));
+                r = manager_do_rotate(m, &f, "user", m->config.seal, PTR_TO_UID(k));
                 if (r >= 0)
                         ordered_hashmap_replace(m->user_journals, k, f);
                 else if (!f)
@@ -744,12 +744,12 @@ static void manager_rotate_journal(Manager *m, JournalFile *f, uid_t uid) {
          * ðŸ’£ðŸ’£ðŸ’£ This invalidate 'f', and the caller cannot reuse the passed JournalFile object. ðŸ’£ðŸ’£ðŸ’£ */
 
         if (f == m->system_journal)
-                (void) manager_do_rotate(m, &m->system_journal, "system", m->seal, /* uid= */ 0);
+                (void) manager_do_rotate(m, &m->system_journal, "system", m->config.seal, /* uid= */ 0);
         else if (f == m->runtime_journal)
                 (void) manager_do_rotate(m, &m->runtime_journal, "runtime", /* seal= */ false, /* uid= */ 0);
         else {
                 assert(ordered_hashmap_get(m->user_journals, UID_TO_PTR(uid)) == f);
-                r = manager_do_rotate(m, &f, "user", m->seal, uid);
+                r = manager_do_rotate(m, &f, "user", m->config.seal, uid);
                 if (r >= 0)
                         ordered_hashmap_replace(m->user_journals, UID_TO_PTR(uid), f);
                 else if (!f)
@@ -798,7 +798,7 @@ static void manager_do_vacuum(Manager *m, JournalStorage *storage, bool verbose)
                 manager_space_usage_message(m, storage);
 
         r = journal_directory_vacuum(storage->path, storage->space.limit,
-                                     storage->metrics.n_max_files, m->max_retention_usec,
+                                     storage->metrics.n_max_files, m->config.max_retention_usec,
                                      &m->oldest_file_usec, verbose);
         if (r < 0 && r != -ENOENT)
                 log_ratelimit_warning_errno(r, JOURNAL_LOG_RATELIMIT,
@@ -967,7 +967,7 @@ static void manager_write_to_journal(
         if (!f)
                 return;
 
-        if (journal_file_rotate_suggested(f, m->max_file_usec, LOG_DEBUG)) {
+        if (journal_file_rotate_suggested(f, m->config.max_file_usec, LOG_DEBUG)) {
                 if (vacuumed) {
                         log_ratelimit_warning(JOURNAL_LOG_RATELIMIT,
                                               "Suppressing rotation, as we already rotated immediately before write attempt. Giving up.");
@@ -1177,10 +1177,10 @@ static void manager_dispatch_message_real(
         iovec[n++] = in_initrd() ? IOVEC_MAKE_STRING("_RUNTIME_SCOPE=initrd") : IOVEC_MAKE_STRING("_RUNTIME_SCOPE=system");
         assert(n <= mm);
 
-        if (m->split_mode == SPLIT_UID && c && uid_is_valid(c->uid))
+        if (m->config.split_mode == SPLIT_UID && c && uid_is_valid(c->uid))
                 /* Split up strictly by (non-root) UID */
                 journal_uid = c->uid;
-        else if (m->split_mode == SPLIT_LOGIN && c && c->uid > 0 && uid_is_valid(c->owner_uid))
+        else if (m->config.split_mode == SPLIT_LOGIN && c && c->uid > 0 && uid_is_valid(c->owner_uid))
                 /* Split up by login UIDs.  We do this only if the
                  * realuid is not root, in order not to accidentally
                  * leak privileged information to the user that is
@@ -1881,21 +1881,21 @@ static int manager_schedule_sync(Manager *m, int priority) {
         if (m->sync_scheduled)
                 return 0;
 
-        if (m->sync_interval_usec > 0) {
+        if (m->config.sync_interval_usec > 0) {
 
                 if (!m->sync_event_source) {
                         r = sd_event_add_time_relative(
                                         m->event,
                                         &m->sync_event_source,
                                         CLOCK_MONOTONIC,
-                                        m->sync_interval_usec, 0,
+                                        m->config.sync_interval_usec, 0,
                                         manager_dispatch_sync, m);
                         if (r < 0)
                                 return r;
 
                         r = sd_event_source_set_priority(m->sync_event_source, SD_EVENT_PRIORITY_IMPORTANT);
                 } else {
-                        r = sd_event_source_set_time_relative(m->sync_event_source, m->sync_interval_usec);
+                        r = sd_event_source_set_time_relative(m->sync_event_source, m->config.sync_interval_usec);
                         if (r < 0)
                                 return r;
 
@@ -2125,7 +2125,7 @@ static bool manager_is_idle(Manager *m) {
 
         /* If a retention maximum is set larger than the idle time we need to be running to enforce it, hence
          * turn off the idle logic. */
-        if (m->max_retention_usec > IDLE_TIMEOUT_USEC)
+        if (m->config.max_retention_usec > IDLE_TIMEOUT_USEC)
                 return false;
 
         /* We aren't idle if we have a varlink client */
@@ -2258,8 +2258,8 @@ int manager_reload_journals(Manager *m) {
                 /* Current journal can continue being used. Update config values as needed. */
                 r = journal_file_reload(
                                 m->system_journal,
-                                manager_get_file_flags(m, m->seal),
-                                m->compress.threshold_bytes,
+                                manager_get_file_flags(m, m->config.seal),
+                                m->config.compress.threshold_bytes,
                                 &m->system_storage.metrics);
                 if (r < 0)
                         return log_warning_errno(r, "Failed to reload system journal on reload, ignoring: %m");
@@ -2273,7 +2273,7 @@ int manager_reload_journals(Manager *m) {
                 r = journal_file_reload(
                                 m->runtime_journal,
                                 manager_get_file_flags(m, /* seal */ false),
-                                m->compress.threshold_bytes,
+                                m->config.compress.threshold_bytes,
                                 &m->runtime_storage.metrics);
                 if (r < 0)
                         return log_warning_errno(r, "Failed to reload runtime journal on reload, ignoring: %m");
@@ -2308,6 +2308,9 @@ int manager_new(Manager **ret, const char *namespace) {
                 .notify_fd = -EBADF,
                 .forward_socket_fd = -EBADF,
 
+                .system_storage.name = "System Journal",
+                .runtime_storage.name = "Runtime Journal",
+
                 .watchdog_usec = USEC_INFINITY,
 
                 .sync_scheduled = false,
@@ -2602,7 +2605,6 @@ Manager* manager_free(Manager *m) {
         manager_unmap_seqnum_file(m->kernel_seqnum, sizeof(*m->kernel_seqnum));
 
         free(m->buffer);
-        free(m->tty_path);
         free(m->cgroup_root);
         free(m->hostname_field);
         free(m->runtime_storage.path);
@@ -2620,5 +2622,10 @@ Manager* manager_free(Manager *m) {
                 sync_req_free(req);
         prioq_free(m->sync_req_boottime_prioq);
 
+        journal_config_done(&m->config);
+        journal_config_done(&m->config_by_cred);
+        journal_config_done(&m->config_by_conf);
+        journal_config_done(&m->config_by_cmdline);
+
         return mfree(m);
 }
index ac538a12e753e3ad3848a47d738be272f99755a9..05a84bf8f18023674939005dafe251f3dcfdf413 100644 (file)
@@ -74,18 +74,10 @@ typedef struct Manager {
         char *buffer;
 
         OrderedHashmap *ratelimit_groups_by_id;
-        usec_t sync_interval_usec;
-        usec_t ratelimit_interval;
-        unsigned ratelimit_burst;
 
         JournalStorage runtime_storage;
         JournalStorage system_storage;
 
-        JournalCompressOptions compress;
-        int set_audit;
-        bool seal;
-        bool read_kmsg;
-
         bool send_watchdog;
         bool sent_notify_ready;
         bool sync_scheduled;
@@ -93,18 +85,12 @@ typedef struct Manager {
         unsigned n_forward_syslog_missed;
         usec_t last_warn_forward_syslog_missed;
 
-        usec_t max_retention_usec;
-        usec_t max_file_usec;
         usec_t oldest_file_usec;
 
         LIST_HEAD(StdoutStream, stdout_streams);
         LIST_HEAD(StdoutStream, stdout_streams_notify_queue);
         unsigned n_stdout_streams;
 
-        char *tty_path;
-
-        SplitMode split_mode;
-
         MMapCache *mmap;
 
         Set *deferred_closes;
@@ -125,8 +111,6 @@ typedef struct Manager {
 
         usec_t last_realtime_clock;
 
-        size_t line_max;
-
         /* Caching of client metadata */
         Hashmap *client_contexts;
         Prioq *client_contexts_lru;
index cfd17fcd83dcfd9bcbdf83cd5ad630e6e293fe5a..650b81da5f8f82fad3aad5f8bfc708d00ef6fc36 100644 (file)
@@ -454,7 +454,7 @@ static size_t stdout_stream_line_max(StdoutStream *s) {
                 return STDOUT_STREAM_SETUP_PROTOCOL_LINE_MAX;
 
         /* After the protocol's "setup" phase is complete, let's use whatever the user configured */
-        return s->manager->line_max;
+        return s->manager->config.line_max;
 }
 
 static int stdout_stream_scan(
@@ -557,7 +557,7 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents,
 
         /* Try to make use of the allocated buffer in full, but never read more than the configured line size. Also,
          * always leave room for a terminating NUL we might need to add. */
-        limit = MIN(allocated - 1, MAX(s->manager->line_max, STDOUT_STREAM_SETUP_PROTOCOL_LINE_MAX));
+        limit = MIN(allocated - 1, MAX(s->manager->config.line_max, STDOUT_STREAM_SETUP_PROTOCOL_LINE_MAX));
         assert(s->length <= limit);
         iovec = IOVEC_MAKE(s->buffer + s->length, limit - s->length);
 
index 95787418d228c93101f4f025e552917146af373c..393e90e1b5245e85697ea0bbf3323c2f16bfb6f9 100644 (file)
@@ -91,9 +91,9 @@ static int run(int argc, char *argv[]) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to get the current time: %m");
 
-                if (m->max_retention_usec > 0 && m->oldest_file_usec > 0) {
+                if (m->config.max_retention_usec > 0 && m->oldest_file_usec > 0) {
                         /* Calculate when to rotate the next time */
-                        t = usec_sub_unsigned(usec_add(m->oldest_file_usec, m->max_retention_usec), n);
+                        t = usec_sub_unsigned(usec_add(m->oldest_file_usec, m->config.max_retention_usec), n);
 
                         /* The retention time is reached, so let's vacuum! */
                         if (t <= 0) {
index 5eb089a8cb14ee353a7812e1994de7ead959287a..735e4d664a8693a5e1273602198abdff857e5777 100644 (file)
@@ -13,7 +13,7 @@
 
 #define _COMPRESS_PARSE_CHECK(str, enab, thresh, varname)               \
         do {                                                            \
-                JournalCompressOptions varname = {true, 111};           \
+                JournalCompressOptions varname = {-222, 111};           \
                 config_parse_compress("", "", 0, "", 0, "", 0, str,     \
                                       &varname, NULL);                  \
                 assert_se((enab) == varname.enabled);                   \
@@ -48,9 +48,9 @@ TEST(config_compress) {
         COMPRESS_PARSE_CHECK("1G", true, 1024 * 1024 * 1024);
 
         /* Invalid Case */
-        COMPRESS_PARSE_CHECK("-1", true, 111);
-        COMPRESS_PARSE_CHECK("blah blah", true, 111);
-        COMPRESS_PARSE_CHECK("", true, UINT64_MAX);
+        COMPRESS_PARSE_CHECK("-1", -222, 111);
+        COMPRESS_PARSE_CHECK("blah blah", -222, 111);
+        COMPRESS_PARSE_CHECK("", -1, UINT64_MAX);
 }
 
 #define _FORWARD_TO_SOCKET_PARSE_CHECK_FAILS(str, addr, varname)             \