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 47 static char kernfs[] = "kernfs"; 48 49 static bool 50 check_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 66 ATF_TC(disable); 67 ATF_TC_HEAD(disable, tc) 68 { 69 70 atf_tc_set_md_var(tc, "descr", "Tests that builtin modules can " 71 "be disabled"); 72 } 73 74 ATF_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 85 ATF_TC(noauto); 86 ATF_TC_HEAD(noauto, tc) 87 { 88 atf_tc_set_md_var(tc, "descr", "Tests that disabled builtin modules " 89 "will not autoload"); 90 } 91 92 ATF_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 104 ATF_TC(forcereload); 105 ATF_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 111 ATF_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 133 ATF_TC(disabledstat); 134 ATF_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 140 ATF_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 166 ATF_TC(busydisable); 167 ATF_TC_HEAD(busydisable, tc) 168 { 169 atf_tc_set_md_var(tc, "descr", "Tests that busy builtin modules " 170 "cannot be disabled"); 171 } 172 173 ATF_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 184 ATF_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