xref: /netbsd-src/tests/rump/rumpkern/t_modcmd.c (revision c54cb81102ced2313cb40993fe05548aca9933a1)
1*c54cb811Schristos /*	$NetBSD: t_modcmd.c,v 1.10 2017/01/13 21:30:43 christos 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>
32cdf297bbSpooka #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 
49*c54cb811Schristos #include "h_macros.h"
5080be26daSpooka /*
5180be26daSpooka  * We verify that modules can be loaded and unloaded.
5280be26daSpooka  * tmpfs was chosen because it does not depend on an image.
5380be26daSpooka  */
5480be26daSpooka 
5580be26daSpooka ATF_TC(cmsg_modcmd);
ATF_TC_HEAD(cmsg_modcmd,tc)5680be26daSpooka ATF_TC_HEAD(cmsg_modcmd, tc)
5780be26daSpooka {
5880be26daSpooka 	atf_tc_set_md_var(tc, "descr", "Checks that loading and unloading "
5980be26daSpooka 	    "a module (vfs/tmpfs) is possible");
6080be26daSpooka }
6180be26daSpooka 
62cdf297bbSpooka static int
disable_autoload(void)63cdf297bbSpooka disable_autoload(void)
64cdf297bbSpooka {
65cdf297bbSpooka 	struct sysctlnode q, ans[256];
66cdf297bbSpooka 	int mib[3];
67cdf297bbSpooka 	size_t alen;
68cdf297bbSpooka 	unsigned i;
69cdf297bbSpooka 	bool no;
70cdf297bbSpooka 
71cdf297bbSpooka 	mib[0] = CTL_KERN;
72cdf297bbSpooka 	mib[1] = CTL_QUERY;
73cdf297bbSpooka 	alen = sizeof(ans);
74cdf297bbSpooka 
75cdf297bbSpooka 	memset(&q, 0, sizeof(q));
76cdf297bbSpooka 	q.sysctl_flags = SYSCTL_VERSION;
77cdf297bbSpooka 
78cdf297bbSpooka 	if (rump_sys___sysctl(mib, 2, ans, &alen, &q, sizeof(q)) == -1)
79cdf297bbSpooka 		return -1;
80cdf297bbSpooka 
81cdf297bbSpooka 	for (i = 0; i < __arraycount(ans); i++)
82cdf297bbSpooka 		if (strcmp("module", ans[i].sysctl_name) == 0)
83cdf297bbSpooka 			break;
84cdf297bbSpooka 	if (i == __arraycount(ans)) {
85cdf297bbSpooka 		errno = ENOENT;
86cdf297bbSpooka 		return -1;
87cdf297bbSpooka 	}
88cdf297bbSpooka 
89cdf297bbSpooka 	mib[1] = ans[i].sysctl_num;
90cdf297bbSpooka 	mib[2] = CTL_QUERY;
91cdf297bbSpooka 
92cdf297bbSpooka 	if (rump_sys___sysctl(mib, 3, ans, &alen, &q, sizeof(q)) == -1)
93cdf297bbSpooka 		return errno;
94cdf297bbSpooka 
95cdf297bbSpooka 	for (i = 0; i < __arraycount(ans); i++)
96cdf297bbSpooka 		if (strcmp("autoload", ans[i].sysctl_name) == 0)
97cdf297bbSpooka 			break;
98cdf297bbSpooka 	if (i == __arraycount(ans)) {
99cdf297bbSpooka 		errno = ENOENT;
100cdf297bbSpooka 		return -1;
101cdf297bbSpooka 	}
102cdf297bbSpooka 
103cdf297bbSpooka 	mib[2] = ans[i].sysctl_num;
104cdf297bbSpooka 
105cdf297bbSpooka 	no = false;
106cdf297bbSpooka 	alen = 0;
107cdf297bbSpooka 	if (rump_sys___sysctl(mib, 3, NULL, &alen, &no, sizeof(no)) == -1)
108cdf297bbSpooka 		return errno;
109cdf297bbSpooka 
110cdf297bbSpooka 	return 0;
111cdf297bbSpooka 
112cdf297bbSpooka }
113cdf297bbSpooka 
114863335f9Spooka #define TMPFSMODULE "librumpfs_tmpfs.so"
ATF_TC_BODY(cmsg_modcmd,tc)11580be26daSpooka ATF_TC_BODY(cmsg_modcmd, tc)
11680be26daSpooka {
11780be26daSpooka 	struct tmpfs_args args;
11805e0f1dbSpooka 	const struct modinfo *const *mi_start, *const *mi_end;
11980be26daSpooka 	void *handle;
12005e0f1dbSpooka 	int i, rv, loop = 0;
12180be26daSpooka 
12280be26daSpooka 	rump_init();
123cdf297bbSpooka 
124cdf297bbSpooka 	if (disable_autoload() == -1)
125cdf297bbSpooka 		atf_tc_fail_errno("count not disable module autoload");
126cdf297bbSpooka 
12780be26daSpooka 	memset(&args, 0, sizeof(args));
12880be26daSpooka 	args.ta_version = TMPFS_ARGS_VERSION;
12980be26daSpooka 	args.ta_root_mode = 0777;
13080be26daSpooka 
13180be26daSpooka 	if (rump_sys_mkdir("/mp", 0777) == -1)
13280be26daSpooka 		atf_tc_fail_errno("mkdir mountpoint");
13380be26daSpooka 	if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) != -1)
13480be26daSpooka 		atf_tc_fail("mount unexpectedly succeeded");
13580be26daSpooka 
13680be26daSpooka 	handle = dlopen(TMPFSMODULE, RTLD_GLOBAL);
13780be26daSpooka 	if (handle == NULL) {
13880be26daSpooka 		const char *dlmsg = dlerror();
13980be26daSpooka 		atf_tc_fail("cannot open %s: %s", TMPFSMODULE, dlmsg);
14080be26daSpooka 	}
14105e0f1dbSpooka 
14205e0f1dbSpooka  again:
14305e0f1dbSpooka 	mi_start = dlsym(handle, "__start_link_set_modules");
14405e0f1dbSpooka 	mi_end = dlsym(handle, "__stop_link_set_modules");
14505e0f1dbSpooka 	if (mi_start == NULL || mi_end == NULL)
14680be26daSpooka 		atf_tc_fail("cannot find module info");
14705e0f1dbSpooka 	if ((rv = rump_pub_module_init(mi_start, (size_t)(mi_end-mi_start)))!=0)
14880be26daSpooka 		atf_tc_fail("module init failed: %d (%s)", rv, strerror(rv));
14905e0f1dbSpooka 	if ((rv = rump_pub_module_init(mi_start, (size_t)(mi_end-mi_start)))==0)
15005e0f1dbSpooka 		atf_tc_fail("module double init succeeded");
15180be26daSpooka 
15280be26daSpooka 	if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) == -1)
15380be26daSpooka 		atf_tc_fail_errno("still cannot mount");
15480be26daSpooka 	if (rump_sys_unmount("/mp", 0) == -1)
15580be26daSpooka 		atf_tc_fail("cannot unmount");
15605e0f1dbSpooka 	for (i = 0; i < (int)(mi_end-mi_start); i++) {
15705e0f1dbSpooka 		if ((rv = rump_pub_module_fini(mi_start[i])) != 0)
15805e0f1dbSpooka 			atf_tc_fail("module fini failed: %d (%s)",
15905e0f1dbSpooka 			    rv, strerror(rv));
16005e0f1dbSpooka 	}
16105e0f1dbSpooka 	for (i = 0; i < (int)(mi_end-mi_start); i++) {
16205e0f1dbSpooka 		if ((rv = rump_pub_module_fini(mi_start[i])) == 0)
16305e0f1dbSpooka 			atf_tc_fail("module double fini succeeded");
16405e0f1dbSpooka 	}
16505e0f1dbSpooka 	if (loop++ == 0)
16605e0f1dbSpooka 		goto again;
16705e0f1dbSpooka 
16880be26daSpooka 	if (dlclose(handle)) {
16980be26daSpooka 		const char *dlmsg = dlerror();
17080be26daSpooka 		atf_tc_fail("cannot close %s: %s", TMPFSMODULE, dlmsg);
17180be26daSpooka 	}
17280be26daSpooka 
17380be26daSpooka 	if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) != -1)
17480be26daSpooka 		atf_tc_fail("mount unexpectedly succeeded");
17580be26daSpooka }
17680be26daSpooka 
ATF_TP_ADD_TCS(tp)17780be26daSpooka ATF_TP_ADD_TCS(tp)
17880be26daSpooka {
17980be26daSpooka 	ATF_TP_ADD_TC(tp, cmsg_modcmd);
180aebec17aSpooka 
181aebec17aSpooka 	return atf_no_error();
18280be26daSpooka }
183