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