t_pr.c revision 1.6 1 /* $NetBSD: t_pr.c,v 1.6 2010/07/03 12:23:04 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_fail_errno("open fail");
88
89 atf_tc_expect_pass();
90 }
91
92 ATF_TC(devnull2);
93 ATF_TC_HEAD(devnull2, tc)
94 {
95 atf_tc_set_md_var(tc, "descr", "mount_union -b and "
96 "'echo x >> /un/null'");
97 }
98
99 ATF_TC_BODY(devnull2, tc)
100 {
101 struct union_args unionargs;
102 int fd;
103
104 rump_init();
105
106 if (rump_sys_mkdir("/mp", 0777) == -1)
107 atf_tc_fail_errno("mkdir mp");
108
109 unionargs.target = __UNCONST("/dev");
110 unionargs.mntflags = UNMNT_BELOW;
111
112 if (rump_sys_mount(MOUNT_UNION, "/mp", 0,
113 &unionargs, sizeof(unionargs)) == -1)
114 atf_tc_fail_errno("union mount");
115
116 fd = rump_sys_open("/mp/null", O_WRONLY | O_CREAT | O_APPEND);
117 if (fd == -1)
118 atf_tc_fail_errno("open");
119
120 atf_tc_expect_signal(-1, "PR kern/43560");
121 rump_sys_write(fd, &fd, sizeof(fd));
122 }
123
124 ATF_TP_ADD_TCS(tp)
125 {
126 ATF_TP_ADD_TC(tp, multilayer);
127 ATF_TP_ADD_TC(tp, devnull1);
128 ATF_TP_ADD_TC(tp, devnull2);
129
130 return atf_no_error();
131 }
132