1 /* $NetBSD: t_builtin.c,v 1.1 2010/08/27 09:56:40 pooka 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 47 static bool 48 check_kernfs(void) 49 { 50 char buf[16]; 51 bool rv = true; 52 int fd; 53 54 fd = rump_sys_open(HZFILE, O_RDONLY); 55 if (fd == -1) 56 return false; 57 if (rump_sys_read(fd, buf, sizeof(buf)) < 1) 58 rv = false; 59 RL(rump_sys_close(fd)); 60 61 return rv; 62 } 63 64 ATF_TC(disable); 65 ATF_TC_HEAD(disable, tc) 66 { 67 68 atf_tc_set_md_var(tc, "descr", "Tests that builtin modules can " 69 "be disabled"); 70 } 71 72 ATF_TC_BODY(disable, tc) 73 { 74 75 rump_init(); 76 RL(rump_sys_mkdir(MYMP, 0777)); 77 RL(rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0)); 78 ATF_REQUIRE(check_kernfs()); 79 RL(rump_sys_unmount(MYMP, 0)); 80 RL(rump_sys_modctl(MODCTL_UNLOAD, "kernfs")); 81 } 82 83 ATF_TC(noauto); 84 ATF_TC_HEAD(noauto, tc) 85 { 86 atf_tc_set_md_var(tc, "descr", "Tests that disabled builtin modules " 87 "will not autoload"); 88 } 89 90 ATF_TC_BODY(noauto, tc) 91 { 92 93 rump_init(); 94 RL(rump_sys_mkdir(MYMP, 0777)); 95 96 RL(rump_sys_modctl(MODCTL_UNLOAD, "kernfs")); 97 98 ATF_REQUIRE_ERRNO(ENODEV, 99 rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0) == -1); 100 } 101 102 ATF_TC(forcereload); 103 ATF_TC_HEAD(forcereload, tc) 104 { 105 atf_tc_set_md_var(tc, "descr", "Tests that disabled builtin modules " 106 "can be force-reloaded"); 107 } 108 109 ATF_TC_BODY(forcereload, tc) 110 { 111 struct modctl_load mod; 112 113 rump_init(); 114 RL(rump_sys_mkdir(MYMP, 0777)); 115 116 RL(rump_sys_modctl(MODCTL_UNLOAD, "kernfs")); 117 ATF_REQUIRE_ERRNO(ENODEV, 118 rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0) == -1); 119 120 memset(&mod, 0, sizeof(mod)); 121 mod.ml_filename = "kernfs"; 122 mod.ml_flags = MODCTL_LOAD_FORCE; 123 124 RL(rump_sys_modctl(MODCTL_LOAD, &mod)); 125 126 RL(rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0)); 127 ATF_REQUIRE(check_kernfs()); 128 RL(rump_sys_unmount(MYMP, 0)); 129 } 130 131 ATF_TC(disabledstat); 132 ATF_TC_HEAD(disabledstat, tc) 133 { 134 atf_tc_set_md_var(tc, "descr", "Tests that disabled builtin modules " 135 "show up in modstat with refcount -1"); 136 } 137 138 ATF_TC_BODY(disabledstat, tc) 139 { 140 struct modstat ms[128]; 141 struct iovec iov; 142 int i; 143 bool found = false; 144 145 rump_init(); 146 RL(rump_sys_mkdir(MYMP, 0777)); 147 148 RL(rump_sys_modctl(MODCTL_UNLOAD, "kernfs")); 149 150 iov.iov_base = ms; 151 iov.iov_len = sizeof(ms); 152 RL(rump_sys_modctl(MODCTL_STAT, &iov)); 153 154 for (i = 0; i < __arraycount(ms); i++) { 155 if (strcmp(ms[i].ms_name, "kernfs") == 0) { 156 ATF_REQUIRE_EQ(ms[i].ms_refcnt, -1); 157 found = 1; 158 break; 159 } 160 } 161 ATF_REQUIRE(found); 162 } 163 164 ATF_TC(busydisable); 165 ATF_TC_HEAD(busydisable, tc) 166 { 167 atf_tc_set_md_var(tc, "descr", "Tests that busy builtin modules " 168 "cannot be disabled"); 169 } 170 171 ATF_TC_BODY(busydisable, tc) 172 { 173 174 rump_init(); 175 RL(rump_sys_mkdir(MYMP, 0777)); 176 RL(rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0)); 177 ATF_REQUIRE(check_kernfs()); 178 ATF_REQUIRE_ERRNO(EBUSY, 179 rump_sys_modctl(MODCTL_UNLOAD, "kernfs") == -1); 180 } 181 182 ATF_TP_ADD_TCS(tp) 183 { 184 185 ATF_TP_ADD_TC(tp, disable); 186 ATF_TP_ADD_TC(tp, noauto); 187 ATF_TP_ADD_TC(tp, forcereload); 188 ATF_TP_ADD_TC(tp, disabledstat); 189 ATF_TP_ADD_TC(tp, busydisable); 190 191 return atf_no_error(); 192 } 193