From: Lennart Poettering Date: Wed, 27 Dec 2017 20:49:19 +0000 (+0100) Subject: process-util: add another fork_safe() flag for enabling LOG_ERR/LOG_WARN logging X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=093bfffb485caf4d1d328e9585641005029a83d9;p=elogind.git process-util: add another fork_safe() flag for enabling LOG_ERR/LOG_WARN logging --- diff --git a/src/basic/exec-util.c b/src/basic/exec-util.c index 19ac3686c..8a4b38ceb 100644 --- a/src/basic/exec-util.c +++ b/src/basic/exec-util.c @@ -55,9 +55,9 @@ static int do_spawn(const char *path, char *argv[], int stdout_fd, pid_t *pid) { return 0; } - r = safe_fork("(direxec)", FORK_DEATHSIG, &_pid); + r = safe_fork("(direxec)", FORK_DEATHSIG|FORK_LOG, &_pid); if (r < 0) - return log_error_errno(r, "Failed to fork: %m"); + return r; if (r == 0) { char *_argv[2]; @@ -220,9 +220,9 @@ int execute_directories( * them to finish. Optionally a timeout is applied. If a file with the same name * exists in more than one directory, the earliest one wins. */ - r = safe_fork("(sd-executor)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &executor_pid); + r = safe_fork("(sd-executor)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &executor_pid); if (r < 0) - return log_error_errno(r, "Failed to fork: %m"); + return r; if (r == 0) { r = do_execute(dirs, timeout, callbacks, callback_args, fd, argv); _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); diff --git a/src/basic/process-util.c b/src/basic/process-util.c index ca0d4426b..a9736119c 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -1166,11 +1166,13 @@ int safe_fork_full( pid_t original_pid, pid; sigset_t saved_ss; bool block_signals; - int r; + int prio, r; /* A wrapper around fork(), that does a couple of important initializations in addition to mere forking. Always * returns the child's PID in *ret_pid. Returns == 0 in the child, and > 0 in the parent. */ + prio = flags & FORK_LOG ? LOG_ERR : LOG_DEBUG; + original_pid = getpid_cached(); block_signals = flags & (FORK_RESET_SIGNALS|FORK_DEATHSIG); @@ -1181,10 +1183,10 @@ int safe_fork_full( /* We temporarily block all signals, so that the new child has them blocked initially. This way, we can be sure * that SIGTERMs are not lost we might send to the child. */ if (sigfillset(&ss) < 0) - return log_debug_errno(errno, "Failed to reset signal set: %m"); + return log_full_errno(prio, errno, "Failed to reset signal set: %m"); if (sigprocmask(SIG_SETMASK, &ss, &saved_ss) < 0) - return log_debug_errno(errno, "Failed to reset signal mask: %m"); + return log_full_errno(prio, errno, "Failed to reset signal mask: %m"); } pid = fork(); @@ -1194,7 +1196,7 @@ int safe_fork_full( if (block_signals) /* undo what we did above */ (void) sigprocmask(SIG_SETMASK, &saved_ss, NULL); - return log_debug_errno(r, "Failed to fork: %m"); + return log_full_errno(prio, r, "Failed to fork: %m"); } if (pid > 0) { /* We are in the parent process */ @@ -1221,31 +1223,32 @@ int safe_fork_full( if (name) { r = rename_process(name); if (r < 0) - log_debug_errno(r, "Failed to rename process, ignoring: %m"); + log_full_errno(flags & FORK_LOG ? LOG_WARNING : LOG_DEBUG, + r, "Failed to rename process, ignoring: %m"); } if (flags & FORK_DEATHSIG) if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) { - log_debug_errno(errno, "Failed to set death signal: %m"); + log_full_errno(prio, errno, "Failed to set death signal: %m"); _exit(EXIT_FAILURE); } if (flags & FORK_RESET_SIGNALS) { r = reset_all_signal_handlers(); if (r < 0) { - log_debug_errno(r, "Failed to reset signal handlers: %m"); + log_full_errno(prio, r, "Failed to reset signal handlers: %m"); _exit(EXIT_FAILURE); } /* This implicitly undoes the signal mask stuff we did before the fork()ing above */ r = reset_signal_mask(); if (r < 0) { - log_debug_errno(r, "Failed to reset signal mask: %m"); + log_full_errno(prio, r, "Failed to reset signal mask: %m"); _exit(EXIT_FAILURE); } } else if (block_signals) { /* undo what we did above */ if (sigprocmask(SIG_SETMASK, &saved_ss, NULL) < 0) { - log_debug_errno(errno, "Failed to restore signal mask: %m"); + log_full_errno(prio, errno, "Failed to restore signal mask: %m"); _exit(EXIT_FAILURE); } } @@ -1271,7 +1274,7 @@ int safe_fork_full( r = close_all_fds(except_fds, n_except_fds); if (r < 0) { - log_debug_errno(r, "Failed to close all file descriptors: %m"); + log_full_errno(prio, r, "Failed to close all file descriptors: %m"); _exit(EXIT_FAILURE); } } @@ -1285,7 +1288,7 @@ int safe_fork_full( if (flags & FORK_NULL_STDIO) { r = make_null_stdio(); if (r < 0) { - log_debug_errno(r, "Failed to connect stdin/stdout to /dev/null: %m"); + log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m"); _exit(EXIT_FAILURE); } } diff --git a/src/basic/process-util.h b/src/basic/process-util.h index 1609c48df..e971a3f49 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -171,6 +171,7 @@ typedef enum ForkFlags { FORK_DEATHSIG = 1U << 2, FORK_NULL_STDIO = 1U << 3, FORK_REOPEN_LOG = 1U << 4, + FORK_LOG = 1U << 5, } ForkFlags; int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid); diff --git a/src/login/inhibit.c b/src/login/inhibit.c index 3ea5124b3..76571217f 100644 --- a/src/login/inhibit.c +++ b/src/login/inhibit.c @@ -270,11 +270,9 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - r = safe_fork("(inhibit)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS, &pid); - if (r < 0) { - log_error_errno(r, "Failed to fork: %m"); + r = safe_fork("(inhibit)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid); + if (r < 0) return EXIT_FAILURE; - } if (r == 0) { /* Child */ execvp(argv[optind], argv + optind); diff --git a/src/shared/pager.c b/src/shared/pager.c index 1f0d0b887..587b1c885 100644 --- a/src/shared/pager.c +++ b/src/shared/pager.c @@ -89,9 +89,9 @@ int pager_open(bool no_pager, bool jump_to_end) { if (pipe2(fd, O_CLOEXEC) < 0) return log_error_errno(errno, "Failed to create pager pipe: %m"); - r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &pager_pid); + r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pager_pid); if (r < 0) - return log_error_errno(r, "Failed to fork pager: %m"); + return r; if (r == 0) { const char* less_opts, *less_charset; @@ -209,9 +209,9 @@ int show_man_page(const char *desc, bool null_stdio) { } else args[1] = desc; - r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_NULL_STDIO : 0), &pid); + r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_NULL_STDIO : 0)|FORK_LOG, &pid); if (r < 0) - return log_error_errno(r, "Failed to fork: %m"); + return r; if (r == 0) { /* Child */ execvp(args[0], (char**) args);