From e4691ebb49fb8fd883727991c187b37a6fb8753f Mon Sep 17 00:00:00 2001 From: DaanDeMeyer Date: Wed, 2 Jul 2025 16:25:15 +0200 Subject: [PATCH] fork-journal: Generalize to fork-notify Most of the logic isn't journalctl specific, let's generalize a bit so we can reuse this for other commands as well. --- src/run/run.c | 6 +- src/shared/{fork-journal.c => fork-notify.c} | 70 +++++++++++--------- src/shared/{fork-journal.h => fork-notify.h} | 6 +- src/shared/meson.build | 2 +- src/systemctl/systemctl-start-unit.c | 4 +- 5 files changed, 48 insertions(+), 40 deletions(-) rename src/shared/{fork-journal.c => fork-notify.c} (86%) rename src/shared/{fork-journal.h => fork-notify.h} (61%) diff --git a/src/run/run.c b/src/run/run.c index b7c4facabc7..69d0490e57d 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -34,7 +34,7 @@ #include "exec-util.h" #include "exit-status.h" #include "fd-util.h" -#include "fork-journal.h" +#include "fork-notify.h" #include "format-table.h" #include "format-util.h" #include "fs-util.h" @@ -2438,7 +2438,7 @@ static int start_transient_service(sd_bus *bus) { return r; peer_fd = safe_close(peer_fd); - _cleanup_(journal_terminate) PidRef journal_pid = PIDREF_NULL; + _cleanup_(fork_notify_terminate) PidRef journal_pid = PIDREF_NULL; if (arg_verbose) (void) journal_fork(arg_runtime_scope, STRV_MAKE(c.unit), &journal_pid); @@ -2517,7 +2517,7 @@ static int start_transient_service(sd_bus *bus) { return log_error_errno(r, "Failed to run event loop: %m"); /* Close the journal watch logic before we output the exit summary */ - journal_terminate(&journal_pid); + fork_notify_terminate(&journal_pid); if (arg_wait && !arg_quiet) run_context_show_result(&c); diff --git a/src/shared/fork-journal.c b/src/shared/fork-notify.c similarity index 86% rename from src/shared/fork-journal.c rename to src/shared/fork-notify.c index ec22a700613..c1331c06a00 100644 --- a/src/shared/fork-journal.c +++ b/src/shared/fork-notify.c @@ -7,7 +7,7 @@ #include "escape.h" #include "event-util.h" #include "exit-status.h" -#include "fork-journal.h" +#include "fork-notify.h" #include "log.h" #include "notify-recv.h" #include "parse-util.h" @@ -27,13 +27,13 @@ static int on_child_exit(sd_event_source *s, const siginfo_t *si, void *userdata if (si->si_code == CLD_EXITED) { if (si->si_status == EXIT_SUCCESS) - log_debug("journalctl " PID_FMT " exited successfully.", si->si_pid); + log_debug("Child process " PID_FMT " exited successfully.", si->si_pid); else - log_debug("journalctl " PID_FMT " died with a failure exit status %i, ignoring.", si->si_pid, si->si_status); + log_debug("Child process " PID_FMT " died with a failure exit status %i, ignoring.", si->si_pid, si->si_status); } else if (si->si_code == CLD_KILLED) - log_debug("journalctl " PID_FMT " was killed by signal %s, ignoring.", si->si_pid, signal_to_string(si->si_status)); + log_debug("Child process " PID_FMT " was killed by signal %s, ignoring.", si->si_pid, signal_to_string(si->si_status)); else if (si->si_code == CLD_DUMPED) - log_debug("journalctl " PID_FMT " dumped core by signal %s, ignoring.", si->si_pid, signal_to_string(si->si_status)); + log_debug("Child process " PID_FMT " dumped core by signal %s, ignoring.", si->si_pid, signal_to_string(si->si_status)); else log_debug("Got unexpected exit code %i via SIGCHLD, ignoring.", si->si_code); @@ -87,19 +87,15 @@ static int on_child_notify(sd_event_source *s, int fd, uint32_t revents, void *u return 0; } -int journal_fork(RuntimeScope scope, char * const *units, PidRef *ret_pidref) { +int fork_notify(char * const *argv, PidRef *ret_pidref) { int r; - assert(scope >= 0); - assert(scope < _RUNTIME_SCOPE_MAX); + assert(!strv_isempty(argv)); assert(ret_pidref); if (!is_main_thread()) return -EPERM; - if (strv_isempty(units)) - return 0; - _cleanup_(sd_event_unrefp) sd_event *event = NULL; r = sd_event_new(&event); if (r < 0) @@ -123,22 +119,6 @@ int journal_fork(RuntimeScope scope, char * const *units, PidRef *ret_pidref) { if (r < 0) return r; - _cleanup_strv_free_ char **argv = strv_new( - "journalctl", - "-q", - "--follow", - "--no-pager", - "--lines=1", - "--synchronize-on-exit=yes"); - if (!argv) - return log_oom_debug(); - - STRV_FOREACH(u, units) - if (strv_extendf(&argv, - scope == RUNTIME_SCOPE_SYSTEM ? "--unit=%s" : "--user-unit=%s", - *u) < 0) - return log_oom_debug(); - if (DEBUG_LOGGING) { _cleanup_free_ char *l = quote_command_line(argv, SHELL_ESCAPE_EMPTY); log_debug("Invoking '%s' as child.", strnull(l)); @@ -147,7 +127,7 @@ int journal_fork(RuntimeScope scope, char * const *units, PidRef *ret_pidref) { BLOCK_SIGNALS(SIGCHLD); r = pidref_safe_fork_full( - "(journalctl)", + "(fork-notify)", (const int[3]) { -EBADF, STDOUT_FILENO, STDERR_FILENO }, /* except_fds= */ NULL, /* n_except_fds= */ 0, @@ -164,7 +144,7 @@ int journal_fork(RuntimeScope scope, char * const *units, PidRef *ret_pidref) { } r = invoke_callout_binary(argv[0], argv); - log_debug_errno(r, "Failed to invoke journalctl: %m"); + log_debug_errno(r, "Failed to invoke %s: %m", argv[0]); _exit(EXIT_EXEC); } @@ -177,7 +157,7 @@ int journal_fork(RuntimeScope scope, char * const *units, PidRef *ret_pidref) { if (r < 0) return r; - (void) sd_event_source_set_description(child_event_source, "fork-journal-child"); + (void) sd_event_source_set_description(child_event_source, "fork-notify-child"); r = sd_event_loop(event); if (r < 0) @@ -189,7 +169,7 @@ int journal_fork(RuntimeScope scope, char * const *units, PidRef *ret_pidref) { return 0; } -void journal_terminate(PidRef *pidref) { +void fork_notify_terminate(PidRef *pidref) { int r; if (!pidref_is_set(pidref)) @@ -199,6 +179,32 @@ void journal_terminate(PidRef *pidref) { if (r < 0 && r != -ESRCH) log_debug_errno(r, "Failed to send SIGTERM to journalctl child " PID_FMT ", ignoring: %m", pidref->pid); - (void) pidref_wait_for_terminate_and_check("journalctl", pidref, /* flags= */ 0); + (void) pidref_wait_for_terminate_and_check(/* name= */ NULL, pidref, /* flags= */ 0); pidref_done(pidref); } + +int journal_fork(RuntimeScope scope, char * const* units, PidRef *ret_pidref) { + assert(scope >= 0); + assert(scope < _RUNTIME_SCOPE_MAX); + + if (strv_isempty(units)) + return 0; + + _cleanup_strv_free_ char **argv = strv_new( + "journalctl", + "-q", + "--follow", + "--no-pager", + "--lines=1", + "--synchronize-on-exit=yes"); + if (!argv) + return log_oom_debug(); + + STRV_FOREACH(u, units) + if (strv_extendf(&argv, + scope == RUNTIME_SCOPE_SYSTEM ? "--unit=%s" : "--user-unit=%s", + *u) < 0) + return log_oom_debug(); + + return fork_notify(argv, ret_pidref); +} diff --git a/src/shared/fork-journal.h b/src/shared/fork-notify.h similarity index 61% rename from src/shared/fork-journal.h rename to src/shared/fork-notify.h index a53a452b26a..71e2c3ce321 100644 --- a/src/shared/fork-journal.h +++ b/src/shared/fork-notify.h @@ -3,6 +3,8 @@ #include "forward.h" -int journal_fork(RuntimeScope scope, char * const *units, PidRef *ret_pidref); +int fork_notify(char * const *cmdline, PidRef *ret_pidref); + +void fork_notify_terminate(PidRef *pidref); -void journal_terminate(PidRef *pidref); +int journal_fork(RuntimeScope scope, char * const *units, PidRef *ret_pidref); diff --git a/src/shared/meson.build b/src/shared/meson.build index 2a49a5e9b88..06e2ae3b1d2 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -78,7 +78,7 @@ shared_sources = files( 'find-esp.c', 'firewall-util-nft.c', 'firewall-util.c', - 'fork-journal.c', + 'fork-notify.c', 'format-table.c', 'fstab-util.c', 'generator.c', diff --git a/src/systemctl/systemctl-start-unit.c b/src/systemctl/systemctl-start-unit.c index 7ff5548ba85..92a89302df0 100644 --- a/src/systemctl/systemctl-start-unit.c +++ b/src/systemctl/systemctl-start-unit.c @@ -10,7 +10,7 @@ #include "bus-util.h" #include "bus-wait-for-jobs.h" #include "bus-wait-for-units.h" -#include "fork-journal.h" +#include "fork-notify.h" #include "pidref.h" #include "runtime-scope.h" #include "special.h" @@ -390,7 +390,7 @@ int verb_start(int argc, char *argv[], void *userdata) { return log_error_errno(r, "Failed to allocate unit watch context: %m"); } - _cleanup_(journal_terminate) PidRef journal_pid = PIDREF_NULL; + _cleanup_(fork_notify_terminate) PidRef journal_pid = PIDREF_NULL; if (arg_marked) ret = enqueue_marked_jobs(bus, w); else { -- 2.47.3