1 // SPDX-License-Identifier: GPL-2.0-or-later
7 #include <linux/types.h>
11 #include "../../tools/testing/selftests/pidfd/pidfd.h"
12 #include "samples-vfs.h"
14 static int __statmount(__u64 mnt_id, __u64 mnt_ns_id, __u64 mask,
15 struct statmount *stmnt, size_t bufsize,
18 struct mnt_id_req req = {
19 .size = MNT_ID_REQ_SIZE_VER1,
22 .mnt_ns_id = mnt_ns_id,
25 return syscall(__NR_statmount, &req, stmnt, bufsize, flags);
28 static struct statmount *sys_statmount(__u64 mnt_id, __u64 mnt_ns_id,
29 __u64 mask, unsigned int flags)
31 size_t bufsize = 1 << 15;
32 struct statmount *stmnt = NULL, *tmp = NULL;
36 tmp = realloc(stmnt, bufsize);
41 ret = __statmount(mnt_id, mnt_ns_id, mask, stmnt, bufsize, flags);
45 if (errno != EOVERFLOW)
49 if (bufsize >= UINT_MAX / 2)
58 static ssize_t sys_listmount(__u64 mnt_id, __u64 last_mnt_id, __u64 mnt_ns_id,
59 __u64 list[], size_t num, unsigned int flags)
61 struct mnt_id_req req = {
62 .size = MNT_ID_REQ_SIZE_VER1,
65 .mnt_ns_id = mnt_ns_id,
68 return syscall(__NR_listmount, &req, list, num, flags);
71 int main(int argc, char *argv[])
73 #define LISTMNT_BUFFER 10
74 __u64 list[LISTMNT_BUFFER], last_mnt_id = 0;
75 int ret, pidfd, fd_mntns;
76 struct mnt_ns_info info = {};
78 pidfd = sys_pidfd_open(getpid(), 0);
80 die_errno("pidfd_open failed");
82 fd_mntns = ioctl(pidfd, PIDFD_GET_MNT_NAMESPACE, 0);
84 die_errno("ioctl(PIDFD_GET_MNT_NAMESPACE) failed");
86 ret = ioctl(fd_mntns, NS_MNT_GET_INFO, &info);
88 die_errno("ioctl(NS_GET_MNTNS_ID) failed");
90 printf("Listing %u mounts for mount namespace %" PRIu64 "\n",
91 info.nr_mounts, (uint64_t)info.mnt_ns_id);
95 nr_mounts = sys_listmount(LSMT_ROOT, last_mnt_id,
96 info.mnt_ns_id, list, LISTMNT_BUFFER,
101 printf("Finished listing %u mounts for mount namespace %" PRIu64 "\n\n",
102 info.nr_mounts, (uint64_t)info.mnt_ns_id);
103 fd_mntns_next = ioctl(fd_mntns, NS_MNT_GET_NEXT, &info);
104 if (fd_mntns_next < 0) {
105 if (errno == ENOENT) {
106 printf("Finished listing all mount namespaces\n");
109 die_errno("ioctl(NS_MNT_GET_NEXT) failed");
112 fd_mntns = fd_mntns_next;
114 printf("Listing %u mounts for mount namespace %" PRIu64 "\n",
115 info.nr_mounts, (uint64_t)info.mnt_ns_id);
119 for (size_t cur = 0; cur < nr_mounts; cur++) {
120 struct statmount *stmnt;
122 last_mnt_id = list[cur];
124 stmnt = sys_statmount(last_mnt_id, info.mnt_ns_id,
126 STATMOUNT_MNT_BASIC |
128 STATMOUNT_MNT_POINT |
129 STATMOUNT_MNT_NS_ID |
131 STATMOUNT_FS_TYPE, 0);
133 printf("Failed to statmount(%" PRIu64 ") in mount namespace(%" PRIu64 ")\n",
134 (uint64_t)last_mnt_id, (uint64_t)info.mnt_ns_id);
138 printf("mnt_id:\t\t%" PRIu64 "\nmnt_parent_id:\t%" PRIu64 "\nfs_type:\t%s\nmnt_root:\t%s\nmnt_point:\t%s\nmnt_opts:\t%s\n\n",
139 (uint64_t)stmnt->mnt_id,
140 (uint64_t)stmnt->mnt_parent_id,
141 stmnt->str + stmnt->fs_type,
142 stmnt->str + stmnt->mnt_root,
143 stmnt->str + stmnt->mnt_point,
144 stmnt->str + stmnt->mnt_opts);