xref: /netbsd-src/tests/fs/union/t_pr.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: t_pr.c,v 1.7 2010/07/03 13:37:22 pooka 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);
23 ATF_TC_HEAD(multilayer, tc)
24 {
25 	atf_tc_set_md_var(tc, "descr", "mount_union -b twice");
26 }
27 
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 	/* atf_tc_expect_signal(-1, "PR kern/23986"); */
54 	rump_sys_mount(MOUNT_UNION, "/Tunion", 0,&unionargs,sizeof(unionargs));
55 }
56 
57 ATF_TC(devnull1);
58 ATF_TC_HEAD(devnull1, tc)
59 {
60 	atf_tc_set_md_var(tc, "descr", "mount_union -b and "
61 	    "'echo x > /un/null'");
62 }
63 
64 ATF_TC_BODY(devnull1, tc)
65 {
66 	struct union_args unionargs;
67 	int fd;
68 
69 	rump_init();
70 
71 	if (rump_sys_mkdir("/mp", 0777) == -1)
72 		atf_tc_fail_errno("mkdir mp");
73 
74 	unionargs.target = __UNCONST("/dev");
75 	unionargs.mntflags = UNMNT_BELOW;
76 
77 	if (rump_sys_mount(MOUNT_UNION, "/mp", 0,
78 	    &unionargs, sizeof(unionargs)) == -1)
79 		atf_tc_fail_errno("union mount");
80 
81 	fd = rump_sys_open("/mp/null", O_WRONLY | O_CREAT | O_TRUNC);
82 
83 	atf_tc_expect_fail("PR kern/43560");
84 	if (fd == -1 && errno == EROFS) {
85 		atf_tc_fail("open returned EROFS");
86 	} else if (fd == -1) {
87 		atf_tc_expect_pass();
88 		atf_tc_fail_errno("open fail");
89 	}
90 
91 }
92 
93 ATF_TC(devnull2);
94 ATF_TC_HEAD(devnull2, tc)
95 {
96 	atf_tc_set_md_var(tc, "descr", "mount_union -b and "
97 	    "'echo x >> /un/null'");
98 }
99 
100 ATF_TC_BODY(devnull2, tc)
101 {
102 	struct union_args unionargs;
103 	int fd;
104 
105 	rump_init();
106 
107 	if (rump_sys_mkdir("/mp", 0777) == -1)
108 		atf_tc_fail_errno("mkdir mp");
109 
110 	unionargs.target = __UNCONST("/dev");
111 	unionargs.mntflags = UNMNT_BELOW;
112 
113 	if (rump_sys_mount(MOUNT_UNION, "/mp", 0,
114 	    &unionargs, sizeof(unionargs)) == -1)
115 		atf_tc_fail_errno("union mount");
116 
117 	fd = rump_sys_open("/mp/null", O_WRONLY | O_CREAT | O_APPEND);
118 	if (fd == -1)
119 		atf_tc_fail_errno("open");
120 
121 	atf_tc_expect_signal(-1, "PR kern/43560");
122 	rump_sys_write(fd, &fd, sizeof(fd));
123 }
124 
125 ATF_TP_ADD_TCS(tp)
126 {
127 	ATF_TP_ADD_TC(tp, multilayer);
128 	ATF_TP_ADD_TC(tp, devnull1);
129 	ATF_TP_ADD_TC(tp, devnull2);
130 
131 	return atf_no_error();
132 }
133