Path: blob/master/tools/testing/selftests/filesystems/nsfs/iterate_mntns.c
26302 views
// SPDX-License-Identifier: GPL-2.0-or-later1// Copyright (c) 2024 Christian Brauner <[email protected]>23#define _GNU_SOURCE4#include <fcntl.h>5#include <linux/auto_dev-ioctl.h>6#include <linux/errno.h>7#include <sched.h>8#include <stdio.h>9#include <string.h>10#include <sys/stat.h>11#include <sys/mount.h>12#include <unistd.h>1314#include "../../kselftest_harness.h"1516#define MNT_NS_COUNT 1117#define MNT_NS_LAST_INDEX 101819struct mnt_ns_info {20__u32 size;21__u32 nr_mounts;22__u64 mnt_ns_id;23};2425#define MNT_NS_INFO_SIZE_VER0 16 /* size of first published struct */2627/* Get information about namespace. */28#define NS_MNT_GET_INFO _IOR(0xb7, 10, struct mnt_ns_info)29/* Get next namespace. */30#define NS_MNT_GET_NEXT _IOR(0xb7, 11, struct mnt_ns_info)31/* Get previous namespace. */32#define NS_MNT_GET_PREV _IOR(0xb7, 12, struct mnt_ns_info)3334FIXTURE(iterate_mount_namespaces) {35int fd_mnt_ns[MNT_NS_COUNT];36__u64 mnt_ns_id[MNT_NS_COUNT];37};3839FIXTURE_SETUP(iterate_mount_namespaces)40{41for (int i = 0; i < MNT_NS_COUNT; i++)42self->fd_mnt_ns[i] = -EBADF;4344/*45* Creating a new user namespace let's us guarantee that we only see46* mount namespaces that we did actually create.47*/48ASSERT_EQ(unshare(CLONE_NEWUSER), 0);4950for (int i = 0; i < MNT_NS_COUNT; i++) {51struct mnt_ns_info info = {};5253ASSERT_EQ(unshare(CLONE_NEWNS), 0);54self->fd_mnt_ns[i] = open("/proc/self/ns/mnt", O_RDONLY | O_CLOEXEC);55ASSERT_GE(self->fd_mnt_ns[i], 0);56ASSERT_EQ(ioctl(self->fd_mnt_ns[i], NS_MNT_GET_INFO, &info), 0);57self->mnt_ns_id[i] = info.mnt_ns_id;58}59}6061FIXTURE_TEARDOWN(iterate_mount_namespaces)62{63for (int i = 0; i < MNT_NS_COUNT; i++) {64if (self->fd_mnt_ns[i] < 0)65continue;66ASSERT_EQ(close(self->fd_mnt_ns[i]), 0);67}68}6970TEST_F(iterate_mount_namespaces, iterate_all_forward)71{72int fd_mnt_ns_cur, count = 0;7374fd_mnt_ns_cur = fcntl(self->fd_mnt_ns[0], F_DUPFD_CLOEXEC);75ASSERT_GE(fd_mnt_ns_cur, 0);7677for (;; count++) {78struct mnt_ns_info info = {};79int fd_mnt_ns_next;8081fd_mnt_ns_next = ioctl(fd_mnt_ns_cur, NS_MNT_GET_NEXT, &info);82if (fd_mnt_ns_next < 0 && errno == ENOENT)83break;84ASSERT_GE(fd_mnt_ns_next, 0);85ASSERT_EQ(close(fd_mnt_ns_cur), 0);86fd_mnt_ns_cur = fd_mnt_ns_next;87}88ASSERT_EQ(count, MNT_NS_LAST_INDEX);89}9091TEST_F(iterate_mount_namespaces, iterate_all_backwards)92{93int fd_mnt_ns_cur, count = 0;9495fd_mnt_ns_cur = fcntl(self->fd_mnt_ns[MNT_NS_LAST_INDEX], F_DUPFD_CLOEXEC);96ASSERT_GE(fd_mnt_ns_cur, 0);9798for (;; count++) {99struct mnt_ns_info info = {};100int fd_mnt_ns_prev;101102fd_mnt_ns_prev = ioctl(fd_mnt_ns_cur, NS_MNT_GET_PREV, &info);103if (fd_mnt_ns_prev < 0 && errno == ENOENT)104break;105ASSERT_GE(fd_mnt_ns_prev, 0);106ASSERT_EQ(close(fd_mnt_ns_cur), 0);107fd_mnt_ns_cur = fd_mnt_ns_prev;108}109ASSERT_EQ(count, MNT_NS_LAST_INDEX);110}111112TEST_F(iterate_mount_namespaces, iterate_forward)113{114int fd_mnt_ns_cur;115116ASSERT_EQ(setns(self->fd_mnt_ns[0], CLONE_NEWNS), 0);117118fd_mnt_ns_cur = self->fd_mnt_ns[0];119for (int i = 1; i < MNT_NS_COUNT; i++) {120struct mnt_ns_info info = {};121int fd_mnt_ns_next;122123fd_mnt_ns_next = ioctl(fd_mnt_ns_cur, NS_MNT_GET_NEXT, &info);124ASSERT_GE(fd_mnt_ns_next, 0);125ASSERT_EQ(close(fd_mnt_ns_cur), 0);126fd_mnt_ns_cur = fd_mnt_ns_next;127ASSERT_EQ(info.mnt_ns_id, self->mnt_ns_id[i]);128}129}130131TEST_F(iterate_mount_namespaces, iterate_backward)132{133int fd_mnt_ns_cur;134135ASSERT_EQ(setns(self->fd_mnt_ns[MNT_NS_LAST_INDEX], CLONE_NEWNS), 0);136137fd_mnt_ns_cur = self->fd_mnt_ns[MNT_NS_LAST_INDEX];138for (int i = MNT_NS_LAST_INDEX - 1; i >= 0; i--) {139struct mnt_ns_info info = {};140int fd_mnt_ns_prev;141142fd_mnt_ns_prev = ioctl(fd_mnt_ns_cur, NS_MNT_GET_PREV, &info);143ASSERT_GE(fd_mnt_ns_prev, 0);144ASSERT_EQ(close(fd_mnt_ns_cur), 0);145fd_mnt_ns_cur = fd_mnt_ns_prev;146ASSERT_EQ(info.mnt_ns_id, self->mnt_ns_id[i]);147}148}149150TEST_F(iterate_mount_namespaces, nfs_valid_ioctl)151{152ASSERT_NE(ioctl(self->fd_mnt_ns[0], AUTOFS_DEV_IOCTL_OPENMOUNT, NULL), 0);153ASSERT_EQ(errno, ENOTTY);154155ASSERT_NE(ioctl(self->fd_mnt_ns[0], AUTOFS_DEV_IOCTL_CLOSEMOUNT, NULL), 0);156ASSERT_EQ(errno, ENOTTY);157158ASSERT_NE(ioctl(self->fd_mnt_ns[0], AUTOFS_DEV_IOCTL_READY, NULL), 0);159ASSERT_EQ(errno, ENOTTY);160}161162TEST_HARNESS_MAIN163164165