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