1*57718be8SEnji Cooper /* $NetBSD: t_modcmd.c,v 1.9 2010/05/31 23:51:28 pooka Exp $ */ 2*57718be8SEnji Cooper 3*57718be8SEnji Cooper /* 4*57718be8SEnji Cooper * Copyright (c) 2009 The NetBSD Foundation, Inc. 5*57718be8SEnji Cooper * All rights reserved. 6*57718be8SEnji Cooper * 7*57718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 8*57718be8SEnji Cooper * modification, are permitted provided that the following conditions 9*57718be8SEnji Cooper * are met: 10*57718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 11*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 12*57718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 13*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 14*57718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 15*57718be8SEnji Cooper * 16*57718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17*57718be8SEnji Cooper * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18*57718be8SEnji Cooper * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19*57718be8SEnji Cooper * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20*57718be8SEnji Cooper * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21*57718be8SEnji Cooper * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*57718be8SEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23*57718be8SEnji Cooper * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24*57718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25*57718be8SEnji Cooper * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26*57718be8SEnji Cooper * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27*57718be8SEnji Cooper * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*57718be8SEnji Cooper */ 29*57718be8SEnji Cooper 30*57718be8SEnji Cooper #include <sys/types.h> 31*57718be8SEnji Cooper #include <sys/mount.h> 32*57718be8SEnji Cooper #include <sys/sysctl.h> 33*57718be8SEnji Cooper 34*57718be8SEnji Cooper #include <rump/rump.h> 35*57718be8SEnji Cooper #include <rump/rump_syscalls.h> 36*57718be8SEnji Cooper 37*57718be8SEnji Cooper #include <fs/tmpfs/tmpfs_args.h> 38*57718be8SEnji Cooper 39*57718be8SEnji Cooper #include <atf-c.h> 40*57718be8SEnji Cooper #include <dlfcn.h> 41*57718be8SEnji Cooper #include <err.h> 42*57718be8SEnji Cooper #include <errno.h> 43*57718be8SEnji Cooper #include <stdio.h> 44*57718be8SEnji Cooper #include <stdlib.h> 45*57718be8SEnji Cooper #include <string.h> 46*57718be8SEnji Cooper #include <unistd.h> 47*57718be8SEnji Cooper #include <util.h> 48*57718be8SEnji Cooper 49*57718be8SEnji Cooper #include "../../h_macros.h" 50*57718be8SEnji Cooper /* 51*57718be8SEnji Cooper * We verify that modules can be loaded and unloaded. 52*57718be8SEnji Cooper * tmpfs was chosen because it does not depend on an image. 53*57718be8SEnji Cooper */ 54*57718be8SEnji Cooper 55*57718be8SEnji Cooper ATF_TC(cmsg_modcmd); 56*57718be8SEnji Cooper ATF_TC_HEAD(cmsg_modcmd, tc) 57*57718be8SEnji Cooper { 58*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Checks that loading and unloading " 59*57718be8SEnji Cooper "a module (vfs/tmpfs) is possible"); 60*57718be8SEnji Cooper } 61*57718be8SEnji Cooper 62*57718be8SEnji Cooper static int 63*57718be8SEnji Cooper disable_autoload(void) 64*57718be8SEnji Cooper { 65*57718be8SEnji Cooper struct sysctlnode q, ans[256]; 66*57718be8SEnji Cooper int mib[3]; 67*57718be8SEnji Cooper size_t alen; 68*57718be8SEnji Cooper unsigned i; 69*57718be8SEnji Cooper bool no; 70*57718be8SEnji Cooper 71*57718be8SEnji Cooper mib[0] = CTL_KERN; 72*57718be8SEnji Cooper mib[1] = CTL_QUERY; 73*57718be8SEnji Cooper alen = sizeof(ans); 74*57718be8SEnji Cooper 75*57718be8SEnji Cooper memset(&q, 0, sizeof(q)); 76*57718be8SEnji Cooper q.sysctl_flags = SYSCTL_VERSION; 77*57718be8SEnji Cooper 78*57718be8SEnji Cooper if (rump_sys___sysctl(mib, 2, ans, &alen, &q, sizeof(q)) == -1) 79*57718be8SEnji Cooper return -1; 80*57718be8SEnji Cooper 81*57718be8SEnji Cooper for (i = 0; i < __arraycount(ans); i++) 82*57718be8SEnji Cooper if (strcmp("module", ans[i].sysctl_name) == 0) 83*57718be8SEnji Cooper break; 84*57718be8SEnji Cooper if (i == __arraycount(ans)) { 85*57718be8SEnji Cooper errno = ENOENT; 86*57718be8SEnji Cooper return -1; 87*57718be8SEnji Cooper } 88*57718be8SEnji Cooper 89*57718be8SEnji Cooper mib[1] = ans[i].sysctl_num; 90*57718be8SEnji Cooper mib[2] = CTL_QUERY; 91*57718be8SEnji Cooper 92*57718be8SEnji Cooper if (rump_sys___sysctl(mib, 3, ans, &alen, &q, sizeof(q)) == -1) 93*57718be8SEnji Cooper return errno; 94*57718be8SEnji Cooper 95*57718be8SEnji Cooper for (i = 0; i < __arraycount(ans); i++) 96*57718be8SEnji Cooper if (strcmp("autoload", ans[i].sysctl_name) == 0) 97*57718be8SEnji Cooper break; 98*57718be8SEnji Cooper if (i == __arraycount(ans)) { 99*57718be8SEnji Cooper errno = ENOENT; 100*57718be8SEnji Cooper return -1; 101*57718be8SEnji Cooper } 102*57718be8SEnji Cooper 103*57718be8SEnji Cooper mib[2] = ans[i].sysctl_num; 104*57718be8SEnji Cooper 105*57718be8SEnji Cooper no = false; 106*57718be8SEnji Cooper alen = 0; 107*57718be8SEnji Cooper if (rump_sys___sysctl(mib, 3, NULL, &alen, &no, sizeof(no)) == -1) 108*57718be8SEnji Cooper return errno; 109*57718be8SEnji Cooper 110*57718be8SEnji Cooper return 0; 111*57718be8SEnji Cooper 112*57718be8SEnji Cooper } 113*57718be8SEnji Cooper 114*57718be8SEnji Cooper #define TMPFSMODULE "librumpfs_tmpfs.so" 115*57718be8SEnji Cooper ATF_TC_BODY(cmsg_modcmd, tc) 116*57718be8SEnji Cooper { 117*57718be8SEnji Cooper struct tmpfs_args args; 118*57718be8SEnji Cooper const struct modinfo *const *mi_start, *const *mi_end; 119*57718be8SEnji Cooper void *handle; 120*57718be8SEnji Cooper int i, rv, loop = 0; 121*57718be8SEnji Cooper 122*57718be8SEnji Cooper rump_init(); 123*57718be8SEnji Cooper 124*57718be8SEnji Cooper if (disable_autoload() == -1) 125*57718be8SEnji Cooper atf_tc_fail_errno("count not disable module autoload"); 126*57718be8SEnji Cooper 127*57718be8SEnji Cooper memset(&args, 0, sizeof(args)); 128*57718be8SEnji Cooper args.ta_version = TMPFS_ARGS_VERSION; 129*57718be8SEnji Cooper args.ta_root_mode = 0777; 130*57718be8SEnji Cooper 131*57718be8SEnji Cooper if (rump_sys_mkdir("/mp", 0777) == -1) 132*57718be8SEnji Cooper atf_tc_fail_errno("mkdir mountpoint"); 133*57718be8SEnji Cooper if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) != -1) 134*57718be8SEnji Cooper atf_tc_fail("mount unexpectedly succeeded"); 135*57718be8SEnji Cooper 136*57718be8SEnji Cooper handle = dlopen(TMPFSMODULE, RTLD_GLOBAL); 137*57718be8SEnji Cooper if (handle == NULL) { 138*57718be8SEnji Cooper const char *dlmsg = dlerror(); 139*57718be8SEnji Cooper atf_tc_fail("cannot open %s: %s", TMPFSMODULE, dlmsg); 140*57718be8SEnji Cooper } 141*57718be8SEnji Cooper 142*57718be8SEnji Cooper again: 143*57718be8SEnji Cooper mi_start = dlsym(handle, "__start_link_set_modules"); 144*57718be8SEnji Cooper mi_end = dlsym(handle, "__stop_link_set_modules"); 145*57718be8SEnji Cooper if (mi_start == NULL || mi_end == NULL) 146*57718be8SEnji Cooper atf_tc_fail("cannot find module info"); 147*57718be8SEnji Cooper if ((rv = rump_pub_module_init(mi_start, (size_t)(mi_end-mi_start)))!=0) 148*57718be8SEnji Cooper atf_tc_fail("module init failed: %d (%s)", rv, strerror(rv)); 149*57718be8SEnji Cooper if ((rv = rump_pub_module_init(mi_start, (size_t)(mi_end-mi_start)))==0) 150*57718be8SEnji Cooper atf_tc_fail("module double init succeeded"); 151*57718be8SEnji Cooper 152*57718be8SEnji Cooper if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) == -1) 153*57718be8SEnji Cooper atf_tc_fail_errno("still cannot mount"); 154*57718be8SEnji Cooper if (rump_sys_unmount("/mp", 0) == -1) 155*57718be8SEnji Cooper atf_tc_fail("cannot unmount"); 156*57718be8SEnji Cooper for (i = 0; i < (int)(mi_end-mi_start); i++) { 157*57718be8SEnji Cooper if ((rv = rump_pub_module_fini(mi_start[i])) != 0) 158*57718be8SEnji Cooper atf_tc_fail("module fini failed: %d (%s)", 159*57718be8SEnji Cooper rv, strerror(rv)); 160*57718be8SEnji Cooper } 161*57718be8SEnji Cooper for (i = 0; i < (int)(mi_end-mi_start); i++) { 162*57718be8SEnji Cooper if ((rv = rump_pub_module_fini(mi_start[i])) == 0) 163*57718be8SEnji Cooper atf_tc_fail("module double fini succeeded"); 164*57718be8SEnji Cooper } 165*57718be8SEnji Cooper if (loop++ == 0) 166*57718be8SEnji Cooper goto again; 167*57718be8SEnji Cooper 168*57718be8SEnji Cooper if (dlclose(handle)) { 169*57718be8SEnji Cooper const char *dlmsg = dlerror(); 170*57718be8SEnji Cooper atf_tc_fail("cannot close %s: %s", TMPFSMODULE, dlmsg); 171*57718be8SEnji Cooper } 172*57718be8SEnji Cooper 173*57718be8SEnji Cooper if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) != -1) 174*57718be8SEnji Cooper atf_tc_fail("mount unexpectedly succeeded"); 175*57718be8SEnji Cooper } 176*57718be8SEnji Cooper 177*57718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 178*57718be8SEnji Cooper { 179*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, cmsg_modcmd); 180*57718be8SEnji Cooper 181*57718be8SEnji Cooper return atf_no_error(); 182*57718be8SEnji Cooper } 183