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:
+3
-3
@@ -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);
|
||||
@@ -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',
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user