xref: /netbsd-src/tests/rump/rumpkern/t_modcmd.c (revision cdf297bb0188ff50c05e40d19fcd8538b29ff96e)
1*cdf297bbSpooka /*	$NetBSD: t_modcmd.c,v 1.6 2010/05/01 11:20:21 pooka Exp $	*/
280be26daSpooka 
380be26daSpooka /*
480be26daSpooka  * Copyright (c) 2009 The NetBSD Foundation, Inc.
580be26daSpooka  * All rights reserved.
680be26daSpooka  *
780be26daSpooka  * Redistribution and use in source and binary forms, with or without
880be26daSpooka  * modification, are permitted provided that the following conditions
980be26daSpooka  * are met:
1080be26daSpooka  * 1. Redistributions of source code must retain the above copyright
1180be26daSpooka  *    notice, this list of conditions and the following disclaimer.
1280be26daSpooka  * 2. Redistributions in binary form must reproduce the above copyright
1380be26daSpooka  *    notice, this list of conditions and the following disclaimer in the
1480be26daSpooka  *    documentation and/or other materials provided with the distribution.
1580be26daSpooka  *
1680be26daSpooka  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
1780be26daSpooka  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
1880be26daSpooka  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1980be26daSpooka  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2080be26daSpooka  * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
2180be26daSpooka  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2280be26daSpooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2380be26daSpooka  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2480be26daSpooka  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2580be26daSpooka  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2680be26daSpooka  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
2780be26daSpooka  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2880be26daSpooka  */
2980be26daSpooka 
3080be26daSpooka #include <sys/types.h>
3180be26daSpooka #include <sys/mount.h>
32*cdf297bbSpooka #include <sys/sysctl.h>
3380be26daSpooka 
3480be26daSpooka #include <rump/rump.h>
3580be26daSpooka #include <rump/rump_syscalls.h>
3680be26daSpooka 
3780be26daSpooka #include <fs/tmpfs/tmpfs_args.h>
3880be26daSpooka 
3980be26daSpooka #include <atf-c.h>
4080be26daSpooka #include <dlfcn.h>
4180be26daSpooka #include <err.h>
4280be26daSpooka #include <errno.h>
4380be26daSpooka #include <stdio.h>
4480be26daSpooka #include <stdlib.h>
4580be26daSpooka #include <string.h>
4680be26daSpooka #include <unistd.h>
4780be26daSpooka #include <util.h>
4880be26daSpooka 
4980be26daSpooka #include "../../h_macros.h"
5080be26daSpooka 
5180be26daSpooka /*
5280be26daSpooka  * We verify that modules can be loaded and unloaded.
5380be26daSpooka  * tmpfs was chosen because it does not depend on an image.
5480be26daSpooka  */
5580be26daSpooka 
5680be26daSpooka ATF_TC(cmsg_modcmd);
5780be26daSpooka ATF_TC_HEAD(cmsg_modcmd, tc)
5880be26daSpooka {
5980be26daSpooka 	atf_tc_set_md_var(tc, "descr", "Checks that loading and unloading "
6080be26daSpooka 	    "a module (vfs/tmpfs) is possible");
6180be26daSpooka }
6280be26daSpooka 
63*cdf297bbSpooka static int
64*cdf297bbSpooka disable_autoload(void)
65*cdf297bbSpooka {
66*cdf297bbSpooka 	struct sysctlnode q, ans[256];
67*cdf297bbSpooka 	int mib[3];
68*cdf297bbSpooka 	size_t alen;
69*cdf297bbSpooka 	unsigned i;
70*cdf297bbSpooka 	bool no;
71*cdf297bbSpooka 
72*cdf297bbSpooka 	mib[0] = CTL_KERN;
73*cdf297bbSpooka 	mib[1] = CTL_QUERY;
74*cdf297bbSpooka 	alen = sizeof(ans);
75*cdf297bbSpooka 
76*cdf297bbSpooka 	memset(&q, 0, sizeof(q));
77*cdf297bbSpooka 	q.sysctl_flags = SYSCTL_VERSION;
78*cdf297bbSpooka 
79*cdf297bbSpooka 	if (rump_sys___sysctl(mib, 2, ans, &alen, &q, sizeof(q)) == -1)
80*cdf297bbSpooka 		return -1;
81*cdf297bbSpooka 
82*cdf297bbSpooka 	for (i = 0; i < __arraycount(ans); i++)
83*cdf297bbSpooka 		if (strcmp("module", ans[i].sysctl_name) == 0)
84*cdf297bbSpooka 			break;
85*cdf297bbSpooka 	if (i == __arraycount(ans)) {
86*cdf297bbSpooka 		errno = ENOENT;
87*cdf297bbSpooka 		return -1;
88*cdf297bbSpooka 	}
89*cdf297bbSpooka 
90*cdf297bbSpooka 	mib[1] = ans[i].sysctl_num;
91*cdf297bbSpooka 	mib[2] = CTL_QUERY;
92*cdf297bbSpooka 
93*cdf297bbSpooka 	if (rump_sys___sysctl(mib, 3, ans, &alen, &q, sizeof(q)) == -1)
94*cdf297bbSpooka 		return errno;
95*cdf297bbSpooka 
96*cdf297bbSpooka 	for (i = 0; i < __arraycount(ans); i++)
97*cdf297bbSpooka 		if (strcmp("autoload", ans[i].sysctl_name) == 0)
98*cdf297bbSpooka 			break;
99*cdf297bbSpooka 	if (i == __arraycount(ans)) {
100*cdf297bbSpooka 		errno = ENOENT;
101*cdf297bbSpooka 		return -1;
102*cdf297bbSpooka 	}
103*cdf297bbSpooka 
104*cdf297bbSpooka 	mib[2] = ans[i].sysctl_num;
105*cdf297bbSpooka 
106*cdf297bbSpooka 	no = false;
107*cdf297bbSpooka 	alen = 0;
108*cdf297bbSpooka 	if (rump_sys___sysctl(mib, 3, NULL, &alen, &no, sizeof(no)) == -1)
109*cdf297bbSpooka 		return errno;
110*cdf297bbSpooka 
111*cdf297bbSpooka 	return 0;
112*cdf297bbSpooka 
113*cdf297bbSpooka }
114*cdf297bbSpooka 
115863335f9Spooka #define TMPFSMODULE "librumpfs_tmpfs.so"
11680be26daSpooka ATF_TC_BODY(cmsg_modcmd, tc)
11780be26daSpooka {
11880be26daSpooka 	struct tmpfs_args args;
11905e0f1dbSpooka 	const struct modinfo *const *mi_start, *const *mi_end;
12080be26daSpooka 	void *handle;
12105e0f1dbSpooka 	int i, rv, loop = 0;
12280be26daSpooka 
12380be26daSpooka 	rump_init();
124*cdf297bbSpooka 
125*cdf297bbSpooka 	if (disable_autoload() == -1)
126*cdf297bbSpooka 		atf_tc_fail_errno("count not disable module autoload");
127*cdf297bbSpooka 
12880be26daSpooka 	memset(&args, 0, sizeof(args));
12980be26daSpooka 	args.ta_version = TMPFS_ARGS_VERSION;
13080be26daSpooka 	args.ta_root_mode = 0777;
13180be26daSpooka 
13280be26daSpooka 	if (rump_sys_mkdir("/mp", 0777) == -1)
13380be26daSpooka 		atf_tc_fail_errno("mkdir mountpoint");
13480be26daSpooka 	if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) != -1)
13580be26daSpooka 		atf_tc_fail("mount unexpectedly succeeded");
13680be26daSpooka 
13780be26daSpooka 	handle = dlopen(TMPFSMODULE, RTLD_GLOBAL);
13880be26daSpooka 	if (handle == NULL) {
13980be26daSpooka 		const char *dlmsg = dlerror();
14080be26daSpooka 		atf_tc_fail("cannot open %s: %s", TMPFSMODULE, dlmsg);
14180be26daSpooka 	}
14205e0f1dbSpooka 
14305e0f1dbSpooka  again:
14405e0f1dbSpooka 	mi_start = dlsym(handle, "__start_link_set_modules");
14505e0f1dbSpooka 	mi_end = dlsym(handle, "__stop_link_set_modules");
14605e0f1dbSpooka 	if (mi_start == NULL || mi_end == NULL)
14780be26daSpooka 		atf_tc_fail("cannot find module info");
14805e0f1dbSpooka 	if ((rv = rump_pub_module_init(mi_start, (size_t)(mi_end-mi_start)))!=0)
14980be26daSpooka 		atf_tc_fail("module init failed: %d (%s)", rv, strerror(rv));
15005e0f1dbSpooka 	if ((rv = rump_pub_module_init(mi_start, (size_t)(mi_end-mi_start)))==0)
15105e0f1dbSpooka 		atf_tc_fail("module double init succeeded");
15280be26daSpooka 
15380be26daSpooka 	if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) == -1)
15480be26daSpooka 		atf_tc_fail_errno("still cannot mount");
15580be26daSpooka 	if (rump_sys_unmount("/mp", 0) == -1)
15680be26daSpooka 		atf_tc_fail("cannot unmount");
15705e0f1dbSpooka 	for (i = 0; i < (int)(mi_end-mi_start); i++) {
15805e0f1dbSpooka 		if ((rv = rump_pub_module_fini(mi_start[i])) != 0)
15905e0f1dbSpooka 			atf_tc_fail("module fini failed: %d (%s)",
16005e0f1dbSpooka 			    rv, strerror(rv));
16105e0f1dbSpooka 	}
16205e0f1dbSpooka 	for (i = 0; i < (int)(mi_end-mi_start); i++) {
16305e0f1dbSpooka 		if ((rv = rump_pub_module_fini(mi_start[i])) == 0)
16405e0f1dbSpooka 			atf_tc_fail("module double fini succeeded");
16505e0f1dbSpooka 	}
16605e0f1dbSpooka 	if (loop++ == 0)
16705e0f1dbSpooka 		goto again;
16805e0f1dbSpooka 
16980be26daSpooka 	if (dlclose(handle)) {
17080be26daSpooka 		const char *dlmsg = dlerror();
17180be26daSpooka 		atf_tc_fail("cannot close %s: %s", TMPFSMODULE, dlmsg);
17280be26daSpooka 	}
17380be26daSpooka 
17480be26daSpooka 	if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) != -1)
17580be26daSpooka 		atf_tc_fail("mount unexpectedly succeeded");
17680be26daSpooka }
17780be26daSpooka 
17880be26daSpooka ATF_TP_ADD_TCS(tp)
17980be26daSpooka {
18080be26daSpooka 	ATF_TP_ADD_TC(tp, cmsg_modcmd);
181aebec17aSpooka 
182aebec17aSpooka 	return atf_no_error();
18380be26daSpooka }
184