diff --git a/src/journal/journald-audit.c b/src/journal/journald-audit.c index ebf401c4c2..479a4d2791 100644 --- a/src/journal/journald-audit.c +++ b/src/journal/journald-audit.c @@ -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."); diff --git a/src/journal/journald-config.c b/src/journal/journald-config.c index 648ac55d7e..cece07411f 100644 --- a/src/journal/journald-config.c +++ b/src/journal/journald-config.c @@ -26,115 +26,121 @@ * 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, \ - } +void journal_config_done(JournalConfig *c) { + assert(c); -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; - - m->config.forward_to_wall = true; - - 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; - - m->line_max = DEFAULT_LINE_MAX; + free(c->tty_path); } -static void manager_reset_configs(Manager *m) { +static void journal_config_set_defaults(JournalConfig *c) { + assert(c); + + 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_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 }; + m->config.forward_to_socket = (SocketAddress) {}; } -static void manager_merge_storage(Manager *m) { - assert(m); +#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 - /* 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; -} - -#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_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; } diff --git a/src/journal/journald-config.h b/src/journal/journald-config.h index ffa6c5f2b8..31077acba2 100644 --- a/src/journal/journald-config.h +++ b/src/journal/journald-config.h @@ -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); diff --git a/src/journal/journald-console.c b/src/journal/journald-console.c index 73cccb4da9..0f376f9e5a 100644 --- a/src/journal/journald-console.c +++ b/src/journal/journald-console.c @@ -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, diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c index a6b34f14e4..e6d0c70e02 100644 --- a/src/journal/journald-context.c +++ b/src/journal/journald-context.c @@ -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); diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf index 26cd08b384..23caa287ff 100644 --- a/src/journal/journald-gperf.gperf +++ b/src/journal/journald-gperf.gperf @@ -6,7 +6,7 @@ _Pragma("GCC diagnostic ignored \"-Wzero-as-null-pointer-constant\"") #endif #include #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) diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c index 926cc823db..ec05e1f1b4 100644 --- a/src/journal/journald-kmsg.c +++ b/src/journal/journald-kmsg.c @@ -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. */ diff --git a/src/journal/journald-manager.c b/src/journal/journald-manager.c index 3be6296cea..727425225f 100644 --- a/src/journal/journald-manager.c +++ b/src/journal/journald-manager.c @@ -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); } diff --git a/src/journal/journald-manager.h b/src/journal/journald-manager.h index ac538a12e7..05a84bf8f1 100644 --- a/src/journal/journald-manager.h +++ b/src/journal/journald-manager.h @@ -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; diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c index cfd17fcd83..650b81da5f 100644 --- a/src/journal/journald-stream.c +++ b/src/journal/journald-stream.c @@ -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); diff --git a/src/journal/journald.c b/src/journal/journald.c index 95787418d2..393e90e1b5 100644 --- a/src/journal/journald.c +++ b/src/journal/journald.c @@ -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) { diff --git a/src/journal/test-journald-config.c b/src/journal/test-journald-config.c index 5eb089a8cb..735e4d664a 100644 --- a/src/journal/test-journald-config.c +++ b/src/journal/test-journald-config.c @@ -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) \