]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
process-util: introduce namespace_get_leader helper
authorNick Rosbrook <enr0n@ubuntu.com>
Fri, 8 Sep 2023 21:03:56 +0000 (17:03 -0400)
committerNick Rosbrook <enr0n@ubuntu.com>
Fri, 13 Oct 2023 19:13:11 +0000 (15:13 -0400)
For a given PID and namespace type, this helper function gives the PID
of the leader of the namespace containing the given PID. Use this in
systemd-coredump instead of using the existing get_mount_namespace_leader.

This helper will be used again in a later commit.

src/basic/process-util.c
src/basic/process-util.h
src/coredump/coredump.c

index 4928379bd757a8ffbc045f4d46a9aef2b8027f37..7cebbe1cc10e6b4ad2815c651f3390beed373f3a 100644 (file)
@@ -318,6 +318,33 @@ int container_get_leader(const char *machine, pid_t *pid) {
         return 0;
 }
 
+int namespace_get_leader(pid_t pid, NamespaceType type, pid_t *ret) {
+        int r;
+
+        assert(ret);
+
+        for (;;) {
+                pid_t ppid;
+
+                r = get_process_ppid(pid, &ppid);
+                if (r < 0)
+                        return r;
+
+                r = in_same_namespace(pid, ppid, type);
+                if (r < 0)
+                        return r;
+                if (r == 0) {
+                        /* If the parent and the child are not in the same
+                         * namespace, then the child is the leader we are
+                         * looking for. */
+                        *ret = pid;
+                        return 0;
+                }
+
+                pid = ppid;
+        }
+}
+
 int is_kernel_thread(pid_t pid) {
         _cleanup_free_ char *line = NULL;
         unsigned long long flags;
index 8f87fdc2ae74f578fe129046668d7a0e8f925f77..7acc102f40c0ced0492dd14d4999750b2d992b94 100644 (file)
@@ -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)                                  \
@@ -53,6 +54,8 @@ 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 {
index 3a82a7174285dc9c9ed8134d6a9c12ba32b55f18..e9b1f64e4f31669fa69ccc3fa729100f9f7cb3ad 100644 (file)
@@ -713,56 +713,6 @@ static int compose_open_fds(pid_t pid, char **ret) {
         return memstream_finalize(&m, ret, NULL);
 }
 
-static int get_process_ns(pid_t pid, const char *namespace, ino_t *ns) {
-        const char *p;
-        struct stat stbuf;
-        _cleanup_close_ int proc_ns_dir_fd = -EBADF;
-
-        p = procfs_file_alloca(pid, "ns");
-
-        proc_ns_dir_fd = open(p, O_DIRECTORY | O_CLOEXEC | O_RDONLY);
-        if (proc_ns_dir_fd < 0)
-                return -errno;
-
-        if (fstatat(proc_ns_dir_fd, namespace, &stbuf, /* flags */0) < 0)
-                return -errno;
-
-        *ns = stbuf.st_ino;
-        return 0;
-}
-
-static int get_mount_namespace_leader(pid_t pid, pid_t *ret) {
-        ino_t proc_mntns;
-        int r;
-
-        r = get_process_ns(pid, "mnt", &proc_mntns);
-        if (r < 0)
-                return r;
-
-        for (;;) {
-                ino_t parent_mntns;
-                pid_t ppid;
-
-                r = get_process_ppid(pid, &ppid);
-                if (r == -EADDRNOTAVAIL) /* Reached the top (i.e. typically PID 1, but could also be a process
-                                          * whose parent is not in our pidns) */
-                        return -ENOENT;
-                if (r < 0)
-                        return r;
-
-                r = get_process_ns(ppid, "mnt", &parent_mntns);
-                if (r < 0)
-                        return r;
-
-                if (proc_mntns != parent_mntns) {
-                        *ret = ppid;
-                        return 0;
-                }
-
-                pid = ppid;
-        }
-}
-
 /* Returns 1 if the parent was found.
  * Returns 0 if there is not a process we can call the pid's
  * container parent (the pid's process isn't 'containerized').
@@ -788,7 +738,7 @@ static int get_process_container_parent_cmdline(pid_t pid, char** cmdline) {
                 return 0;
         }
 
-        r = get_mount_namespace_leader(pid, &container_pid);
+        r = namespace_get_leader(pid, NAMESPACE_MOUNT, &container_pid);
         if (r < 0)
                 return r;