From: Yu Watanabe Date: Tue, 15 Jul 2025 17:55:55 +0000 (+0900) Subject: journald-manager: rework reopening journal files on reload X-Git-Tag: v258-rc1~34^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=922d037f349b72139480cdded41b3fa23a3001be;p=thirdparty%2Fsystemd.git journald-manager: rework reopening journal files on reload Previous implementations had several issues: - user journals were not updated, - transition from volatile -> persistent storage transition was not handled. Let's make all journal files closed when at least one journal file related configurations are changed, and reopen necessary journals with requested settings. --- diff --git a/src/journal/journald-config.c b/src/journal/journald-config.c index cf5b1b359c5..4a514cd573f 100644 --- a/src/journal/journald-config.c +++ b/src/journal/journald-config.c @@ -363,7 +363,6 @@ static void manager_reload_config(Manager *m) { int manager_dispatch_reload_signal(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { Manager *m = ASSERT_PTR(userdata); - int r; (void) notify_reloading(); @@ -375,10 +374,7 @@ int manager_dispatch_reload_signal(sd_event_source *s, const struct signalfd_sig manager_reset_kernel_audit(m, old.set_audit); manager_reload_forward_socket(m, &old.forward_to_socket); manager_refresh_client_contexts_on_reload(m, old.ratelimit_interval, old.ratelimit_burst); - - r = manager_reload_journals(m); - if (r < 0) - return r; + manager_reopen_journals(m, &old); log_info("Config file reloaded."); (void) sd_notify(/* unset_environment */ false, NOTIFY_READY_MESSAGE); diff --git a/src/journal/journald-manager.c b/src/journal/journald-manager.c index 494bf7c4811..bd2a05489df 100644 --- a/src/journal/journald-manager.c +++ b/src/journal/journald-manager.c @@ -2263,43 +2263,34 @@ static int manager_setup_memory_pressure(Manager *m) { return 0; } -int manager_reload_journals(Manager *m) { +void manager_reopen_journals(Manager *m, const JournalConfig *old) { assert(m); - int r; + if (m->config.storage == old->storage && + m->config.compress.enabled == old->compress.enabled && + m->config.compress.threshold_bytes == old->compress.threshold_bytes && + m->config.seal == old->seal && + m->config.sync_interval_usec == old->sync_interval_usec && + journal_metrics_equal(&m->config.system_storage_metrics, &old->system_storage_metrics) && + journal_metrics_equal(&m->config.runtime_storage_metrics, &old->runtime_storage_metrics)) + return; /* no-op */ + + /* Explicitly close the runtime journal to make it reopened later by manager_system_journal_open(). + * But only when volatile (or no) storage is requested. If auto or persistent storage is requested, + * we may need to flush the runtime journal to the persistent storage, it will done through + * manager_system_journal_open(). Hence, we should not touch the runtime journal here in that case. */ + if (IN_SET(m->config.storage, STORAGE_VOLATILE, STORAGE_NONE)) + m->runtime_journal = journal_file_offline_close(m->runtime_journal); + + /* Close other journals unconditionally to make the new settings applied. */ + m->system_journal = journal_file_offline_close(m->system_journal); + ordered_hashmap_clear(m->user_journals); + set_clear(m->deferred_closes); - if (m->system_journal && IN_SET(m->config.storage, STORAGE_PERSISTENT, STORAGE_AUTO)) { - /* Current journal can continue being used. Update config values as needed. */ - r = journal_file_reload( - m->system_journal, - 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"); - } else if (m->system_journal && m->config.storage == STORAGE_VOLATILE) { - /* Journal needs to be switched from system to runtime. */ - r = manager_relinquish_var(m); - if (r < 0) - return log_warning_errno(r, "Failed to relinquish to runtime journal on reload, ignoring: %m"); - } else if (m->runtime_journal && IN_SET(m->config.storage, STORAGE_PERSISTENT, STORAGE_AUTO, STORAGE_VOLATILE)) { - /* Current journal can continue being used. Update config values as needed.*/ - r = journal_file_reload( - m->runtime_journal, - manager_get_file_flags(m, /* seal */ false), - 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"); - } + (void) manager_system_journal_open(m, /* flush_requested = */ false, /* relinquish_requested = */ false); - /* If journal-related configuration, such as SystemMaxUse, SystemMaxFileSize, RuntimeMaxUse, RuntimeMaxFileSize, - * were to change, then we can vacuum for the change to take effect. For example, if pre-reload SystemMaxUse=2M, - * current usage=1.5M, and the post-reload SystemMaxUse=1M, the vacuum can shrink it to 1M. - */ + /* To make the storage related settings applied, vacuum the storage. */ manager_vacuum(m, /* verbose */ false); - - return 0; } int manager_new(Manager **ret) { diff --git a/src/journal/journald-manager.h b/src/journal/journald-manager.h index 4453fbe9adc..c103a7fc2a6 100644 --- a/src/journal/journald-manager.h +++ b/src/journal/journald-manager.h @@ -189,7 +189,7 @@ int manager_process_datagram(sd_event_source *es, int fd, uint32_t revents, void void manager_space_usage_message(Manager *m, JournalStorage *storage); int manager_start_or_stop_idle_timer(Manager *m); -int manager_reload_journals(Manager *m); +void manager_reopen_journals(Manager *m, const JournalConfig *old); int manager_map_seqnum_file(Manager *m, const char *fname, size_t size, void **ret); void manager_unmap_seqnum_file(void *p, size_t size);