1314818Sngie/*	$NetBSD: t_modautoload.c,v 1.6 2017/01/13 21:30:42 christos Exp $	*/
2272343Sngie
3272343Sngie#include <sys/types.h>
4272343Sngie#include <sys/mount.h>
5272343Sngie#include <sys/module.h>
6272343Sngie#include <sys/dirent.h>
7272343Sngie#include <sys/sysctl.h>
8272343Sngie
9272343Sngie#include <atf-c.h>
10272343Sngie#include <err.h>
11272343Sngie#include <errno.h>
12272343Sngie#include <fcntl.h>
13272343Sngie#include <stdio.h>
14272343Sngie#include <unistd.h>
15272343Sngie#include <string.h>
16272343Sngie#include <stdlib.h>
17272343Sngie
18272343Sngie#include <rump/rump.h>
19272343Sngie#include <rump/rump_syscalls.h>
20272343Sngie
21272343Sngie#include <miscfs/kernfs/kernfs.h>
22272343Sngie
23314818Sngie#include "h_macros.h"
24272343Sngie
25272343SngieATF_TC(modautoload);
26272343SngieATF_TC_HEAD(modautoload, tc)
27272343Sngie{
28272343Sngie
29272343Sngie	atf_tc_set_md_var(tc, "descr", "tests that kernel module "
30272343Sngie	    "autoload works in rump");
31272343Sngie}
32272343Sngie
33272343Sngiestatic void
34272343Sngiemountkernfs(void)
35272343Sngie{
36309466Sngie	bool old_autoload, new_autoload;
37309466Sngie	size_t old_len, new_len;
38309466Sngie	int error;
39272343Sngie
40272343Sngie	if (!rump_nativeabi_p())
41272343Sngie		atf_tc_skip("host kernel modules not supported");
42272343Sngie
43272343Sngie	rump_init();
44272343Sngie
45272343Sngie	if (rump_sys_mkdir("/kern", 0777) == -1)
46272343Sngie		atf_tc_fail_errno("mkdir /kern");
47309466Sngie
48309466Sngie	new_autoload = true;
49313680Sngie	old_len = sizeof(old_autoload);
50309466Sngie	new_len = sizeof(new_autoload);
51309466Sngie	error = sysctlbyname("kern.module.autoload",
52309466Sngie				  &old_autoload, &old_len,
53309466Sngie				  &new_autoload, new_len);
54309466Sngie	if (error != 0)
55309466Sngie		atf_tc_fail_errno("could not enable module autoload");
56309466Sngie
57272343Sngie	if (rump_sys_mount(MOUNT_KERNFS, "/kern", 0, NULL, 0) == -1)
58272343Sngie		atf_tc_fail_errno("could not mount kernfs");
59272343Sngie}
60272343Sngie
61272343Sngie/*
62272343Sngie * Why use kernfs here?  It talks to plenty of other parts with the
63272343Sngie * kernel (e.g. vfs_attach() in modcmd), but is still easy to verify
64272343Sngie * it's working correctly.
65272343Sngie */
66272343Sngie
67272343Sngie#define MAGICNUM 1323
68272343SngieATF_TC_BODY(modautoload, tc)
69272343Sngie{
70272343Sngie	extern int rumpns_hz;
71272343Sngie	char buf[64];
72272343Sngie	int fd;
73272343Sngie
74272343Sngie	mountkernfs();
75272343Sngie	rumpns_hz = MAGICNUM;
76272343Sngie	if ((fd = rump_sys_open("/kern/hz", O_RDONLY)) == -1)
77272343Sngie		atf_tc_fail_errno("open /kern/hz");
78272343Sngie	if (rump_sys_read(fd, buf, sizeof(buf)) <= 0)
79272343Sngie		atf_tc_fail_errno("read");
80272343Sngie	ATF_REQUIRE(atoi(buf) == MAGICNUM);
81272343Sngie}
82272343Sngie
83272343SngieATF_TP_ADD_TCS(tp)
84272343Sngie{
85272343Sngie	ATF_TP_ADD_TC(tp, modautoload);
86272343Sngie
87272343Sngie	return atf_no_error();
88272343Sngie}
89