process-util: introduce new FORK_FREEZE flag for safe_fork()
Often we want to fork off a process that just hangs until we kill it, let's add a simple flag to create one of this type, and use it at various places.
This commit is contained in:
@@ -519,12 +519,10 @@ int userns_acquire_empty(void) {
|
||||
_cleanup_(pidref_done_sigkill_wait) PidRef pid = PIDREF_NULL;
|
||||
int r;
|
||||
|
||||
r = pidref_safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_USERNS, &pid);
|
||||
r = pidref_safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_USERNS|FORK_FREEZE, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
/* Child. We do nothing here, just freeze until somebody kills us. */
|
||||
freeze();
|
||||
assert(r > 0);
|
||||
|
||||
return pidref_namespace_open_by_type(&pid, NAMESPACE_USER);
|
||||
}
|
||||
@@ -541,12 +539,10 @@ int userns_acquire(const char *uid_map, const char *gid_map) {
|
||||
* and then kills the process again. This way we have a userns fd that is not bound to any
|
||||
* process. We can use that for file system mounts and similar. */
|
||||
|
||||
r = pidref_safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_USERNS, &pid);
|
||||
r = pidref_safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_USERNS|FORK_FREEZE, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
/* Child. We do nothing here, just freeze until somebody kills us. */
|
||||
freeze();
|
||||
assert(r > 0);
|
||||
|
||||
xsprintf(path, "/proc/" PID_FMT "/uid_map", pid.pid);
|
||||
r = write_string_file(path, uid_map, WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||
@@ -762,12 +758,10 @@ int netns_acquire(void) {
|
||||
/* Forks off a process in a new network namespace, acquires a network namespace fd, and then kills
|
||||
* the process again. This way we have a netns fd that is not bound to any process. */
|
||||
|
||||
r = pidref_safe_fork("(sd-mknetns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_NETNS, &pid);
|
||||
r = pidref_safe_fork("(sd-mknetns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_NETNS|FORK_FREEZE, &pid);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to fork process into new netns: %m");
|
||||
if (r == 0)
|
||||
/* Child. We do nothing here, just freeze until somebody kills us. */
|
||||
freeze();
|
||||
assert(r > 0);
|
||||
|
||||
return pidref_namespace_open_by_type(&pid, NAMESPACE_NET);
|
||||
}
|
||||
|
||||
@@ -1763,6 +1763,9 @@ int safe_fork_full(
|
||||
}
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, FORK_FREEZE))
|
||||
freeze();
|
||||
|
||||
if (ret_pid)
|
||||
*ret_pid = getpid_cached();
|
||||
|
||||
|
||||
@@ -192,6 +192,7 @@ typedef enum ForkFlags {
|
||||
FORK_NEW_USERNS = 1 << 19, /* Run child in its own user namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
|
||||
FORK_NEW_NETNS = 1 << 20, /* Run child in its own network namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
|
||||
FORK_NEW_PIDNS = 1 << 21, /* Run child in its own PID namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
|
||||
FORK_FREEZE = 1 << 22, /* Don't return in child, just call freeze() instead */
|
||||
} ForkFlags;
|
||||
|
||||
int safe_fork_full(
|
||||
|
||||
Reference in New Issue
Block a user