1 /* $NetBSD: t_pr.c,v 1.13 2019/07/16 17:29:17 martin Exp $ */
2
3 #include <sys/types.h>
4 #include <sys/mount.h>
5
6 #include <atf-c.h>
7 #include <err.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <stdlib.h>
14
15 #include <rump/rump.h>
16 #include <rump/rump_syscalls.h>
17
18 #include <miscfs/union/union.h>
19
20 #include "h_macros.h"
21
22 ATF_TC(multilayer);
ATF_TC_HEAD(multilayer,tc)23 ATF_TC_HEAD(multilayer, tc)
24 {
25 atf_tc_set_md_var(tc, "descr", "mount_union -b twice");
26 }
27
ATF_TC_BODY(multilayer,tc)28 ATF_TC_BODY(multilayer, tc)
29 {
30 struct union_args unionargs;
31
32 rump_init();
33
34 if (rump_sys_mkdir("/Tunion", 0777) == -1)
35 atf_tc_fail_errno("mkdir mp1");
36 if (rump_sys_mkdir("/Tunion2", 0777) == -1)
37 atf_tc_fail_errno("mkdir mp2");
38 if (rump_sys_mkdir("/Tunion2/A", 0777) == -1)
39 atf_tc_fail_errno("mkdir A");
40 if (rump_sys_mkdir("/Tunion2/B", 0777) == -1)
41 atf_tc_fail_errno("mkdir B");
42
43 unionargs.target = __UNCONST("/Tunion2/A");
44 unionargs.mntflags = UNMNT_BELOW;
45
46 if (rump_sys_mount(MOUNT_UNION, "/Tunion", 0,
47 &unionargs, sizeof(unionargs)) == -1)
48 atf_tc_fail_errno("union mount");
49
50 unionargs.target = __UNCONST("/Tunion2/B");
51 unionargs.mntflags = UNMNT_BELOW;
52
53 rump_sys_mount(MOUNT_UNION, "/Tunion", 0,&unionargs,sizeof(unionargs));
54 }
55
56 ATF_TC(multilayer2);
ATF_TC_HEAD(multilayer2,tc)57 ATF_TC_HEAD(multilayer2, tc)
58 {
59 atf_tc_set_md_var(tc, "descr", "mount_union twice then unmount");
60 }
61
ATF_TC_BODY(multilayer2,tc)62 ATF_TC_BODY(multilayer2, tc)
63 {
64 struct union_args unionargs;
65
66 atf_tc_expect_signal(-1, "PR kern/2423");
67
68 rump_init();
69
70 if (rump_sys_mkdir("/Tunion", 0777) == -1)
71 atf_tc_fail_errno("mkdir mp1");
72 if (rump_sys_mkdir("/Tunion2", 0777) == -1)
73 atf_tc_fail_errno("mkdir mp2");
74 if (rump_sys_mkdir("/Tunion2/A", 0777) == -1)
75 atf_tc_fail_errno("mkdir A");
76 if (rump_sys_mkdir("/Tunion2/B", 0777) == -1)
77 atf_tc_fail_errno("mkdir B");
78
79 unionargs.target = __UNCONST("/Tunion2/A");
80 unionargs.mntflags = UNMNT_ABOVE;
81
82 if (rump_sys_mount(MOUNT_UNION, "/Tunion", 0,
83 &unionargs, sizeof(unionargs)) == -1)
84 atf_tc_fail_errno("union mount");
85 if (rump_sys_mkdir("/Tunion2/A/A", 0777) == -1)
86 atf_tc_fail_errno("mkdir A/A");
87
88 unionargs.target = __UNCONST("/Tunion2/A/A");
89 unionargs.mntflags = UNMNT_ABOVE;
90
91 rump_sys_mount(MOUNT_UNION, "/Tunion", 0,&unionargs,sizeof(unionargs));
92
93 rump_sys_unmount("/Tunion/A", 0);
94 }
95
96 ATF_TC(cyclic);
ATF_TC_HEAD(cyclic,tc)97 ATF_TC_HEAD(cyclic, tc)
98 {
99 atf_tc_set_md_var(tc, "descr", "cyclic mount_union");
100 }
101
ATF_TC_BODY(cyclic,tc)102 ATF_TC_BODY(cyclic, tc)
103 {
104 struct union_args unionargs;
105
106 atf_tc_expect_signal(-1, "PR kern/3645");
107
108 rump_init();
109
110 if (rump_sys_mkdir("/Tunion", 0777) == -1)
111 atf_tc_fail_errno("mkdir mp1");
112 if (rump_sys_mkdir("/Tunion/A", 0777) == -1)
113 atf_tc_fail_errno("mkdir mp2");
114
115 unionargs.target = __UNCONST("/Tunion/A");
116 unionargs.mntflags = UNMNT_ABOVE;
117
118 if (rump_sys_mount(MOUNT_UNION, "/Tunion/A", 0,
119 &unionargs, sizeof(unionargs)) == -1)
120 atf_tc_fail_errno("union mount");
121
122 if (rump_sys_mkdir("/Tunion/A/A", 0777) == -1)
123 atf_tc_fail_errno("mkdir failed");
124 }
125
126 ATF_TC(cyclic2);
ATF_TC_HEAD(cyclic2,tc)127 ATF_TC_HEAD(cyclic2, tc)
128 {
129 atf_tc_set_md_var(tc, "descr", "cyclic mount_union");
130 }
131
ATF_TC_BODY(cyclic2,tc)132 ATF_TC_BODY(cyclic2, tc)
133 {
134 struct union_args unionargs;
135
136 atf_tc_expect_signal(-1, "PR kern/4597");
137
138 rump_init();
139
140 if (rump_sys_mkdir("/Tunion", 0777) == -1)
141 atf_tc_fail_errno("mkdir mp1");
142 if (rump_sys_mkdir("/Tunion/A", 0777) == -1)
143 atf_tc_fail_errno("mkdir mp2");
144 if (rump_sys_mkdir("/Tunion/B", 0777) == -1)
145 atf_tc_fail_errno("mkdir mp3");
146
147 unionargs.target = __UNCONST("/Tunion/A");
148 unionargs.mntflags = UNMNT_ABOVE;
149
150 if (rump_sys_mount(MOUNT_UNION, "/Tunion/B", 0,
151 &unionargs, sizeof(unionargs)) == -1)
152 atf_tc_fail_errno("union mount");
153
154 unionargs.target = __UNCONST("/Tunion/B");
155 unionargs.mntflags = UNMNT_ABOVE;
156
157 if (rump_sys_mount(MOUNT_UNION, "/Tunion/A", 0,
158 &unionargs, sizeof(unionargs)) == -1)
159 atf_tc_fail_errno("union mount2");
160
161 if (rump_sys_mkdir("/Tunion/A/A", 0777) == -1)
162 atf_tc_fail_errno("mkdir failed");
163 }
164
165 ATF_TC(devnull1);
ATF_TC_HEAD(devnull1,tc)166 ATF_TC_HEAD(devnull1, tc)
167 {
168 atf_tc_set_md_var(tc, "descr", "mount_union -b and "
169 "'echo x > /un/null'");
170 }
171
ATF_TC_BODY(devnull1,tc)172 ATF_TC_BODY(devnull1, tc)
173 {
174 struct union_args unionargs;
175 int fd, res;
176
177 rump_init();
178
179 if (rump_sys_mkdir("/mp", 0777) == -1)
180 atf_tc_fail_errno("mkdir mp");
181
182 unionargs.target = __UNCONST("/dev");
183 unionargs.mntflags = UNMNT_BELOW;
184
185 if (rump_sys_mount(MOUNT_UNION, "/mp", 0,
186 &unionargs, sizeof(unionargs)) == -1)
187 atf_tc_fail_errno("union mount");
188
189 fd = rump_sys_open("/mp/null", O_WRONLY | O_CREAT | O_TRUNC, 0600);
190
191 if (fd == -1)
192 atf_tc_fail_errno("open");
193
194 res = rump_sys_write(fd, &fd, sizeof(fd));
195 if (res != sizeof(fd))
196 atf_tc_fail("write");
197 }
198
199 ATF_TC(devnull2);
ATF_TC_HEAD(devnull2,tc)200 ATF_TC_HEAD(devnull2, tc)
201 {
202 atf_tc_set_md_var(tc, "descr", "mount_union -b and "
203 "'echo x >> /un/null'");
204 }
205
ATF_TC_BODY(devnull2,tc)206 ATF_TC_BODY(devnull2, tc)
207 {
208 struct union_args unionargs;
209 int fd, res;
210
211 rump_init();
212
213 if (rump_sys_mkdir("/mp", 0777) == -1)
214 atf_tc_fail_errno("mkdir mp");
215
216 unionargs.target = __UNCONST("/dev");
217 unionargs.mntflags = UNMNT_BELOW;
218
219 if (rump_sys_mount(MOUNT_UNION, "/mp", 0,
220 &unionargs, sizeof(unionargs)) == -1)
221 atf_tc_fail_errno("union mount");
222
223 fd = rump_sys_open("/mp/null", O_WRONLY | O_CREAT | O_APPEND, 0600);
224 if (fd == -1)
225 atf_tc_fail_errno("open");
226
227 res = rump_sys_write(fd, &fd, sizeof(fd));
228 if (res != sizeof(fd))
229 atf_tc_fail("write");
230 }
231
ATF_TP_ADD_TCS(tp)232 ATF_TP_ADD_TCS(tp)
233 {
234 ATF_TP_ADD_TC(tp, multilayer);
235 ATF_TP_ADD_TC(tp, multilayer2);
236 ATF_TP_ADD_TC(tp, cyclic);
237 ATF_TP_ADD_TC(tp, cyclic2);
238 ATF_TP_ADD_TC(tp, devnull1);
239 ATF_TP_ADD_TC(tp, devnull2);
240
241 return atf_no_error();
242 }
243