chiark / gitweb /
process-util: add another fork_safe() flag for enabling LOG_ERR/LOG_WARN logging
authorLennart Poettering <lennart@poettering.net>
Wed, 27 Dec 2017 20:49:19 +0000 (21:49 +0100)
committerSven Eden <yamakuzure@gmx.net>
Wed, 30 May 2018 05:49:50 +0000 (07:49 +0200)
src/basic/exec-util.c
src/basic/process-util.c
src/basic/process-util.h
src/login/inhibit.c
src/shared/pager.c

index 19ac3686cdcc595e04b4c19044087ea2a99218f9..8a4b38cebe297903ab84fd88df122db3a5521f27 100644 (file)
@@ -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);
index ca0d4426b4893d55cd4a8fc80ec77432d4e5749a..a9736119ca20a8705ee653d5c91955ccb5e97c14 100644 (file)
@@ -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);
                 }
         }
index 1609c48df1c17214db55902589b2763151010dd7..e971a3f494b88bf8510b3815ce8ffaa9bb7769a4 100644 (file)
@@ -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);
index 3ea5124b3a702d3e7a35b34fe699695083c34d54..76571217ff362a845f068eff3a177a3cb7a201d3 100644 (file)
@@ -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);
index 1f0d0b8872c0cd437765aabeb9503a2f77d52c40..587b1c8853921dd2f218e9112c9f8a8645a7839c 100644 (file)
@@ -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);