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.
This commit is contained in:
DaanDeMeyer
2025-07-14 15:07:48 +02:00
parent be3f7aaf44
commit e4691ebb49
5 changed files with 48 additions and 40 deletions
+3 -3
View File
@@ -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);
@@ -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);
}
@@ -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 journal_terminate(PidRef *pidref);
void fork_notify_terminate(PidRef *pidref);
int journal_fork(RuntimeScope scope, char * const *units, PidRef *ret_pidref);
+1 -1
View File
@@ -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',
+2 -2
View File
@@ -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 {