]> Git Repo - J-linux.git/blob - tools/testing/selftests/bpf/prog_tests/test_bpffs.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / testing / selftests / bpf / prog_tests / test_bpffs.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2020 Facebook */
3 #define _GNU_SOURCE
4 #include <stdio.h>
5 #include <sched.h>
6 #include <sys/mount.h>
7 #include <sys/stat.h>
8 #include <sys/types.h>
9 #include <test_progs.h>
10
11 /* TDIR must be in a location we can create a directory in. */
12 #define TDIR "/tmp/test_bpffs_testdir"
13
14 static int read_iter(char *file)
15 {
16         /* 1024 should be enough to get contiguous 4 "iter" letters at some point */
17         char buf[1024];
18         int fd, len;
19
20         fd = open(file, 0);
21         if (fd < 0)
22                 return -1;
23         while ((len = read(fd, buf, sizeof(buf))) > 0) {
24                 buf[sizeof(buf) - 1] = '\0';
25                 if (strstr(buf, "iter")) {
26                         close(fd);
27                         return 0;
28                 }
29         }
30         close(fd);
31         return -1;
32 }
33
34 static int fn(void)
35 {
36         struct stat a, b, c;
37         int err, map;
38
39         err = unshare(CLONE_NEWNS);
40         if (!ASSERT_OK(err, "unshare"))
41                 goto out;
42
43         err = mount("", "/", "", MS_REC | MS_PRIVATE, NULL);
44         if (!ASSERT_OK(err, "mount /"))
45                 goto out;
46
47         err =  mkdir(TDIR, 0777);
48         /* If the directory already exists we can carry on. It may be left over
49          * from a previous run.
50          */
51         if ((err && errno != EEXIST) && !ASSERT_OK(err, "mkdir " TDIR))
52                 goto out;
53
54         err = mount("none", TDIR, "tmpfs", 0, NULL);
55         if (!ASSERT_OK(err, "mount tmpfs"))
56                 goto out;
57
58         err = mkdir(TDIR "/fs1", 0777);
59         if (!ASSERT_OK(err, "mkdir " TDIR "/fs1"))
60                 goto out;
61         err = mkdir(TDIR "/fs2", 0777);
62         if (!ASSERT_OK(err, "mkdir " TDIR "/fs2"))
63                 goto out;
64
65         err = mount("bpf", TDIR "/fs1", "bpf", 0, NULL);
66         if (!ASSERT_OK(err, "mount bpffs " TDIR "/fs1"))
67                 goto out;
68         err = mount("bpf", TDIR "/fs2", "bpf", 0, NULL);
69         if (!ASSERT_OK(err, "mount bpffs " TDIR "/fs2"))
70                 goto out;
71
72         err = read_iter(TDIR "/fs1/maps.debug");
73         if (!ASSERT_OK(err, "reading " TDIR "/fs1/maps.debug"))
74                 goto out;
75         err = read_iter(TDIR "/fs2/progs.debug");
76         if (!ASSERT_OK(err, "reading " TDIR "/fs2/progs.debug"))
77                 goto out;
78
79         err = mkdir(TDIR "/fs1/a", 0777);
80         if (!ASSERT_OK(err, "creating " TDIR "/fs1/a"))
81                 goto out;
82         err = mkdir(TDIR "/fs1/a/1", 0777);
83         if (!ASSERT_OK(err, "creating " TDIR "/fs1/a/1"))
84                 goto out;
85         err = mkdir(TDIR "/fs1/b", 0777);
86         if (!ASSERT_OK(err, "creating " TDIR "/fs1/b"))
87                 goto out;
88
89         map = bpf_map_create(BPF_MAP_TYPE_ARRAY, NULL, 4, 4, 1, NULL);
90         if (!ASSERT_GT(map, 0, "create_map(ARRAY)"))
91                 goto out;
92         err = bpf_obj_pin(map, TDIR "/fs1/c");
93         if (!ASSERT_OK(err, "pin map"))
94                 goto out;
95         close(map);
96
97         /* Check that RENAME_EXCHANGE works for directories. */
98         err = stat(TDIR "/fs1/a", &a);
99         if (!ASSERT_OK(err, "stat(" TDIR "/fs1/a)"))
100                 goto out;
101         err = renameat2(0, TDIR "/fs1/a", 0, TDIR "/fs1/b", RENAME_EXCHANGE);
102         if (!ASSERT_OK(err, "renameat2(/fs1/a, /fs1/b, RENAME_EXCHANGE)"))
103                 goto out;
104         err = stat(TDIR "/fs1/b", &b);
105         if (!ASSERT_OK(err, "stat(" TDIR "/fs1/b)"))
106                 goto out;
107         if (!ASSERT_EQ(a.st_ino, b.st_ino, "b should have a's inode"))
108                 goto out;
109         err = access(TDIR "/fs1/b/1", F_OK);
110         if (!ASSERT_OK(err, "access(" TDIR "/fs1/b/1)"))
111                 goto out;
112
113         /* Check that RENAME_EXCHANGE works for mixed file types. */
114         err = stat(TDIR "/fs1/c", &c);
115         if (!ASSERT_OK(err, "stat(" TDIR "/fs1/map)"))
116                 goto out;
117         err = renameat2(0, TDIR "/fs1/c", 0, TDIR "/fs1/b", RENAME_EXCHANGE);
118         if (!ASSERT_OK(err, "renameat2(/fs1/c, /fs1/b, RENAME_EXCHANGE)"))
119                 goto out;
120         err = stat(TDIR "/fs1/b", &b);
121         if (!ASSERT_OK(err, "stat(" TDIR "/fs1/b)"))
122                 goto out;
123         if (!ASSERT_EQ(c.st_ino, b.st_ino, "b should have c's inode"))
124                 goto out;
125         err = access(TDIR "/fs1/c/1", F_OK);
126         if (!ASSERT_OK(err, "access(" TDIR "/fs1/c/1)"))
127                 goto out;
128
129         /* Check that RENAME_NOREPLACE works. */
130         err = renameat2(0, TDIR "/fs1/b", 0, TDIR "/fs1/a", RENAME_NOREPLACE);
131         if (!ASSERT_ERR(err, "renameat2(RENAME_NOREPLACE)")) {
132                 err = -EINVAL;
133                 goto out;
134         }
135         err = access(TDIR "/fs1/b", F_OK);
136         if (!ASSERT_OK(err, "access(" TDIR "/fs1/b)"))
137                 goto out;
138
139 out:
140         umount(TDIR "/fs1");
141         umount(TDIR "/fs2");
142         rmdir(TDIR "/fs1");
143         rmdir(TDIR "/fs2");
144         umount(TDIR);
145         rmdir(TDIR);
146         exit(err);
147 }
148
149 void test_test_bpffs(void)
150 {
151         int err, duration = 0, status = 0;
152         pid_t pid;
153
154         pid = fork();
155         if (CHECK(pid == -1, "clone", "clone failed %d", errno))
156                 return;
157         if (pid == 0)
158                 fn();
159         err = waitpid(pid, &status, 0);
160         if (CHECK(err == -1 && errno != ECHILD, "waitpid", "failed %d", errno))
161                 return;
162         if (CHECK(WEXITSTATUS(status), "bpffs test ", "failed %d", WEXITSTATUS(status)))
163                 return;
164 }
This page took 0.037188 seconds and 4 git commands to generate.