xref: /netbsd-src/tests/fs/union/t_pr.c (revision 653f037ebee6a2296283a02b6d16a3408afd1da0)
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