xref: /netbsd-src/tests/fs/kernfs/t_basic.c (revision b62fc9e20372b08e1785ff6d769312d209fa2005)
1 /*	$NetBSD: t_basic.c,v 1.1 2010/03/31 19:14:30 pooka Exp $	*/
2 
3 #include <sys/types.h>
4 #include <sys/mount.h>
5 #include <sys/module.h>
6 #include <sys/dirent.h>
7 #include <sys/sysctl.h>
8 
9 #include <atf-c.h>
10 #include <err.h>
11 #include <errno.h>
12 #include <fcntl.h>
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <string.h>
16 #include <stdlib.h>
17 
18 #include <rump/rump.h>
19 #include <rump/rump_syscalls.h>
20 
21 #include <miscfs/kernfs/kernfs.h>
22 
23 #define USE_ATF
24 #include "../../h_macros.h"
25 
26 #ifdef USE_ATF
27 ATF_TC(getdents);
28 ATF_TC_HEAD(getdents, tc)
29 {
30 
31 	atf_tc_set_md_var(tc, "descr", "kernfs directory contains files");
32 }
33 #else
34 #define atf_tc_fail(...) errx(1, __VA_ARGS__)
35 #endif
36 
37 #ifdef MODDIR
38 /*
39  * Try to load kernfs module (only on archs where ABIs match).
40  * This is slightly ... inconvenient currently.  Let's try to improve
41  * it in the future.
42  *
43  * steps:
44  *   1) copy it into our working directory
45  *   2) rename symbols
46  *   3) lock & load
47  */
48 static int
49 loadmodule(void)
50 {
51 	modctl_load_t ml;
52 	int error;
53 
54 	if (system("cp " MODDIR MODBASE " .") == -1) {
55 		warn("failed to copy %s into pwd", MODDIR MODBASE);
56 		return errno;
57 	}
58 	if (chmod(MODBASE, 0666) == -1) {
59 		warn("chmod %s", MODBASE);
60 		return errno;
61 	}
62 	if (system("make -f /usr/src/sys/rump/Makefile.rump RUMP_SYMREN="
63 	    MODBASE) == -1) {
64 		warn("objcopy failed");
65 		return errno;
66 	}
67 
68 	if ((error = rump_pub_etfs_register(MODBASE, MODBASE, RUMP_ETFS_REG))) {
69 		warn("rump etfs");
70 		return error;
71 	}
72 
73 	memset(&ml, 0, sizeof(ml));
74 	ml.ml_filename = MODBASE;
75 	if (rump_sys_modctl(MODCTL_LOAD, &ml) == -1) {
76 		warn("module load");
77 		return errno;
78 	}
79 
80 	return 0;
81 }
82 #endif
83 
84 static void
85 mountkernfs(void)
86 {
87 
88 	rump_init();
89 
90 #ifdef MODDIR
91 	if (loadmodule() != 0) {
92 		/* failed?  fallback to dlopen() .... some day */
93 		atf_tc_fail("could not load kernfs");
94 	}
95 #endif
96 
97 	if (rump_sys_mkdir("/kern", 0777) == -1)
98 		atf_tc_fail_errno("mkdir /kern");
99 	if (rump_sys_mount(MOUNT_KERNFS, "/kern", 0, NULL, 0) == -1)
100 		atf_tc_fail_errno("could not mount kernfs");
101 }
102 
103 #ifdef USE_ATF
104 ATF_TC_BODY(getdents, tc)
105 #else
106 int main(int argc, char *argv[])
107 #endif
108 {
109 	struct dirent *dent;
110 	char buf[8192];
111 	int dfd;
112 
113 	mountkernfs();
114 
115 	if ((dfd = rump_sys_open("/kern", O_RDONLY)) == -1)
116 		atf_tc_fail_errno("can't open directory");
117 	if (rump_sys_getdents(dfd, buf, sizeof(buf)) == -1)
118 		atf_tc_fail_errno("getdents");
119 
120 	/*
121 	 * Check that we get the first three values (., .., boottime).
122 	 * Make more complete by autogenerating list from kernfs_vnops.c?
123 	 */
124 	dent = (void *)buf;
125 	ATF_REQUIRE_STREQ(dent->d_name, ".");
126 	dent = _DIRENT_NEXT(dent);
127 	ATF_REQUIRE_STREQ(dent->d_name, "..");
128 	dent = _DIRENT_NEXT(dent);
129 	ATF_REQUIRE_STREQ(dent->d_name, "boottime");
130 
131 	/* done */
132 }
133 
134 #ifdef USE_ATF
135 ATF_TC(hostname);
136 ATF_TC_HEAD(hostname, tc)
137 {
138 
139 	atf_tc_set_md_var(tc, "descr", "/kern/hostname changes hostname");
140 }
141 
142 static char *
143 getthehost(void)
144 {
145 	static char buf[8192];
146 	int mib[2];
147 	size_t blen;
148 
149 	mib[0] = CTL_KERN;
150 	mib[1] = KERN_HOSTNAME;
151 	blen = sizeof(buf);
152 	if (rump_sys___sysctl(mib, 2, buf, &blen, NULL, 0) == -1)
153 		atf_tc_fail_errno("sysctl gethostname");
154 
155 	return buf;
156 }
157 
158 #define NEWHOSTNAME "turboton roos-berg"
159 ATF_TC_BODY(hostname, tc)
160 {
161 	char buf[8192];
162 	char *shost, *p;
163 	int fd;
164 
165 	mountkernfs();
166 	if ((fd = rump_sys_open("/kern/hostname", O_RDWR)) == -1)
167 		atf_tc_fail_errno("open hostname");
168 
169 	/* check initial match */
170 	shost = getthehost();
171 	buf[0] = '\0';
172 	if (rump_sys_read(fd, buf, sizeof(buf)) == -1)
173 		atf_tc_fail_errno("read hostname");
174 	p = strchr(buf, '\n');
175 	if (p)
176 		 *p = '\0';
177 	ATF_REQUIRE_STREQ_MSG(buf, shost, "initial hostname mismatch");
178 
179 	/* check changing hostname works */
180 	if (rump_sys_pwrite(fd, NEWHOSTNAME, strlen(NEWHOSTNAME), 0)
181 	    != strlen(NEWHOSTNAME)) {
182 		atf_tc_fail_errno("write new hostname");
183 	}
184 
185 	shost = getthehost();
186 	ATF_REQUIRE_STREQ_MSG(NEWHOSTNAME, shost, "modified hostname mismatch");
187 
188 	/* done */
189 }
190 
191 ATF_TP_ADD_TCS(tp)
192 {
193 	ATF_TP_ADD_TC(tp, hostname);
194 	ATF_TP_ADD_TC(tp, getdents);
195 
196 	return atf_no_error();
197 }
198 #endif
199