diff options
author | Lennart Poettering <lennart@poettering.net> | 2017-12-22 13:08:14 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2017-12-25 11:48:21 +0100 |
commit | 4c253ed1cae8b4df72ce1353ee826a4fae399e25 (patch) | |
tree | 5fc52b199a402b4ddaae0e3005fa85cc610c377f /src/core/unit.c | |
parent | d8caff6db672ab0f2d8064c61f5ef0e8e8d288ca (diff) | |
download | systemd-4c253ed1cae8b4df72ce1353ee826a4fae399e25.tar.gz |
tree-wide: introduce new safe_fork() helper and port everything over
This adds a new safe_fork() wrapper around fork() and makes use of it
everywhere. The new wrapper does a couple of things we previously did
manually and separately in a safer, more correct and automatic way:
1. Optionally resets signal handlers/mask in the child
2. Sets a name on all processes we fork off right after forking off (and
the patch assigns useful names for all processes we fork off now,
following a systematic naming scheme: always enclosed in () – in order
to indicate that these are not proper, exec()ed processes, but only
forked off children, and if the process is long-running with only our
own code, without execve()'ing something else, it gets am "sd-" prefix.)
3. Optionally closes all file descriptors in the child
4. Optionally sets a PR_SET_DEATHSIG to SIGTERM in the child, in a safe
way so that the parent dying before this happens being handled
safely.
5. Optionally reopens the logs
6. Optionally connects stdin/stdout/stderr to /dev/null
7. Debug logs about the forked off processes.
Diffstat (limited to 'src/core/unit.c')
-rw-r--r-- | src/core/unit.c | 36 |
1 files changed, 14 insertions, 22 deletions
diff --git a/src/core/unit.c b/src/core/unit.c index 7af8425707..652587e6ad 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -21,6 +21,7 @@ #include <errno.h> #include <stdlib.h> #include <string.h> +#include <sys/prctl.h> #include <sys/stat.h> #include <unistd.h> @@ -4968,8 +4969,7 @@ void unit_set_exec_params(Unit *u, ExecParameters *p) { SET_FLAG(p->flags, EXEC_CGROUP_DELEGATE, UNIT_CGROUP_BOOL(u, delegate)); } -int unit_fork_helper_process(Unit *u, pid_t *ret) { - pid_t pid; +int unit_fork_helper_process(Unit *u, const char *name, pid_t *ret) { int r; assert(u); @@ -4980,32 +4980,24 @@ int unit_fork_helper_process(Unit *u, pid_t *ret) { (void) unit_realize_cgroup(u); - pid = fork(); - if (pid < 0) - return -errno; - - if (pid == 0) { + r = safe_fork(name, FORK_REOPEN_LOG, ret); + if (r != 0) + return r; - (void) default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); - (void) ignore_signals(SIGPIPE, -1); + (void) default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); + (void) ignore_signals(SIGPIPE, -1); - log_close(); - log_open(); + (void) prctl(PR_SET_PDEATHSIG, SIGTERM); - if (u->cgroup_path) { - r = cg_attach_everywhere(u->manager->cgroup_supported, u->cgroup_path, 0, NULL, NULL); - if (r < 0) { - log_unit_error_errno(u, r, "Failed to join unit cgroup %s: %m", u->cgroup_path); - _exit(EXIT_CGROUP); - } + if (u->cgroup_path) { + r = cg_attach_everywhere(u->manager->cgroup_supported, u->cgroup_path, 0, NULL, NULL); + if (r < 0) { + log_unit_error_errno(u, r, "Failed to join unit cgroup %s: %m", u->cgroup_path); + _exit(EXIT_CGROUP); } - - *ret = getpid_cached(); - return 0; } - *ret = pid; - return 1; + return 0; } static void unit_update_dependency_mask(Unit *u, UnitDependency d, Unit *other, UnitDependencyInfo di) { |