t_pr.c revision 1.7 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