pidref: record pidfd inode number in PidRef struct
Besides internal comparisons, the inode number of pidfds might be interesting directly to users, too. In the future this field should also be exposed, so that it can serve as a unique identifier of a process (but only for display, as there's no method to map this back to a pid or pidfd).
This commit is contained in:
+35
-13
@@ -32,9 +32,38 @@ static int pidfd_inode_ids_supported(void) {
|
||||
return (cached = fd_is_fs_type(fd, PID_FS_MAGIC));
|
||||
}
|
||||
|
||||
bool pidref_equal(const PidRef *a, const PidRef *b) {
|
||||
int pidref_acquire_pidfd_id(PidRef *pidref) {
|
||||
int r;
|
||||
|
||||
assert(pidref);
|
||||
|
||||
if (!pidref_is_set(pidref))
|
||||
return -ESRCH;
|
||||
|
||||
if (pidref->fd < 0)
|
||||
return -ENOMEDIUM;
|
||||
|
||||
if (pidref->fd_id > 0)
|
||||
return 0;
|
||||
|
||||
r = pidfd_inode_ids_supported();
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
struct stat st;
|
||||
|
||||
if (fstat(pidref->fd, &st) < 0)
|
||||
return log_debug_errno(errno, "Failed to get inode number of pidfd for pid " PID_FMT ": %m",
|
||||
pidref->pid);
|
||||
|
||||
pidref->fd_id = (uint64_t) st.st_ino;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool pidref_equal(PidRef *a, PidRef *b) {
|
||||
|
||||
if (pidref_is_set(a)) {
|
||||
if (!pidref_is_set(b))
|
||||
return false;
|
||||
@@ -42,20 +71,13 @@ bool pidref_equal(const PidRef *a, const PidRef *b) {
|
||||
if (a->pid != b->pid)
|
||||
return false;
|
||||
|
||||
if (a->fd < 0 || b->fd < 0)
|
||||
/* Try to compare pidfds using their inode numbers. This way we can ensure that we don't
|
||||
* spuriously consider two PidRefs equal if the pid has been reused once. Note that we
|
||||
* ignore all errors here, not only EOPNOTSUPP, as fstat() might fail due to many reasons. */
|
||||
if (pidref_acquire_pidfd_id(a) < 0 || pidref_acquire_pidfd_id(b) < 0)
|
||||
return true;
|
||||
|
||||
/* pidfds live in their own pidfs and each process comes with a unique inode number since
|
||||
* kernel 6.9. */
|
||||
|
||||
if (pidfd_inode_ids_supported() <= 0)
|
||||
return true;
|
||||
|
||||
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 a->fd_id == b->fd_id;
|
||||
}
|
||||
|
||||
return !pidref_is_set(b);
|
||||
|
||||
Reference in New Issue
Block a user