summaryrefslogtreecommitdiff
path: root/src/libnm-systemd-shared/src/basic/process-util.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnm-systemd-shared/src/basic/process-util.h')
-rw-r--r--src/libnm-systemd-shared/src/basic/process-util.h91
1 files changed, 70 insertions, 21 deletions
diff --git a/src/libnm-systemd-shared/src/basic/process-util.h b/src/libnm-systemd-shared/src/basic/process-util.h
index 5cf5c7c6ec..a75c44cfad 100644
--- a/src/libnm-systemd-shared/src/basic/process-util.h
+++ b/src/libnm-systemd-shared/src/basic/process-util.h
@@ -14,6 +14,7 @@
#include "alloc-util.h"
#include "format-util.h"
#include "macro.h"
+#include "namespace-util.h"
#include "time-util.h"
#define procfs_file_alloca(pid, field) \
@@ -38,21 +39,29 @@ typedef enum ProcessCmdlineFlags {
PROCESS_CMDLINE_QUOTE_POSIX = 1 << 3,
} ProcessCmdlineFlags;
-int get_process_comm(pid_t pid, char **ret);
-int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret);
-int get_process_cmdline_strv(pid_t pid, ProcessCmdlineFlags flags, char ***ret);
+int pid_get_comm(pid_t pid, char **ret);
+int pidref_get_comm(const PidRef *pid, char **ret);
+int pid_get_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret);
+int pidref_get_cmdline(const PidRef *pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret);
+int pid_get_cmdline_strv(pid_t pid, ProcessCmdlineFlags flags, char ***ret);
+int pidref_get_cmdline_strv(const PidRef *pid, ProcessCmdlineFlags flags, char ***ret);
int get_process_exe(pid_t pid, char **ret);
-int get_process_uid(pid_t pid, uid_t *ret);
+int pid_get_uid(pid_t pid, uid_t *ret);
+int pidref_get_uid(const PidRef *pid, uid_t *ret);
int get_process_gid(pid_t pid, gid_t *ret);
int get_process_capeff(pid_t pid, char **ret);
int get_process_cwd(pid_t pid, char **ret);
int get_process_root(pid_t pid, char **ret);
int get_process_environ(pid_t pid, char **ret);
int get_process_ppid(pid_t pid, pid_t *ret);
+int pid_get_start_time(pid_t pid, uint64_t *ret);
+int pidref_get_start_time(const PidRef* pid, uint64_t *ret);
int get_process_umask(pid_t pid, mode_t *ret);
int container_get_leader(const char *machine, pid_t *pid);
+int namespace_get_leader(pid_t pid, NamespaceType type, pid_t *ret);
+
int wait_for_terminate(pid_t pid, siginfo_t *status);
typedef enum WaitFlags {
@@ -74,13 +83,17 @@ void sigkill_nowaitp(pid_t *pid);
int kill_and_sigcont(pid_t pid, int sig);
-int is_kernel_thread(pid_t pid);
+int pid_is_kernel_thread(pid_t pid);
+int pidref_is_kernel_thread(const PidRef *pid);
int getenv_for_pid(pid_t pid, const char *field, char **_value);
-bool pid_is_alive(pid_t pid);
-bool pid_is_unwaited(pid_t pid);
+int pid_is_alive(pid_t pid);
+int pidref_is_alive(const PidRef *pidref);
+int pid_is_unwaited(pid_t pid);
+int pidref_is_unwaited(const PidRef *pidref);
int pid_is_my_child(pid_t pid);
+int pidref_is_my_child(const PidRef *pidref);
int pid_from_same_root_fs(pid_t pid);
bool is_main_thread(void);
@@ -141,24 +154,34 @@ void reset_cached_pid(void);
int must_be_root(void);
+pid_t clone_with_nested_stack(int (*fn)(void *), int flags, void *userdata);
+
+/* 💣 Note that FORK_NEW_USERNS, FORK_NEW_MOUNTNS, or FORK_NEW_NETNS should not be called in threaded
+ * programs, because they cause us to use raw_clone() which does not synchronize the glibc malloc() locks,
+ * and thus will cause deadlocks if the parent uses threads and the child does memory allocations. Hence: if
+ * the parent is threaded these flags may not be used. These flags cannot be used if the parent uses threads
+ * or the child uses malloc(). 💣 */
typedef enum ForkFlags {
FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */
FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */
- FORK_DEATHSIG = 1 << 2, /* Set PR_DEATHSIG in the child to SIGTERM */
+ FORK_DEATHSIG_SIGTERM = 1 << 2, /* Set PR_DEATHSIG in the child to SIGTERM */
FORK_DEATHSIG_SIGINT = 1 << 3, /* Set PR_DEATHSIG in the child to SIGINT */
- FORK_REARRANGE_STDIO = 1 << 4, /* Connect 0,1,2 to specified fds or /dev/null */
- FORK_REOPEN_LOG = 1 << 5, /* Reopen log connection */
- FORK_LOG = 1 << 6, /* Log above LOG_DEBUG log level about failures */
- FORK_WAIT = 1 << 7, /* Wait until child exited */
- FORK_NEW_MOUNTNS = 1 << 8, /* Run child in its own mount namespace */
- FORK_MOUNTNS_SLAVE = 1 << 9, /* Make child's mount namespace MS_SLAVE */
- FORK_PRIVATE_TMP = 1 << 10, /* Mount new /tmp/ in the child (combine with FORK_NEW_MOUNTNS!) */
- FORK_RLIMIT_NOFILE_SAFE = 1 << 11, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
- FORK_STDOUT_TO_STDERR = 1 << 12, /* Make stdout a copy of stderr */
- FORK_FLUSH_STDIO = 1 << 13, /* fflush() stdout (and stderr) before forking */
- FORK_NEW_USERNS = 1 << 14, /* Run child in its own user namespace */
- FORK_CLOEXEC_OFF = 1 << 15, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */
- FORK_KEEP_NOTIFY_SOCKET = 1 << 16, /* Unless this specified, $NOTIFY_SOCKET will be unset. */
+ FORK_DEATHSIG_SIGKILL = 1 << 4, /* Set PR_DEATHSIG in the child to SIGKILL */
+ FORK_REARRANGE_STDIO = 1 << 5, /* Connect 0,1,2 to specified fds or /dev/null */
+ FORK_REOPEN_LOG = 1 << 6, /* Reopen log connection */
+ FORK_LOG = 1 << 7, /* Log above LOG_DEBUG log level about failures */
+ FORK_WAIT = 1 << 8, /* Wait until child exited */
+ FORK_NEW_MOUNTNS = 1 << 9, /* Run child in its own mount namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
+ FORK_MOUNTNS_SLAVE = 1 << 10, /* Make child's mount namespace MS_SLAVE */
+ FORK_PRIVATE_TMP = 1 << 11, /* Mount new /tmp/ in the child (combine with FORK_NEW_MOUNTNS!) */
+ FORK_RLIMIT_NOFILE_SAFE = 1 << 12, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
+ FORK_STDOUT_TO_STDERR = 1 << 13, /* Make stdout a copy of stderr */
+ FORK_FLUSH_STDIO = 1 << 14, /* fflush() stdout (and stderr) before forking */
+ FORK_NEW_USERNS = 1 << 15, /* Run child in its own user namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
+ FORK_CLOEXEC_OFF = 1 << 16, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */
+ FORK_KEEP_NOTIFY_SOCKET = 1 << 17, /* Unless this specified, $NOTIFY_SOCKET will be unset. */
+ FORK_DETACH = 1 << 18, /* Double fork if needed to ensure PID1/subreaper is parent */
+ FORK_NEW_NETNS = 1 << 19, /* Run child in its own network namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
} ForkFlags;
int safe_fork_full(
@@ -173,6 +196,18 @@ static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) {
return safe_fork_full(name, NULL, NULL, 0, flags, ret_pid);
}
+int pidref_safe_fork_full(
+ const char *name,
+ const int stdio_fds[3],
+ const int except_fds[],
+ size_t n_except_fds,
+ ForkFlags flags,
+ PidRef *ret_pid);
+
+static inline int pidref_safe_fork(const char *name, ForkFlags flags, PidRef *ret_pid) {
+ return pidref_safe_fork_full(name, NULL, NULL, 0, flags, ret_pid);
+}
+
int namespace_fork(const char *outer_name, const char *inner_name, const int except_fds[], size_t n_except_fds, ForkFlags flags, int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd, pid_t *ret_pid);
int set_oom_score_adjust(int value);
@@ -201,3 +236,17 @@ int setpriority_closest(int priority);
_noreturn_ void freeze(void);
int get_process_threads(pid_t pid);
+
+int is_reaper_process(void);
+int make_reaper_process(bool b);
+
+int posix_spawn_wrapper(
+ const char *path,
+ char * const *argv,
+ char * const *envp,
+ const char *cgroup,
+ PidRef *ret_pidref);
+
+int proc_dir_open(DIR **ret);
+int proc_dir_read(DIR *d, pid_t *ret);
+int proc_dir_read_pidref(DIR *d, PidRef *ret);