namespace-util: port namespace_get_leader() to PidRef

This commit is contained in:
Lennart Poettering
2025-01-10 14:22:49 +01:00
parent 47e45ea738
commit 0b8b13324e
4 changed files with 94 additions and 23 deletions
+23 -8
View File
@@ -351,31 +351,46 @@ int pidref_in_same_namespace(PidRef *pid1, PidRef *pid2, NamespaceType type) {
return fd_inode_same(ns1, ns2);
}
int namespace_get_leader(pid_t pid, NamespaceType type, pid_t *ret) {
int namespace_get_leader(PidRef *pidref, NamespaceType type, PidRef *ret) {
int r;
assert(pid >= 0);
/* Note: we don't bother with pidref_is_set()/pidref_is_remote() here, as the first call we do,
* pidref_get_ppid_as_pidref() calls those anyway */
assert(type >= 0 && type < _NAMESPACE_TYPE_MAX);
assert(ret);
for (;;) {
pid_t ppid;
_cleanup_(pidref_done) PidRef current = PIDREF_NULL;
PidRef *c = pidref;
r = pid_get_ppid(pid, &ppid);
for (;;) {
_cleanup_(pidref_done) PidRef parent = PIDREF_NULL;
r = pidref_get_ppid_as_pidref(c, &parent);
if (r < 0)
return r;
r = in_same_namespace(pid, ppid, type);
r = pidref_in_same_namespace(c, &parent, 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;
if (pidref_is_set(&current))
*ret = TAKE_PIDREF(current);
else {
r = pidref_copy(c, ret);
if (r < 0)
return r;
}
return 0;
}
pid = ppid;
pidref_done(&current);
current = TAKE_PIDREF(parent);
c = &current;
}
}
+1 -1
View File
@@ -62,7 +62,7 @@ static inline int in_same_namespace(pid_t pid1, pid_t pid2, NamespaceType type)
type);
}
int namespace_get_leader(pid_t pid, NamespaceType type, pid_t *ret);
int namespace_get_leader(PidRef *pidref, NamespaceType type, PidRef *ret);
int detach_mount_namespace(void);
int detach_mount_namespace_harder(uid_t target_uid, gid_t target_gid);