]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pidref: use fd_inode_same to compare pidfds 31713/head
authorMike Yuan <me@yhndnzj.com>
Mon, 11 Mar 2024 08:41:51 +0000 (16:41 +0800)
committerMike Yuan <me@yhndnzj.com>
Mon, 11 Mar 2024 14:57:50 +0000 (22:57 +0800)
src/basic/pidref.c
src/basic/pidref.h

index abe372be2edcaae22f9e0ff628fdbe635e164e9d..5f1042fae815210d78ffd8f56ac90b43f96192c3 100644 (file)
@@ -8,6 +8,33 @@
 #include "pidref.h"
 #include "process-util.h"
 #include "signal-util.h"
+#include "stat-util.h"
+
+bool pidref_equal(const PidRef *a, const PidRef *b) {
+        int r;
+
+        if (pidref_is_set(a)) {
+                if (!pidref_is_set(b))
+                        return false;
+
+                if (a->pid != b->pid)
+                        return false;
+
+                if (a->fd < 0 || b->fd < 0)
+                        return true;
+
+                /* pidfds live in their own pidfs and each process comes with a unique inode number since
+                 * kernel 6.8. We can safely do this on older kernels too though, as previously anonymous
+                 * inode was used and inode number was the same for all pidfds. */
+                r = fd_inode_same(a->fd, b->fd);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to check whether pidfds for pid " PID_FMT " are equal, assuming yes: %m",
+                                        a->pid);
+                return r != 0;
+        }
+
+        return !pidref_is_set(b);
+}
 
 int pidref_set_pid(PidRef *pidref, pid_t pid) {
         int fd;
index c440c8b0e034599b4ab981af30af578562e2e823..9920ebb9b3bca65e5edc2c4ab73e3114c3b86464 100644 (file)
@@ -19,17 +19,7 @@ static inline bool pidref_is_set(const PidRef *pidref) {
         return pidref && pidref->pid > 0;
 }
 
-static inline bool pidref_equal(const PidRef *a, const PidRef *b) {
-
-        if (pidref_is_set(a)) {
-                if (!pidref_is_set(b))
-                        return false;
-
-                return a->pid == b->pid;
-        }
-
-        return !pidref_is_set(b);
-}
+bool pidref_equal(const PidRef *a, const PidRef *b);
 
 /* This turns a pid_t into a PidRef structure, and acquires a pidfd for it, if possible. (As opposed to
  * PIDREF_MAKE_FROM_PID() above, which does not acquire a pidfd.) */