1 // SPDX-License-Identifier: GPL-2.0 2 #define _GNU_SOURCE 3 #include <errno.h> 4 #include <fcntl.h> 5 #include <limits.h> 6 #include <sched.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <linux/nsfs.h> 11 #include <sys/mount.h> 12 #include <sys/stat.h> 13 #include <sys/types.h> 14 #include <sys/wait.h> 15 #include <unistd.h> 16 #include "../kselftest_harness.h" 17 #include "../filesystems/utils.h" 18 19 #ifndef FD_NSFS_ROOT 20 #define FD_NSFS_ROOT -10003 /* Root of the nsfs filesystem */ 21 #endif 22 23 /* 24 * Test that initial namespaces can be reopened via file handle. 25 * Initial namespaces should have active ref count of 1 from boot. 26 */ 27 TEST(init_ns_always_active) 28 { 29 struct file_handle *handle; 30 int mount_id; 31 int ret; 32 int fd1, fd2; 33 struct stat st1, st2; 34 35 handle = malloc(sizeof(*handle) + MAX_HANDLE_SZ); 36 ASSERT_NE(handle, NULL); 37 38 /* Open initial network namespace */ 39 fd1 = open("/proc/1/ns/net", O_RDONLY); 40 ASSERT_GE(fd1, 0); 41 42 /* Get file handle for initial namespace */ 43 handle->handle_bytes = MAX_HANDLE_SZ; 44 ret = name_to_handle_at(fd1, "", handle, &mount_id, AT_EMPTY_PATH); 45 if (ret < 0 && errno == EOPNOTSUPP) { 46 SKIP(free(handle); close(fd1); 47 return, "nsfs doesn't support file handles"); 48 } 49 ASSERT_EQ(ret, 0); 50 51 /* Close the namespace fd */ 52 close(fd1); 53 54 /* Try to reopen via file handle - should succeed since init ns is always active */ 55 fd2 = open_by_handle_at(FD_NSFS_ROOT, handle, O_RDONLY); 56 if (fd2 < 0 && (errno == EINVAL || errno == EOPNOTSUPP)) { 57 SKIP(free(handle); 58 return, "open_by_handle_at with FD_NSFS_ROOT not supported"); 59 } 60 ASSERT_GE(fd2, 0); 61 62 /* Verify we opened the same namespace */ 63 fd1 = open("/proc/1/ns/net", O_RDONLY); 64 ASSERT_GE(fd1, 0); 65 ASSERT_EQ(fstat(fd1, &st1), 0); 66 ASSERT_EQ(fstat(fd2, &st2), 0); 67 ASSERT_EQ(st1.st_ino, st2.st_ino); 68 69 close(fd1); 70 close(fd2); 71 free(handle); 72 } 73 74 TEST_HARNESS_MAIN 75