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