t_builtin.c revision 314817
1/*	$NetBSD: t_builtin.c,v 1.3 2017/01/13 21:30:42 christos Exp $	*/
2
3/*-
4 * Copyright (c) 2010 The NetBSD Foundation, Inc.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
16 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/types.h>
30#include <sys/module.h>
31#include <sys/mount.h>
32
33#include <atf-c.h>
34#include <fcntl.h>
35#include <stdbool.h>
36
37#include <miscfs/kernfs/kernfs.h>
38
39#include <rump/rump.h>
40#include <rump/rump_syscalls.h>
41
42#include "h_macros.h"
43
44#define MYMP "/mnt"
45#define HZFILE MYMP "/hz"
46
47static char kernfs[] = "kernfs";
48
49static bool
50check_kernfs(void)
51{
52	char buf[16];
53	bool rv = true;
54	int fd;
55
56	fd = rump_sys_open(HZFILE, O_RDONLY);
57	if (fd == -1)
58		return false;
59	if (rump_sys_read(fd, buf, sizeof(buf)) < 1)
60		rv = false;
61	RL(rump_sys_close(fd));
62
63	return rv;
64}
65
66ATF_TC(disable);
67ATF_TC_HEAD(disable, tc)
68{
69
70	atf_tc_set_md_var(tc, "descr", "Tests that builtin modules can "
71	    "be disabled");
72}
73
74ATF_TC_BODY(disable, tc)
75{
76
77	rump_init();
78	RL(rump_sys_mkdir(MYMP, 0777));
79	RL(rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0));
80	ATF_REQUIRE(check_kernfs());
81	RL(rump_sys_unmount(MYMP, 0));
82	RL(rump_sys_modctl(MODCTL_UNLOAD, kernfs));
83}
84
85ATF_TC(noauto);
86ATF_TC_HEAD(noauto, tc)
87{
88	atf_tc_set_md_var(tc, "descr", "Tests that disabled builtin modules "
89	    "will not autoload");
90}
91
92ATF_TC_BODY(noauto, tc)
93{
94
95	rump_init();
96	RL(rump_sys_mkdir(MYMP, 0777));
97
98	RL(rump_sys_modctl(MODCTL_UNLOAD, kernfs));
99
100	ATF_REQUIRE_ERRNO(ENODEV,
101	    rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0) == -1);
102}
103
104ATF_TC(forcereload);
105ATF_TC_HEAD(forcereload, tc)
106{
107	atf_tc_set_md_var(tc, "descr", "Tests that disabled builtin modules "
108	    "can be force-reloaded");
109}
110
111ATF_TC_BODY(forcereload, tc)
112{
113	struct modctl_load mod;
114
115	rump_init();
116	RL(rump_sys_mkdir(MYMP, 0777));
117
118	RL(rump_sys_modctl(MODCTL_UNLOAD, kernfs));
119	ATF_REQUIRE_ERRNO(ENODEV,
120	    rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0) == -1);
121
122	memset(&mod, 0, sizeof(mod));
123	mod.ml_filename = kernfs;
124	mod.ml_flags = MODCTL_LOAD_FORCE;
125
126	RL(rump_sys_modctl(MODCTL_LOAD, &mod));
127
128	RL(rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0));
129	ATF_REQUIRE(check_kernfs());
130	RL(rump_sys_unmount(MYMP, 0));
131}
132
133ATF_TC(disabledstat);
134ATF_TC_HEAD(disabledstat, tc)
135{
136	atf_tc_set_md_var(tc, "descr", "Tests that disabled builtin modules "
137	    "show up in modstat with refcount -1");
138}
139
140ATF_TC_BODY(disabledstat, tc)
141{
142	struct modstat ms[128];
143	struct iovec iov;
144	size_t i;
145	bool found = false;
146
147	rump_init();
148	RL(rump_sys_mkdir(MYMP, 0777));
149
150	RL(rump_sys_modctl(MODCTL_UNLOAD, kernfs));
151
152	iov.iov_base = ms;
153	iov.iov_len = sizeof(ms);
154	RL(rump_sys_modctl(MODCTL_STAT, &iov));
155
156	for (i = 0; i < __arraycount(ms); i++) {
157		if (strcmp(ms[i].ms_name, kernfs) == 0) {
158			ATF_REQUIRE_EQ(ms[i].ms_refcnt, (u_int)-1);
159			found = 1;
160			break;
161		}
162	}
163	ATF_REQUIRE(found);
164}
165
166ATF_TC(busydisable);
167ATF_TC_HEAD(busydisable, tc)
168{
169	atf_tc_set_md_var(tc, "descr", "Tests that busy builtin modules "
170	    "cannot be disabled");
171}
172
173ATF_TC_BODY(busydisable, tc)
174{
175
176	rump_init();
177	RL(rump_sys_mkdir(MYMP, 0777));
178	RL(rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0));
179	ATF_REQUIRE(check_kernfs());
180	ATF_REQUIRE_ERRNO(EBUSY,
181	    rump_sys_modctl(MODCTL_UNLOAD, kernfs) == -1);
182}
183
184ATF_TP_ADD_TCS(tp)
185{
186
187	ATF_TP_ADD_TC(tp, disable);
188	ATF_TP_ADD_TC(tp, noauto);
189	ATF_TP_ADD_TC(tp, forcereload);
190	ATF_TP_ADD_TC(tp, disabledstat);
191	ATF_TP_ADD_TC(tp, busydisable);
192
193	return atf_no_error();
194}
195