namespace-util: introduce network_namespace_is_init()

This commit is contained in:
Yu Watanabe
2026-07-18 05:29:59 +09:00
parent bb3fcd73ce
commit dfe19f1350
3 changed files with 40 additions and 0 deletions
+37
View File
@@ -3,6 +3,7 @@
#include <fcntl.h>
#include <linux/magic.h>
#include <linux/nsfs.h>
#include <linux/sockios.h>
#include <sched.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
@@ -410,12 +411,48 @@ int are_our_namespaces(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd,
return true;
}
int network_namespace_is_init(int socket_fd) {
struct stat a, b;
int r;
/* This works only when privileged. */
r = RET_NERRNO(stat(pid_namespace_path(1, NAMESPACE_NET), &a));
if (r == -ENOENT) {
/* If the /proc/ns/<type> API is not around in /proc/ then ns is off in the kernel and we are in the init ns */
r = proc_mounted();
if (r < 0)
return -ENOENT; /* If we can't determine if /proc/ is mounted propagate original error */
return r ? true : -ENOSYS;
}
if (r < 0)
return r;
if (socket_fd >= 0) {
_cleanup_close_ int netns = ioctl(socket_fd, SIOCGSKNS);
if (netns < 0)
return -errno;
if (fstat(netns, &b) < 0)
return -errno;
} else {
if (stat(pid_namespace_path(0, NAMESPACE_NET), &b) < 0)
return -errno;
}
return stat_inode_same(&a, &b);
}
int namespace_is_init(NamespaceType type) {
int r;
assert(type >= 0);
assert(type < _NAMESPACE_TYPE_MAX);
if (type == NAMESPACE_NET)
return network_namespace_is_init(/* socket_fd= */ -EBADF);
if (namespace_info[type].root_inode == 0)
return -EBADR; /* Cannot answer this question */
+1
View File
@@ -52,6 +52,7 @@ int fd_is_namespace(int fd, NamespaceType type);
int is_our_namespace(int fd, NamespaceType type);
int are_our_namespaces(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
int network_namespace_is_init(int socket_fd);
int namespace_is_init(NamespaceType type);
int pidref_in_same_namespace(PidRef *pid1, PidRef *pid2, NamespaceType type);