Sat May 2 15:20:08 2009 UTC ()
Since rump_module_load() doesn't actually load the module, change
the name to rump_module_init().  Also, adjust the signature to take
a direct pointer to modinfo and allow passing of props.  Finally,
provide rump_module_fini().


(pooka)
diff -r1.25 -r1.26 src/lib/libukfs/ukfs.c
diff -r1.13 -r1.14 src/sys/rump/include/rump/rump.h
diff -r1.105 -r1.106 src/sys/rump/librump/rumpkern/rump.c

cvs diff -r1.25 -r1.26 src/lib/libukfs/ukfs.c (switch to unified diff)

--- src/lib/libukfs/ukfs.c 2009/05/02 01:15:52 1.25
+++ src/lib/libukfs/ukfs.c 2009/05/02 15:20:08 1.26
@@ -1,891 +1,892 @@ @@ -1,891 +1,892 @@
1/* $NetBSD: ukfs.c,v 1.25 2009/05/02 01:15:52 pooka Exp $ */ 1/* $NetBSD: ukfs.c,v 1.26 2009/05/02 15:20:08 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007, 2008 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2007, 2008 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Development of this software was supported by the 6 * Development of this software was supported by the
7 * Finnish Cultural Foundation. 7 * Finnish Cultural Foundation.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE. 28 * SUCH DAMAGE.
29 */ 29 */
30 30
31/* 31/*
32 * This library enables access to files systems directly without 32 * This library enables access to files systems directly without
33 * involving system calls. 33 * involving system calls.
34 */ 34 */
35 35
36#ifdef __linux__ 36#ifdef __linux__
37#define _XOPEN_SOURCE 500 37#define _XOPEN_SOURCE 500
38#define _BSD_SOURCE 38#define _BSD_SOURCE
39#define _FILE_OFFSET_BITS 64 39#define _FILE_OFFSET_BITS 64
40#endif 40#endif
41 41
42#include <sys/param.h> 42#include <sys/param.h>
43#include <sys/queue.h> 43#include <sys/queue.h>
44#include <sys/stat.h> 44#include <sys/stat.h>
45#include <sys/sysctl.h> 45#include <sys/sysctl.h>
46#include <sys/mount.h> 46#include <sys/mount.h>
47 47
48#include <assert.h> 48#include <assert.h>
49#include <dirent.h> 49#include <dirent.h>
50#include <dlfcn.h> 50#include <dlfcn.h>
51#include <err.h> 51#include <err.h>
52#include <errno.h> 52#include <errno.h>
53#include <fcntl.h> 53#include <fcntl.h>
54#include <pthread.h> 54#include <pthread.h>
55#include <stdio.h> 55#include <stdio.h>
56#include <stdlib.h> 56#include <stdlib.h>
57#include <string.h> 57#include <string.h>
58#include <unistd.h> 58#include <unistd.h>
59#include <stdint.h> 59#include <stdint.h>
60 60
61#include <rump/ukfs.h> 61#include <rump/ukfs.h>
62 62
63#include <rump/rump.h> 63#include <rump/rump.h>
64#include <rump/rump_syscalls.h> 64#include <rump/rump_syscalls.h>
65 65
66#define UKFS_MODE_DEFAULT 0555 66#define UKFS_MODE_DEFAULT 0555
67 67
68struct ukfs { 68struct ukfs {
69 struct mount *ukfs_mp; 69 struct mount *ukfs_mp;
70 struct vnode *ukfs_rvp; 70 struct vnode *ukfs_rvp;
71 71
72 pthread_spinlock_t ukfs_spin; 72 pthread_spinlock_t ukfs_spin;
73 pid_t ukfs_nextpid; 73 pid_t ukfs_nextpid;
74 struct vnode *ukfs_cdir; 74 struct vnode *ukfs_cdir;
75 int ukfs_devfd; 75 int ukfs_devfd;
76}; 76};
77 77
78struct mount * 78struct mount *
79ukfs_getmp(struct ukfs *ukfs) 79ukfs_getmp(struct ukfs *ukfs)
80{ 80{
81 81
82 return ukfs->ukfs_mp; 82 return ukfs->ukfs_mp;
83} 83}
84 84
85struct vnode * 85struct vnode *
86ukfs_getrvp(struct ukfs *ukfs) 86ukfs_getrvp(struct ukfs *ukfs)
87{ 87{
88 struct vnode *rvp; 88 struct vnode *rvp;
89 89
90 rvp = ukfs->ukfs_rvp; 90 rvp = ukfs->ukfs_rvp;
91 rump_vp_incref(rvp); 91 rump_vp_incref(rvp);
92 92
93 return rvp; 93 return rvp;
94} 94}
95 95
96#ifdef DONT_WANT_PTHREAD_LINKAGE 96#ifdef DONT_WANT_PTHREAD_LINKAGE
97#define pthread_spin_lock(a) 97#define pthread_spin_lock(a)
98#define pthread_spin_unlock(a) 98#define pthread_spin_unlock(a)
99#define pthread_spin_init(a,b) 99#define pthread_spin_init(a,b)
100#define pthread_spin_destroy(a) 100#define pthread_spin_destroy(a)
101#endif 101#endif
102 102
103static pid_t 103static pid_t
104nextpid(struct ukfs *ukfs) 104nextpid(struct ukfs *ukfs)
105{ 105{
106 pid_t npid; 106 pid_t npid;
107 107
108 pthread_spin_lock(&ukfs->ukfs_spin); 108 pthread_spin_lock(&ukfs->ukfs_spin);
109 if (ukfs->ukfs_nextpid == 0) 109 if (ukfs->ukfs_nextpid == 0)
110 ukfs->ukfs_nextpid++; 110 ukfs->ukfs_nextpid++;
111 npid = ukfs->ukfs_nextpid++; 111 npid = ukfs->ukfs_nextpid++;
112 pthread_spin_unlock(&ukfs->ukfs_spin); 112 pthread_spin_unlock(&ukfs->ukfs_spin);
113 113
114 return npid; 114 return npid;
115} 115}
116 116
117static void 117static void
118precall(struct ukfs *ukfs) 118precall(struct ukfs *ukfs)
119{ 119{
120 struct vnode *rvp, *cvp; 120 struct vnode *rvp, *cvp;
121 121
122 rump_setup_curlwp(nextpid(ukfs), 1, 1); 122 rump_setup_curlwp(nextpid(ukfs), 1, 1);
123 rvp = ukfs_getrvp(ukfs); 123 rvp = ukfs_getrvp(ukfs);
124 pthread_spin_lock(&ukfs->ukfs_spin); 124 pthread_spin_lock(&ukfs->ukfs_spin);
125 cvp = ukfs->ukfs_cdir; 125 cvp = ukfs->ukfs_cdir;
126 pthread_spin_unlock(&ukfs->ukfs_spin); 126 pthread_spin_unlock(&ukfs->ukfs_spin);
127 rump_rcvp_set(rvp, cvp); /* takes refs */ 127 rump_rcvp_set(rvp, cvp); /* takes refs */
128 rump_vp_rele(rvp); 128 rump_vp_rele(rvp);
129} 129}
130 130
131static void 131static void
132postcall(struct ukfs *ukfs) 132postcall(struct ukfs *ukfs)
133{ 133{
134 struct vnode *rvp; 134 struct vnode *rvp;
135 135
136 rvp = ukfs_getrvp(ukfs); 136 rvp = ukfs_getrvp(ukfs);
137 rump_rcvp_set(NULL, rvp); 137 rump_rcvp_set(NULL, rvp);
138 rump_vp_rele(rvp); 138 rump_vp_rele(rvp);
139 rump_clear_curlwp(); 139 rump_clear_curlwp();
140} 140}
141 141
142int 142int
143_ukfs_init(int version) 143_ukfs_init(int version)
144{ 144{
145 int rv; 145 int rv;
146 146
147 if (version != UKFS_VERSION) { 147 if (version != UKFS_VERSION) {
148 printf("incompatible ukfs version, %d vs. %d\n", 148 printf("incompatible ukfs version, %d vs. %d\n",
149 version, UKFS_VERSION); 149 version, UKFS_VERSION);
150 errno = EPROGMISMATCH; 150 errno = EPROGMISMATCH;
151 return -1; 151 return -1;
152 } 152 }
153 153
154 if ((rv = rump_init()) != 0) { 154 if ((rv = rump_init()) != 0) {
155 errno = rv; 155 errno = rv;
156 return -1; 156 return -1;
157 } 157 }
158 158
159 return 0; 159 return 0;
160} 160}
161 161
162struct ukfs * 162struct ukfs *
163ukfs_mount(const char *vfsname, const char *devpath, const char *mountpath, 163ukfs_mount(const char *vfsname, const char *devpath, const char *mountpath,
164 int mntflags, void *arg, size_t alen) 164 int mntflags, void *arg, size_t alen)
165{ 165{
166 struct stat sb; 166 struct stat sb;
167 struct ukfs *fs = NULL; 167 struct ukfs *fs = NULL;
168 struct vfsops *vfsops; 168 struct vfsops *vfsops;
169 struct mount *mp = NULL; 169 struct mount *mp = NULL;
170 int rv = 0, devfd = -1, rdonly; 170 int rv = 0, devfd = -1, rdonly;
171 171
172 vfsops = rump_vfs_getopsbyname(vfsname); 172 vfsops = rump_vfs_getopsbyname(vfsname);
173 if (vfsops == NULL) { 173 if (vfsops == NULL) {
174 rv = ENODEV; 174 rv = ENODEV;
175 goto out; 175 goto out;
176 } 176 }
177 177
178 /* 178 /*
179 * Try open and lock the device. if we can't open it, assume 179 * Try open and lock the device. if we can't open it, assume
180 * it's a file system which doesn't use a real device and let 180 * it's a file system which doesn't use a real device and let
181 * it slide. The mount will fail anyway if the fs requires a 181 * it slide. The mount will fail anyway if the fs requires a
182 * device. 182 * device.
183 * 183 *
184 * XXX: strictly speaking this is not 100% correct, as virtual 184 * XXX: strictly speaking this is not 100% correct, as virtual
185 * file systems can use a device path which does exist and can 185 * file systems can use a device path which does exist and can
186 * be opened. E.g. tmpfs should be mountable multiple times 186 * be opened. E.g. tmpfs should be mountable multiple times
187 * with "device" path "/swap", but now isn't. But I think the 187 * with "device" path "/swap", but now isn't. But I think the
188 * chances are so low that it's currently acceptable to let 188 * chances are so low that it's currently acceptable to let
189 * this one slip. 189 * this one slip.
190 */ 190 */
191 rdonly = mntflags & MNT_RDONLY; 191 rdonly = mntflags & MNT_RDONLY;
192 devfd = open(devpath, rdonly ? O_RDONLY : O_RDWR); 192 devfd = open(devpath, rdonly ? O_RDONLY : O_RDWR);
193 if (devfd != -1) { 193 if (devfd != -1) {
194 if (fstat(devfd, &sb) == -1) { 194 if (fstat(devfd, &sb) == -1) {
195 close(devfd); 195 close(devfd);
196 devfd = -1; 196 devfd = -1;
197 rv = errno; 197 rv = errno;
198 goto out; 198 goto out;
199 } 199 }
200 200
201 /* 201 /*
202 * We do this only for non-block device since the 202 * We do this only for non-block device since the
203 * (NetBSD) kernel allows block device open only once. 203 * (NetBSD) kernel allows block device open only once.
204 */ 204 */
205 if (!S_ISBLK(sb.st_mode)) { 205 if (!S_ISBLK(sb.st_mode)) {
206 if (flock(devfd, LOCK_NB | (rdonly ? LOCK_SH:LOCK_EX)) 206 if (flock(devfd, LOCK_NB | (rdonly ? LOCK_SH:LOCK_EX))
207 == -1) { 207 == -1) {
208 warnx("ukfs_mount: cannot get %s lock on " 208 warnx("ukfs_mount: cannot get %s lock on "
209 "device", rdonly ? "shared" : "exclusive"); 209 "device", rdonly ? "shared" : "exclusive");
210 close(devfd); 210 close(devfd);
211 devfd = -1; 211 devfd = -1;
212 rv = errno; 212 rv = errno;
213 goto out; 213 goto out;
214 } 214 }
215 } else { 215 } else {
216 close(devfd); 216 close(devfd);
217 devfd = -1; 217 devfd = -1;
218 } 218 }
219 } 219 }
220 220
221 fs = malloc(sizeof(struct ukfs)); 221 fs = malloc(sizeof(struct ukfs));
222 if (fs == NULL) { 222 if (fs == NULL) {
223 rv = ENOMEM; 223 rv = ENOMEM;
224 goto out; 224 goto out;
225 } 225 }
226 memset(fs, 0, sizeof(struct ukfs)); 226 memset(fs, 0, sizeof(struct ukfs));
227 mp = rump_mnt_init(vfsops, mntflags); 227 mp = rump_mnt_init(vfsops, mntflags);
228 228
229 rump_fakeblk_register(devpath); 229 rump_fakeblk_register(devpath);
230 rv = rump_mnt_mount(mp, mountpath, arg, &alen); 230 rv = rump_mnt_mount(mp, mountpath, arg, &alen);
231 rump_fakeblk_deregister(devpath); 231 rump_fakeblk_deregister(devpath);
232 if (rv) { 232 if (rv) {
233 goto out; 233 goto out;
234 } 234 }
235 rv = rump_vfs_root(mp, &fs->ukfs_rvp, 0); 235 rv = rump_vfs_root(mp, &fs->ukfs_rvp, 0);
236 if (rv) { 236 if (rv) {
237 goto out; 237 goto out;
238 } 238 }
239 fs->ukfs_cdir = ukfs_getrvp(fs); 239 fs->ukfs_cdir = ukfs_getrvp(fs);
240 240
241 fs->ukfs_mp = mp; 241 fs->ukfs_mp = mp;
242 pthread_spin_init(&fs->ukfs_spin, PTHREAD_PROCESS_SHARED); 242 pthread_spin_init(&fs->ukfs_spin, PTHREAD_PROCESS_SHARED);
243 fs->ukfs_devfd = devfd; 243 fs->ukfs_devfd = devfd;
244 assert(rv == 0); 244 assert(rv == 0);
245 245
246 out: 246 out:
247 if (rv) { 247 if (rv) {
248 if (mp) 248 if (mp)
249 rump_mnt_destroy(mp); 249 rump_mnt_destroy(mp);
250 if (fs) 250 if (fs)
251 free(fs); 251 free(fs);
252 errno = rv; 252 errno = rv;
253 fs = NULL; 253 fs = NULL;
254 if (devfd != -1) { 254 if (devfd != -1) {
255 flock(devfd, LOCK_UN); 255 flock(devfd, LOCK_UN);
256 close(devfd); 256 close(devfd);
257 } 257 }
258 } 258 }
259 259
260 return fs; 260 return fs;
261} 261}
262 262
263void 263void
264ukfs_release(struct ukfs *fs, int flags) 264ukfs_release(struct ukfs *fs, int flags)
265{ 265{
266 int rv; 266 int rv;
267 267
268 if ((flags & UKFS_RELFLAG_NOUNMOUNT) == 0) { 268 if ((flags & UKFS_RELFLAG_NOUNMOUNT) == 0) {
269 kauth_cred_t cred; 269 kauth_cred_t cred;
270 270
271 rump_vp_rele(fs->ukfs_cdir); 271 rump_vp_rele(fs->ukfs_cdir);
272 rump_vp_rele(fs->ukfs_rvp); 272 rump_vp_rele(fs->ukfs_rvp);
273 cred = rump_cred_suserget(); 273 cred = rump_cred_suserget();
274 rv = rump_vfs_sync(fs->ukfs_mp, 1, cred); 274 rv = rump_vfs_sync(fs->ukfs_mp, 1, cred);
275 rump_cred_suserput(cred); 275 rump_cred_suserput(cred);
276 rump_vp_recycle_nokidding(ukfs_getrvp(fs)); 276 rump_vp_recycle_nokidding(ukfs_getrvp(fs));
277 rv |= rump_vfs_unmount(fs->ukfs_mp, 0); 277 rv |= rump_vfs_unmount(fs->ukfs_mp, 0);
278 assert(rv == 0); 278 assert(rv == 0);
279 } 279 }
280 280
281 rump_vfs_syncwait(fs->ukfs_mp); 281 rump_vfs_syncwait(fs->ukfs_mp);
282 rump_mnt_destroy(fs->ukfs_mp); 282 rump_mnt_destroy(fs->ukfs_mp);
283 283
284 pthread_spin_destroy(&fs->ukfs_spin); 284 pthread_spin_destroy(&fs->ukfs_spin);
285 if (fs->ukfs_devfd != -1) { 285 if (fs->ukfs_devfd != -1) {
286 flock(fs->ukfs_devfd, LOCK_UN); 286 flock(fs->ukfs_devfd, LOCK_UN);
287 close(fs->ukfs_devfd); 287 close(fs->ukfs_devfd);
288 } 288 }
289 free(fs); 289 free(fs);
290} 290}
291 291
292#define STDCALL(ukfs, thecall) \ 292#define STDCALL(ukfs, thecall) \
293 int rv = 0; \ 293 int rv = 0; \
294 \ 294 \
295 precall(ukfs); \ 295 precall(ukfs); \
296 rv = thecall; \ 296 rv = thecall; \
297 postcall(ukfs); \ 297 postcall(ukfs); \
298 return rv; 298 return rv;
299 299
300int 300int
301ukfs_opendir(struct ukfs *ukfs, const char *dirname, struct ukfs_dircookie **c) 301ukfs_opendir(struct ukfs *ukfs, const char *dirname, struct ukfs_dircookie **c)
302{ 302{
303 struct vnode *vp; 303 struct vnode *vp;
304 int rv; 304 int rv;
305 305
306 precall(ukfs); 306 precall(ukfs);
307 rv = rump_namei(RUMP_NAMEI_LOOKUP, RUMP_NAMEI_LOCKLEAF, dirname, 307 rv = rump_namei(RUMP_NAMEI_LOOKUP, RUMP_NAMEI_LOCKLEAF, dirname,
308 NULL, &vp, NULL); 308 NULL, &vp, NULL);
309 postcall(ukfs); 309 postcall(ukfs);
310 310
311 if (rv == 0) { 311 if (rv == 0) {
312 RUMP_VOP_UNLOCK(vp, 0); 312 RUMP_VOP_UNLOCK(vp, 0);
313 } else { 313 } else {
314 errno = rv; 314 errno = rv;
315 rv = -1; 315 rv = -1;
316 } 316 }
317 317
318 /*LINTED*/ 318 /*LINTED*/
319 *c = (struct ukfs_dircookie *)vp; 319 *c = (struct ukfs_dircookie *)vp;
320 return rv; 320 return rv;
321} 321}
322 322
323static int 323static int
324getmydents(struct vnode *vp, off_t *off, uint8_t *buf, size_t bufsize) 324getmydents(struct vnode *vp, off_t *off, uint8_t *buf, size_t bufsize)
325{ 325{
326 struct uio *uio; 326 struct uio *uio;
327 size_t resid; 327 size_t resid;
328 int rv, eofflag; 328 int rv, eofflag;
329 kauth_cred_t cred; 329 kauth_cred_t cred;
330  330
331 uio = rump_uio_setup(buf, bufsize, *off, RUMPUIO_READ); 331 uio = rump_uio_setup(buf, bufsize, *off, RUMPUIO_READ);
332 cred = rump_cred_suserget(); 332 cred = rump_cred_suserget();
333 rv = RUMP_VOP_READDIR(vp, uio, cred, &eofflag, NULL, NULL); 333 rv = RUMP_VOP_READDIR(vp, uio, cred, &eofflag, NULL, NULL);
334 rump_cred_suserput(cred); 334 rump_cred_suserput(cred);
335 RUMP_VOP_UNLOCK(vp, 0); 335 RUMP_VOP_UNLOCK(vp, 0);
336 *off = rump_uio_getoff(uio); 336 *off = rump_uio_getoff(uio);
337 resid = rump_uio_free(uio); 337 resid = rump_uio_free(uio);
338 338
339 if (rv) { 339 if (rv) {
340 errno = rv; 340 errno = rv;
341 return -1; 341 return -1;
342 } 342 }
343 343
344 /* LINTED: not totally correct return type, but follows syscall */ 344 /* LINTED: not totally correct return type, but follows syscall */
345 return bufsize - resid; 345 return bufsize - resid;
346} 346}
347 347
348/*ARGSUSED*/ 348/*ARGSUSED*/
349int 349int
350ukfs_getdents_cookie(struct ukfs *ukfs, struct ukfs_dircookie *c, off_t *off, 350ukfs_getdents_cookie(struct ukfs *ukfs, struct ukfs_dircookie *c, off_t *off,
351 uint8_t *buf, size_t bufsize) 351 uint8_t *buf, size_t bufsize)
352{ 352{
353 /*LINTED*/ 353 /*LINTED*/
354 struct vnode *vp = (struct vnode *)c; 354 struct vnode *vp = (struct vnode *)c;
355 355
356 RUMP_VOP_LOCK(vp, RUMP_LK_SHARED); 356 RUMP_VOP_LOCK(vp, RUMP_LK_SHARED);
357 return getmydents(vp, off, buf, bufsize); 357 return getmydents(vp, off, buf, bufsize);
358} 358}
359 359
360int 360int
361ukfs_getdents(struct ukfs *ukfs, const char *dirname, off_t *off, 361ukfs_getdents(struct ukfs *ukfs, const char *dirname, off_t *off,
362 uint8_t *buf, size_t bufsize) 362 uint8_t *buf, size_t bufsize)
363{ 363{
364 struct vnode *vp; 364 struct vnode *vp;
365 int rv; 365 int rv;
366 366
367 precall(ukfs); 367 precall(ukfs);
368 rv = rump_namei(RUMP_NAMEI_LOOKUP, RUMP_NAMEI_LOCKLEAF, dirname, 368 rv = rump_namei(RUMP_NAMEI_LOOKUP, RUMP_NAMEI_LOCKLEAF, dirname,
369 NULL, &vp, NULL); 369 NULL, &vp, NULL);
370 postcall(ukfs); 370 postcall(ukfs);
371 if (rv) { 371 if (rv) {
372 errno = rv; 372 errno = rv;
373 return -1; 373 return -1;
374 } 374 }
375 375
376 rv = getmydents(vp, off, buf, bufsize); 376 rv = getmydents(vp, off, buf, bufsize);
377 rump_vp_rele(vp); 377 rump_vp_rele(vp);
378 return rv; 378 return rv;
379} 379}
380 380
381/*ARGSUSED*/ 381/*ARGSUSED*/
382int 382int
383ukfs_closedir(struct ukfs *ukfs, struct ukfs_dircookie *c) 383ukfs_closedir(struct ukfs *ukfs, struct ukfs_dircookie *c)
384{ 384{
385 385
386 /*LINTED*/ 386 /*LINTED*/
387 rump_vp_rele((struct vnode *)c); 387 rump_vp_rele((struct vnode *)c);
388 return 0; 388 return 0;
389} 389}
390 390
391int 391int
392ukfs_open(struct ukfs *ukfs, const char *filename, int flags) 392ukfs_open(struct ukfs *ukfs, const char *filename, int flags)
393{ 393{
394 int fd; 394 int fd;
395 395
396 precall(ukfs); 396 precall(ukfs);
397 fd = rump_sys_open(filename, flags, 0); 397 fd = rump_sys_open(filename, flags, 0);
398 postcall(ukfs); 398 postcall(ukfs);
399 if (fd == -1) 399 if (fd == -1)
400 return -1; 400 return -1;
401 401
402 return fd; 402 return fd;
403} 403}
404 404
405ssize_t 405ssize_t
406ukfs_read(struct ukfs *ukfs, const char *filename, off_t off, 406ukfs_read(struct ukfs *ukfs, const char *filename, off_t off,
407 uint8_t *buf, size_t bufsize) 407 uint8_t *buf, size_t bufsize)
408{ 408{
409 int fd; 409 int fd;
410 ssize_t xfer = -1; /* XXXgcc */ 410 ssize_t xfer = -1; /* XXXgcc */
411 411
412 precall(ukfs); 412 precall(ukfs);
413 fd = rump_sys_open(filename, RUMP_O_RDONLY, 0); 413 fd = rump_sys_open(filename, RUMP_O_RDONLY, 0);
414 if (fd == -1) 414 if (fd == -1)
415 goto out; 415 goto out;
416 416
417 xfer = rump_sys_pread(fd, buf, bufsize, 0, off); 417 xfer = rump_sys_pread(fd, buf, bufsize, 0, off);
418 rump_sys_close(fd); 418 rump_sys_close(fd);
419 419
420 out: 420 out:
421 postcall(ukfs); 421 postcall(ukfs);
422 if (fd == -1) { 422 if (fd == -1) {
423 return -1; 423 return -1;
424 } 424 }
425 return xfer; 425 return xfer;
426} 426}
427 427
428/*ARGSUSED*/ 428/*ARGSUSED*/
429ssize_t 429ssize_t
430ukfs_read_fd(struct ukfs *ukfs, int fd, off_t off, uint8_t *buf, size_t buflen) 430ukfs_read_fd(struct ukfs *ukfs, int fd, off_t off, uint8_t *buf, size_t buflen)
431{ 431{
432 432
433 return rump_sys_pread(fd, buf, buflen, 0, off); 433 return rump_sys_pread(fd, buf, buflen, 0, off);
434} 434}
435 435
436ssize_t 436ssize_t
437ukfs_write(struct ukfs *ukfs, const char *filename, off_t off, 437ukfs_write(struct ukfs *ukfs, const char *filename, off_t off,
438 uint8_t *buf, size_t bufsize) 438 uint8_t *buf, size_t bufsize)
439{ 439{
440 int fd; 440 int fd;
441 ssize_t xfer = -1; /* XXXgcc */ 441 ssize_t xfer = -1; /* XXXgcc */
442 442
443 precall(ukfs); 443 precall(ukfs);
444 fd = rump_sys_open(filename, RUMP_O_WRONLY, 0); 444 fd = rump_sys_open(filename, RUMP_O_WRONLY, 0);
445 if (fd == -1) 445 if (fd == -1)
446 goto out; 446 goto out;
447 447
448 /* write and commit */ 448 /* write and commit */
449 xfer = rump_sys_pwrite(fd, buf, bufsize, 0, off); 449 xfer = rump_sys_pwrite(fd, buf, bufsize, 0, off);
450 if (xfer > 0) 450 if (xfer > 0)
451 rump_sys_fsync(fd); 451 rump_sys_fsync(fd);
452 452
453 rump_sys_close(fd); 453 rump_sys_close(fd);
454 454
455 out: 455 out:
456 postcall(ukfs); 456 postcall(ukfs);
457 if (fd == -1) { 457 if (fd == -1) {
458 return -1; 458 return -1;
459 } 459 }
460 return xfer; 460 return xfer;
461} 461}
462 462
463/*ARGSUSED*/ 463/*ARGSUSED*/
464ssize_t 464ssize_t
465ukfs_write_fd(struct ukfs *ukfs, int fd, off_t off, uint8_t *buf, size_t buflen, 465ukfs_write_fd(struct ukfs *ukfs, int fd, off_t off, uint8_t *buf, size_t buflen,
466 int dosync) 466 int dosync)
467{ 467{
468 ssize_t xfer; 468 ssize_t xfer;
469 469
470 xfer = rump_sys_pwrite(fd, buf, buflen, 0, off); 470 xfer = rump_sys_pwrite(fd, buf, buflen, 0, off);
471 if (xfer > 0 && dosync) 471 if (xfer > 0 && dosync)
472 rump_sys_fsync(fd); 472 rump_sys_fsync(fd);
473 473
474 return xfer; 474 return xfer;
475} 475}
476 476
477/*ARGSUSED*/ 477/*ARGSUSED*/
478int 478int
479ukfs_close(struct ukfs *ukfs, int fd) 479ukfs_close(struct ukfs *ukfs, int fd)
480{ 480{
481 481
482 rump_sys_close(fd); 482 rump_sys_close(fd);
483 return 0; 483 return 0;
484} 484}
485 485
486int 486int
487ukfs_create(struct ukfs *ukfs, const char *filename, mode_t mode) 487ukfs_create(struct ukfs *ukfs, const char *filename, mode_t mode)
488{ 488{
489 int fd; 489 int fd;
490 490
491 precall(ukfs); 491 precall(ukfs);
492 fd = rump_sys_open(filename, RUMP_O_WRONLY | RUMP_O_CREAT, mode); 492 fd = rump_sys_open(filename, RUMP_O_WRONLY | RUMP_O_CREAT, mode);
493 if (fd == -1) 493 if (fd == -1)
494 return -1; 494 return -1;
495 rump_sys_close(fd); 495 rump_sys_close(fd);
496 496
497 postcall(ukfs); 497 postcall(ukfs);
498 return 0; 498 return 0;
499} 499}
500 500
501int 501int
502ukfs_mknod(struct ukfs *ukfs, const char *path, mode_t mode, dev_t dev) 502ukfs_mknod(struct ukfs *ukfs, const char *path, mode_t mode, dev_t dev)
503{ 503{
504 504
505 STDCALL(ukfs, rump_sys_mknod(path, mode, dev)); 505 STDCALL(ukfs, rump_sys_mknod(path, mode, dev));
506} 506}
507 507
508int 508int
509ukfs_mkfifo(struct ukfs *ukfs, const char *path, mode_t mode) 509ukfs_mkfifo(struct ukfs *ukfs, const char *path, mode_t mode)
510{ 510{
511 511
512 STDCALL(ukfs, rump_sys_mkfifo(path, mode)); 512 STDCALL(ukfs, rump_sys_mkfifo(path, mode));
513} 513}
514 514
515int 515int
516ukfs_mkdir(struct ukfs *ukfs, const char *filename, mode_t mode) 516ukfs_mkdir(struct ukfs *ukfs, const char *filename, mode_t mode)
517{ 517{
518 518
519 STDCALL(ukfs, rump_sys_mkdir(filename, mode)); 519 STDCALL(ukfs, rump_sys_mkdir(filename, mode));
520} 520}
521 521
522int 522int
523ukfs_remove(struct ukfs *ukfs, const char *filename) 523ukfs_remove(struct ukfs *ukfs, const char *filename)
524{ 524{
525 525
526 STDCALL(ukfs, rump_sys_unlink(filename)); 526 STDCALL(ukfs, rump_sys_unlink(filename));
527} 527}
528 528
529int 529int
530ukfs_rmdir(struct ukfs *ukfs, const char *filename) 530ukfs_rmdir(struct ukfs *ukfs, const char *filename)
531{ 531{
532 532
533 STDCALL(ukfs, rump_sys_rmdir(filename)); 533 STDCALL(ukfs, rump_sys_rmdir(filename));
534} 534}
535 535
536int 536int
537ukfs_link(struct ukfs *ukfs, const char *filename, const char *f_create) 537ukfs_link(struct ukfs *ukfs, const char *filename, const char *f_create)
538{ 538{
539 539
540 STDCALL(ukfs, rump_sys_link(filename, f_create)); 540 STDCALL(ukfs, rump_sys_link(filename, f_create));
541} 541}
542 542
543int 543int
544ukfs_symlink(struct ukfs *ukfs, const char *filename, const char *linkname) 544ukfs_symlink(struct ukfs *ukfs, const char *filename, const char *linkname)
545{ 545{
546 546
547 STDCALL(ukfs, rump_sys_symlink(filename, linkname)); 547 STDCALL(ukfs, rump_sys_symlink(filename, linkname));
548} 548}
549 549
550ssize_t 550ssize_t
551ukfs_readlink(struct ukfs *ukfs, const char *filename, 551ukfs_readlink(struct ukfs *ukfs, const char *filename,
552 char *linkbuf, size_t buflen) 552 char *linkbuf, size_t buflen)
553{ 553{
554 ssize_t rv; 554 ssize_t rv;
555 555
556 precall(ukfs); 556 precall(ukfs);
557 rv = rump_sys_readlink(filename, linkbuf, buflen); 557 rv = rump_sys_readlink(filename, linkbuf, buflen);
558 postcall(ukfs); 558 postcall(ukfs);
559 return rv; 559 return rv;
560} 560}
561 561
562int 562int
563ukfs_rename(struct ukfs *ukfs, const char *from, const char *to) 563ukfs_rename(struct ukfs *ukfs, const char *from, const char *to)
564{ 564{
565 565
566 STDCALL(ukfs, rump_sys_rename(from, to)); 566 STDCALL(ukfs, rump_sys_rename(from, to));
567} 567}
568 568
569int 569int
570ukfs_chdir(struct ukfs *ukfs, const char *path) 570ukfs_chdir(struct ukfs *ukfs, const char *path)
571{ 571{
572 struct vnode *newvp, *oldvp; 572 struct vnode *newvp, *oldvp;
573 int rv; 573 int rv;
574 574
575 precall(ukfs); 575 precall(ukfs);
576 rv = rump_sys_chdir(path); 576 rv = rump_sys_chdir(path);
577 if (rv == -1) 577 if (rv == -1)
578 goto out; 578 goto out;
579 579
580 newvp = rump_cdir_get(); 580 newvp = rump_cdir_get();
581 pthread_spin_lock(&ukfs->ukfs_spin); 581 pthread_spin_lock(&ukfs->ukfs_spin);
582 oldvp = ukfs->ukfs_cdir; 582 oldvp = ukfs->ukfs_cdir;
583 ukfs->ukfs_cdir = newvp; 583 ukfs->ukfs_cdir = newvp;
584 pthread_spin_unlock(&ukfs->ukfs_spin); 584 pthread_spin_unlock(&ukfs->ukfs_spin);
585 if (oldvp) 585 if (oldvp)
586 rump_vp_rele(oldvp); 586 rump_vp_rele(oldvp);
587 587
588 out: 588 out:
589 postcall(ukfs); 589 postcall(ukfs);
590 return rv; 590 return rv;
591} 591}
592 592
593int 593int
594ukfs_stat(struct ukfs *ukfs, const char *filename, struct stat *file_stat) 594ukfs_stat(struct ukfs *ukfs, const char *filename, struct stat *file_stat)
595{ 595{
596 596
597 STDCALL(ukfs, rump_sys_stat(filename, file_stat)); 597 STDCALL(ukfs, rump_sys_stat(filename, file_stat));
598} 598}
599 599
600int 600int
601ukfs_lstat(struct ukfs *ukfs, const char *filename, struct stat *file_stat) 601ukfs_lstat(struct ukfs *ukfs, const char *filename, struct stat *file_stat)
602{ 602{
603 603
604 STDCALL(ukfs, rump_sys_lstat(filename, file_stat)); 604 STDCALL(ukfs, rump_sys_lstat(filename, file_stat));
605} 605}
606 606
607int 607int
608ukfs_chmod(struct ukfs *ukfs, const char *filename, mode_t mode) 608ukfs_chmod(struct ukfs *ukfs, const char *filename, mode_t mode)
609{ 609{
610 610
611 STDCALL(ukfs, rump_sys_chmod(filename, mode)); 611 STDCALL(ukfs, rump_sys_chmod(filename, mode));
612} 612}
613 613
614int 614int
615ukfs_lchmod(struct ukfs *ukfs, const char *filename, mode_t mode) 615ukfs_lchmod(struct ukfs *ukfs, const char *filename, mode_t mode)
616{ 616{
617 617
618 STDCALL(ukfs, rump_sys_lchmod(filename, mode)); 618 STDCALL(ukfs, rump_sys_lchmod(filename, mode));
619} 619}
620 620
621int 621int
622ukfs_chown(struct ukfs *ukfs, const char *filename, uid_t uid, gid_t gid) 622ukfs_chown(struct ukfs *ukfs, const char *filename, uid_t uid, gid_t gid)
623{ 623{
624 624
625 STDCALL(ukfs, rump_sys_chown(filename, uid, gid)); 625 STDCALL(ukfs, rump_sys_chown(filename, uid, gid));
626} 626}
627 627
628int 628int
629ukfs_lchown(struct ukfs *ukfs, const char *filename, uid_t uid, gid_t gid) 629ukfs_lchown(struct ukfs *ukfs, const char *filename, uid_t uid, gid_t gid)
630{ 630{
631 631
632 STDCALL(ukfs, rump_sys_lchown(filename, uid, gid)); 632 STDCALL(ukfs, rump_sys_lchown(filename, uid, gid));
633} 633}
634 634
635int 635int
636ukfs_chflags(struct ukfs *ukfs, const char *filename, u_long flags) 636ukfs_chflags(struct ukfs *ukfs, const char *filename, u_long flags)
637{ 637{
638 638
639 STDCALL(ukfs, rump_sys_chflags(filename, flags)); 639 STDCALL(ukfs, rump_sys_chflags(filename, flags));
640} 640}
641 641
642int 642int
643ukfs_lchflags(struct ukfs *ukfs, const char *filename, u_long flags) 643ukfs_lchflags(struct ukfs *ukfs, const char *filename, u_long flags)
644{ 644{
645 645
646 STDCALL(ukfs, rump_sys_lchflags(filename, flags)); 646 STDCALL(ukfs, rump_sys_lchflags(filename, flags));
647} 647}
648 648
649int 649int
650ukfs_utimes(struct ukfs *ukfs, const char *filename, const struct timeval *tptr) 650ukfs_utimes(struct ukfs *ukfs, const char *filename, const struct timeval *tptr)
651{ 651{
652 652
653 STDCALL(ukfs, rump_sys_utimes(filename, tptr)); 653 STDCALL(ukfs, rump_sys_utimes(filename, tptr));
654} 654}
655 655
656int 656int
657ukfs_lutimes(struct ukfs *ukfs, const char *filename,  657ukfs_lutimes(struct ukfs *ukfs, const char *filename,
658 const struct timeval *tptr) 658 const struct timeval *tptr)
659{ 659{
660 660
661 STDCALL(ukfs, rump_sys_lutimes(filename, tptr)); 661 STDCALL(ukfs, rump_sys_lutimes(filename, tptr));
662} 662}
663 663
664/* 664/*
665 * Dynamic module support 665 * Dynamic module support
666 */ 666 */
667 667
668/* load one library */ 668/* load one library */
669 669
670/* 670/*
671 * XXX: the dlerror stuff isn't really threadsafe, but then again I 671 * XXX: the dlerror stuff isn't really threadsafe, but then again I
672 * can't protect against other threads calling dl*() outside of ukfs, 672 * can't protect against other threads calling dl*() outside of ukfs,
673 * so just live with it being flimsy 673 * so just live with it being flimsy
674 */ 674 */
675int 675int
676ukfs_modload(const char *fname) 676ukfs_modload(const char *fname)
677{ 677{
678 void *handle, *thesym; 678 void *handle;
 679 struct modinfo **mi;
679 struct stat sb; 680 struct stat sb;
680 int error; 681 int error;
681 682
682 if (stat(fname, &sb) == -1) 683 if (stat(fname, &sb) == -1)
683 return -1; 684 return -1;
684 685
685 handle = dlopen(fname, RTLD_GLOBAL); 686 handle = dlopen(fname, RTLD_GLOBAL);
686 if (handle == NULL) { 687 if (handle == NULL) {
687 const char *dlmsg = dlerror(); 688 const char *dlmsg = dlerror();
688 if (strstr(dlmsg, "Undefined symbol")) 689 if (strstr(dlmsg, "Undefined symbol"))
689 return 0; 690 return 0;
690 warnx("dlopen %s failed: %s\n", fname, dlmsg); 691 warnx("dlopen %s failed: %s\n", fname, dlmsg);
691 /* XXXerrno */ 692 /* XXXerrno */
692 return -1; 693 return -1;
693 } 694 }
694 695
695 thesym = dlsym(handle, "__start_link_set_modules"); 696 mi = dlsym(handle, "__start_link_set_modules");
696 if (thesym) { 697 if (mi) {
697 error = rump_module_load(thesym); 698 error = rump_module_init(*mi, NULL);
698 if (error) 699 if (error)
699 goto errclose; 700 goto errclose;
700 return 1; 701 return 1;
701 } 702 }
702 error = EINVAL; 703 error = EINVAL;
703 704
704 errclose: 705 errclose:
705 dlclose(handle); 706 dlclose(handle);
706 errno = error; 707 errno = error;
707 return -1; 708 return -1;
708} 709}
709 710
710struct loadfail { 711struct loadfail {
711 char *pname; 712 char *pname;
712 713
713 LIST_ENTRY(loadfail) entries; 714 LIST_ENTRY(loadfail) entries;
714}; 715};
715 716
716#define RUMPFSMOD_PREFIX "librumpfs_" 717#define RUMPFSMOD_PREFIX "librumpfs_"
717#define RUMPFSMOD_SUFFIX ".so" 718#define RUMPFSMOD_SUFFIX ".so"
718 719
719int 720int
720ukfs_modload_dir(const char *dir) 721ukfs_modload_dir(const char *dir)
721{ 722{
722 char nbuf[MAXPATHLEN+1], *p; 723 char nbuf[MAXPATHLEN+1], *p;
723 struct dirent entry, *result; 724 struct dirent entry, *result;
724 DIR *libdir; 725 DIR *libdir;
725 struct loadfail *lf, *nlf; 726 struct loadfail *lf, *nlf;
726 int error, nloaded = 0, redo; 727 int error, nloaded = 0, redo;
727 LIST_HEAD(, loadfail) lfs; 728 LIST_HEAD(, loadfail) lfs;
728 729
729 libdir = opendir(dir); 730 libdir = opendir(dir);
730 if (libdir == NULL) 731 if (libdir == NULL)
731 return -1; 732 return -1;
732 733
733 LIST_INIT(&lfs); 734 LIST_INIT(&lfs);
734 for (;;) { 735 for (;;) {
735 if ((error = readdir_r(libdir, &entry, &result)) != 0) 736 if ((error = readdir_r(libdir, &entry, &result)) != 0)
736 break; 737 break;
737 if (!result) 738 if (!result)
738 break; 739 break;
739 if (strncmp(result->d_name, RUMPFSMOD_PREFIX, 740 if (strncmp(result->d_name, RUMPFSMOD_PREFIX,
740 strlen(RUMPFSMOD_PREFIX)) != 0) 741 strlen(RUMPFSMOD_PREFIX)) != 0)
741 continue; 742 continue;
742 if (((p = strstr(result->d_name, RUMPFSMOD_SUFFIX)) == NULL) 743 if (((p = strstr(result->d_name, RUMPFSMOD_SUFFIX)) == NULL)
743 || strlen(p) != strlen(RUMPFSMOD_SUFFIX)) 744 || strlen(p) != strlen(RUMPFSMOD_SUFFIX))
744 continue; 745 continue;
745 strlcpy(nbuf, dir, sizeof(nbuf)); 746 strlcpy(nbuf, dir, sizeof(nbuf));
746 strlcat(nbuf, "/", sizeof(nbuf)); 747 strlcat(nbuf, "/", sizeof(nbuf));
747 strlcat(nbuf, result->d_name, sizeof(nbuf)); 748 strlcat(nbuf, result->d_name, sizeof(nbuf));
748 switch (ukfs_modload(nbuf)) { 749 switch (ukfs_modload(nbuf)) {
749 case 0: 750 case 0:
750 lf = malloc(sizeof(*lf)); 751 lf = malloc(sizeof(*lf));
751 if (lf == NULL) { 752 if (lf == NULL) {
752 error = ENOMEM; 753 error = ENOMEM;
753 break; 754 break;
754 } 755 }
755 lf->pname = strdup(nbuf); 756 lf->pname = strdup(nbuf);
756 if (lf->pname == NULL) { 757 if (lf->pname == NULL) {
757 free(lf); 758 free(lf);
758 error = ENOMEM; 759 error = ENOMEM;
759 break; 760 break;
760 } 761 }
761 LIST_INSERT_HEAD(&lfs, lf, entries); 762 LIST_INSERT_HEAD(&lfs, lf, entries);
762 break; 763 break;
763 case 1: 764 case 1:
764 nloaded++; 765 nloaded++;
765 break; 766 break;
766 default: 767 default:
767 /* ignore errors */ 768 /* ignore errors */
768 break; 769 break;
769 } 770 }
770 } 771 }
771 closedir(libdir); 772 closedir(libdir);
772 if (error && nloaded != 0) 773 if (error && nloaded != 0)
773 error = 0; 774 error = 0;
774 775
775 /* 776 /*
776 * El-cheapo dependency calculator. Just try to load the 777 * El-cheapo dependency calculator. Just try to load the
777 * modules n times in a loop 778 * modules n times in a loop
778 */ 779 */
779 for (redo = 1; redo;) { 780 for (redo = 1; redo;) {
780 redo = 0; 781 redo = 0;
781 nlf = LIST_FIRST(&lfs); 782 nlf = LIST_FIRST(&lfs);
782 while ((lf = nlf) != NULL) { 783 while ((lf = nlf) != NULL) {
783 nlf = LIST_NEXT(lf, entries); 784 nlf = LIST_NEXT(lf, entries);
784 if (ukfs_modload(lf->pname) == 1) { 785 if (ukfs_modload(lf->pname) == 1) {
785 nloaded++; 786 nloaded++;
786 redo = 1; 787 redo = 1;
787 LIST_REMOVE(lf, entries); 788 LIST_REMOVE(lf, entries);
788 free(lf->pname); 789 free(lf->pname);
789 free(lf); 790 free(lf);
790 } 791 }
791 } 792 }
792 } 793 }
793 794
794 while ((lf = LIST_FIRST(&lfs)) != NULL) { 795 while ((lf = LIST_FIRST(&lfs)) != NULL) {
795 LIST_REMOVE(lf, entries); 796 LIST_REMOVE(lf, entries);
796 free(lf->pname); 797 free(lf->pname);
797 free(lf); 798 free(lf);
798 } 799 }
799 800
800 if (error && nloaded == 0) { 801 if (error && nloaded == 0) {
801 errno = error; 802 errno = error;
802 return -1; 803 return -1;
803 } 804 }
804 805
805 return nloaded; 806 return nloaded;
806} 807}
807 808
808/* XXX: this code uses definitions from NetBSD, needs rumpdefs */ 809/* XXX: this code uses definitions from NetBSD, needs rumpdefs */
809ssize_t 810ssize_t
810ukfs_vfstypes(char *buf, size_t buflen) 811ukfs_vfstypes(char *buf, size_t buflen)
811{ 812{
812 int mib[3]; 813 int mib[3];
813 struct sysctlnode q, ans[128]; 814 struct sysctlnode q, ans[128];
814 size_t alen; 815 size_t alen;
815 int i; 816 int i;
816 817
817 mib[0] = CTL_VFS; 818 mib[0] = CTL_VFS;
818 mib[1] = VFS_GENERIC; 819 mib[1] = VFS_GENERIC;
819 mib[2] = CTL_QUERY; 820 mib[2] = CTL_QUERY;
820 alen = sizeof(ans); 821 alen = sizeof(ans);
821 822
822 memset(&q, 0, sizeof(q)); 823 memset(&q, 0, sizeof(q));
823 q.sysctl_flags = SYSCTL_VERSION; 824 q.sysctl_flags = SYSCTL_VERSION;
824 825
825 if (rump_sys___sysctl(mib, 3, ans, &alen, &q, sizeof(q)) == -1) { 826 if (rump_sys___sysctl(mib, 3, ans, &alen, &q, sizeof(q)) == -1) {
826 return -1; 827 return -1;
827 } 828 }
828 829
829 for (i = 0; i < alen/sizeof(ans[0]); i++) 830 for (i = 0; i < alen/sizeof(ans[0]); i++)
830 if (strcmp("fstypes", ans[i].sysctl_name) == 0) 831 if (strcmp("fstypes", ans[i].sysctl_name) == 0)
831 break; 832 break;
832 if (i == alen/sizeof(ans[0])) { 833 if (i == alen/sizeof(ans[0])) {
833 errno = ENXIO; 834 errno = ENXIO;
834 return -1; 835 return -1;
835 } 836 }
836 837
837 mib[0] = CTL_VFS; 838 mib[0] = CTL_VFS;
838 mib[1] = VFS_GENERIC; 839 mib[1] = VFS_GENERIC;
839 mib[2] = ans[i].sysctl_num; 840 mib[2] = ans[i].sysctl_num;
840 841
841 if (rump_sys___sysctl(mib, 3, buf, &buflen, NULL, 0) == -1) { 842 if (rump_sys___sysctl(mib, 3, buf, &buflen, NULL, 0) == -1) {
842 return -1; 843 return -1;
843 } 844 }
844 845
845 return buflen; 846 return buflen;
846} 847}
847 848
848/* 849/*
849 * Utilities 850 * Utilities
850 */ 851 */
851int 852int
852ukfs_util_builddirs(struct ukfs *ukfs, const char *pathname, mode_t mode) 853ukfs_util_builddirs(struct ukfs *ukfs, const char *pathname, mode_t mode)
853{ 854{
854 char *f1, *f2; 855 char *f1, *f2;
855 int rv; 856 int rv;
856 mode_t mask; 857 mode_t mask;
857 bool end; 858 bool end;
858 859
859 /*ukfs_umask((mask = ukfs_umask(0)));*/ 860 /*ukfs_umask((mask = ukfs_umask(0)));*/
860 umask((mask = umask(0))); 861 umask((mask = umask(0)));
861 862
862 f1 = f2 = strdup(pathname); 863 f1 = f2 = strdup(pathname);
863 if (f1 == NULL) { 864 if (f1 == NULL) {
864 errno = ENOMEM; 865 errno = ENOMEM;
865 return -1; 866 return -1;
866 } 867 }
867 868
868 end = false; 869 end = false;
869 for (;;) { 870 for (;;) {
870 /* find next component */ 871 /* find next component */
871 f2 += strspn(f2, "/"); 872 f2 += strspn(f2, "/");
872 f2 += strcspn(f2, "/"); 873 f2 += strcspn(f2, "/");
873 if (*f2 == '\0') 874 if (*f2 == '\0')
874 end = true; 875 end = true;
875 else 876 else
876 *f2 = '\0'; 877 *f2 = '\0';
877 878
878 rv = ukfs_mkdir(ukfs, f1, mode & ~mask);  879 rv = ukfs_mkdir(ukfs, f1, mode & ~mask);
879 if (errno == EEXIST) 880 if (errno == EEXIST)
880 rv = 0; 881 rv = 0;
881 882
882 if (rv == -1 || *f2 != '\0' || end) 883 if (rv == -1 || *f2 != '\0' || end)
883 break; 884 break;
884 885
885 *f2 = '/'; 886 *f2 = '/';
886 } 887 }
887 888
888 free(f1); 889 free(f1);
889 890
890 return rv; 891 return rv;
891} 892}

cvs diff -r1.13 -r1.14 src/sys/rump/include/rump/rump.h (switch to unified diff)

--- src/sys/rump/include/rump/rump.h 2009/04/29 18:00:49 1.13
+++ src/sys/rump/include/rump/rump.h 2009/05/02 15:20:08 1.14
@@ -1,182 +1,190 @@ @@ -1,182 +1,190 @@
1/* $NetBSD: rump.h,v 1.13 2009/04/29 18:00:49 pooka Exp $ */ 1/* $NetBSD: rump.h,v 1.14 2009/05/02 15:20:08 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Development of this software was supported by Google Summer of Code. 6 * Development of this software was supported by Google Summer of Code.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE. 27 * SUCH DAMAGE.
28 */ 28 */
29 29
30#ifndef _RUMP_RUMP_H_ 30#ifndef _RUMP_RUMP_H_
31#define _RUMP_RUMP_H_ 31#define _RUMP_RUMP_H_
32 32
33/* 33/*
34 * NOTE: do not #include anything from <sys> here. Otherwise this 34 * NOTE: do not #include anything from <sys> here. Otherwise this
35 * has no chance of working on non-NetBSD platforms. 35 * has no chance of working on non-NetBSD platforms.
36 */ 36 */
37 37
38struct mount; 38struct mount;
39struct vnode; 39struct vnode;
40struct vattr; 40struct vattr;
41struct componentname; 41struct componentname;
42struct vfsops; 42struct vfsops;
43struct fid; 43struct fid;
44struct statvfs; 44struct statvfs;
45 45
 46/* yetch */
46#if !defined(_RUMPKERNEL) && !defined(__NetBSD__) 47#if !defined(_RUMPKERNEL) && !defined(__NetBSD__)
47struct kauth_cred; 48struct kauth_cred;
48typedef struct kauth_cred *kauth_cred_t; 49typedef struct kauth_cred *kauth_cred_t;
49#endif 50#endif
 51#if defined(__NetBSD__)
 52#include <prop/proplib.h>
 53#else
 54struct prop_dictionary;
 55typedef struct prop_dictionary *prop_dictionary_t;
 56#endif /* __NetBSD__ */
50 57
51struct lwp; 58struct lwp;
52struct modinfo; 59struct modinfo;
53 60
54#include <rump/rumpvnode_if.h> 61#include <rump/rumpvnode_if.h>
55#include <rump/rumpdefs.h> 62#include <rump/rumpdefs.h>
56 63
57#ifndef curlwp 64#ifndef curlwp
58#define curlwp rump_get_curlwp() 65#define curlwp rump_get_curlwp()
59#endif 66#endif
60 67
61/* 68/*
62 * Something like rump capabilities would be nicer, but let's 69 * Something like rump capabilities would be nicer, but let's
63 * do this for a start. 70 * do this for a start.
64 */ 71 */
65#define RUMP_VERSION 01 72#define RUMP_VERSION 01
66#define rump_init() rump__init(RUMP_VERSION) 73#define rump_init() rump__init(RUMP_VERSION)
67int rump_module_load(struct modinfo **); 74int rump_module_init(struct modinfo *, prop_dictionary_t props);
 75int rump_module_fini(struct modinfo *);
68 76
69int rump__init(int); 77int rump__init(int);
70struct mount *rump_mnt_init(struct vfsops *, int); 78struct mount *rump_mnt_init(struct vfsops *, int);
71int rump_mnt_mount(struct mount *, const char *, void *, size_t *); 79int rump_mnt_mount(struct mount *, const char *, void *, size_t *);
72void rump_mnt_destroy(struct mount *); 80void rump_mnt_destroy(struct mount *);
73 81
74struct componentname *rump_makecn(u_long, u_long, const char *, size_t, 82struct componentname *rump_makecn(u_long, u_long, const char *, size_t,
75 kauth_cred_t, struct lwp *); 83 kauth_cred_t, struct lwp *);
76void rump_freecn(struct componentname *, int); 84void rump_freecn(struct componentname *, int);
77#define RUMPCN_ISLOOKUP 0x01 85#define RUMPCN_ISLOOKUP 0x01
78#define RUMPCN_FREECRED 0x02 86#define RUMPCN_FREECRED 0x02
79#define RUMPCN_HASNTBUF 0x04 87#define RUMPCN_HASNTBUF 0x04
80int rump_namei(uint32_t, uint32_t, const char *, 88int rump_namei(uint32_t, uint32_t, const char *,
81 struct vnode **, struct vnode **, 89 struct vnode **, struct vnode **,
82 struct componentname **); 90 struct componentname **);
83 91
84void rump_getvninfo(struct vnode *, enum vtype *, off_t * /*XXX*/, dev_t *); 92void rump_getvninfo(struct vnode *, enum vtype *, off_t * /*XXX*/, dev_t *);
85 93
86int rump_fakeblk_register(const char *); 94int rump_fakeblk_register(const char *);
87int rump_fakeblk_find(const char *); 95int rump_fakeblk_find(const char *);
88void rump_fakeblk_deregister(const char *); 96void rump_fakeblk_deregister(const char *);
89 97
90struct vfsops *rump_vfslist_iterate(struct vfsops *); 98struct vfsops *rump_vfslist_iterate(struct vfsops *);
91struct vfsops *rump_vfs_getopsbyname(const char *); 99struct vfsops *rump_vfs_getopsbyname(const char *);
92 100
93struct vattr *rump_vattr_init(void); 101struct vattr *rump_vattr_init(void);
94void rump_vattr_settype(struct vattr *, enum vtype); 102void rump_vattr_settype(struct vattr *, enum vtype);
95void rump_vattr_setmode(struct vattr *, mode_t); 103void rump_vattr_setmode(struct vattr *, mode_t);
96void rump_vattr_setrdev(struct vattr *, dev_t); 104void rump_vattr_setrdev(struct vattr *, dev_t);
97void rump_vattr_free(struct vattr *); 105void rump_vattr_free(struct vattr *);
98 106
99void rump_vp_incref(struct vnode *); 107void rump_vp_incref(struct vnode *);
100int rump_vp_getref(struct vnode *); 108int rump_vp_getref(struct vnode *);
101void rump_vp_decref(struct vnode *); 109void rump_vp_decref(struct vnode *);
102void rump_vp_recycle_nokidding(struct vnode *); 110void rump_vp_recycle_nokidding(struct vnode *);
103void rump_vp_rele(struct vnode *); 111void rump_vp_rele(struct vnode *);
104 112
105enum rump_uiorw { RUMPUIO_READ, RUMPUIO_WRITE }; 113enum rump_uiorw { RUMPUIO_READ, RUMPUIO_WRITE };
106struct uio *rump_uio_setup(void *, size_t, off_t, enum rump_uiorw); 114struct uio *rump_uio_setup(void *, size_t, off_t, enum rump_uiorw);
107size_t rump_uio_getresid(struct uio *); 115size_t rump_uio_getresid(struct uio *);
108off_t rump_uio_getoff(struct uio *); 116off_t rump_uio_getoff(struct uio *);
109size_t rump_uio_free(struct uio *); 117size_t rump_uio_free(struct uio *);
110 118
111void rump_vp_interlock(struct vnode *); 119void rump_vp_interlock(struct vnode *);
112 120
113kauth_cred_t rump_cred_create(uid_t, gid_t, size_t, gid_t *); 121kauth_cred_t rump_cred_create(uid_t, gid_t, size_t, gid_t *);
114kauth_cred_t rump_cred_suserget(void); 122kauth_cred_t rump_cred_suserget(void);
115void rump_cred_destroy(kauth_cred_t); 123void rump_cred_destroy(kauth_cred_t);
116 124
117#define rump_cred_suserput(c) rump_cred_destroy(c) 125#define rump_cred_suserput(c) rump_cred_destroy(c)
118/* COMPAT_NETHACK */ 126/* COMPAT_NETHACK */
119#define WizardMode() rump_cred_suserget() 127#define WizardMode() rump_cred_suserget()
120#define YASD(cred) rump_cred_suserput(cred) 128#define YASD(cred) rump_cred_suserput(cred)
121 129
122int rump_vfs_unmount(struct mount *, int); 130int rump_vfs_unmount(struct mount *, int);
123int rump_vfs_root(struct mount *, struct vnode **, int); 131int rump_vfs_root(struct mount *, struct vnode **, int);
124int rump_vfs_statvfs(struct mount *, struct statvfs *); 132int rump_vfs_statvfs(struct mount *, struct statvfs *);
125int rump_vfs_sync(struct mount *, int, kauth_cred_t); 133int rump_vfs_sync(struct mount *, int, kauth_cred_t);
126int rump_vfs_fhtovp(struct mount *, struct fid *, struct vnode **); 134int rump_vfs_fhtovp(struct mount *, struct fid *, struct vnode **);
127int rump_vfs_vptofh(struct vnode *, struct fid *, size_t *); 135int rump_vfs_vptofh(struct vnode *, struct fid *, size_t *);
128void rump_vfs_syncwait(struct mount *); 136void rump_vfs_syncwait(struct mount *);
129 137
130struct lwp *rump_newproc_switch(void); 138struct lwp *rump_newproc_switch(void);
131struct lwp *rump_setup_curlwp(pid_t, lwpid_t, int); 139struct lwp *rump_setup_curlwp(pid_t, lwpid_t, int);
132struct lwp *rump_get_curlwp(void); 140struct lwp *rump_get_curlwp(void);
133void rump_clear_curlwp(void); 141void rump_clear_curlwp(void);
134 142
135void rump_rcvp_set(struct vnode *, struct vnode *); 143void rump_rcvp_set(struct vnode *, struct vnode *);
136struct vnode *rump_cdir_get(void); 144struct vnode *rump_cdir_get(void);
137 145
138/* I picked the wrong header to stop sniffin' glue */ 146/* I picked the wrong header to stop sniffin' glue */
139int rump_syspuffs_glueinit(int, int *); 147int rump_syspuffs_glueinit(int, int *);
140 148
141int rump_virtif_create(int); 149int rump_virtif_create(int);
142 150
143typedef int (*rump_sysproxy_t)(int, void *, uint8_t *, size_t, register_t *); 151typedef int (*rump_sysproxy_t)(int, void *, uint8_t *, size_t, register_t *);
144int rump_sysproxy_set(rump_sysproxy_t, void *); 152int rump_sysproxy_set(rump_sysproxy_t, void *);
145int rump_sysproxy_socket_setup_client(int); 153int rump_sysproxy_socket_setup_client(int);
146int rump_sysproxy_socket_setup_server(int); 154int rump_sysproxy_socket_setup_server(int);
147 155
148/* 156/*
149 * Begin rump syscall conditionals. Yes, something a little better 157 * Begin rump syscall conditionals. Yes, something a little better
150 * is required here. 158 * is required here.
151 */ 159 */
152#ifdef RUMP_SYS_NETWORKING 160#ifdef RUMP_SYS_NETWORKING
153#define socket(a,b,c) rump_sys_socket(a,b,c) 161#define socket(a,b,c) rump_sys_socket(a,b,c)
154#define accept(a,b,c) rump_sys_accept(a,b,c) 162#define accept(a,b,c) rump_sys_accept(a,b,c)
155#define bind(a,b,c) rump_sys_bind(a,b,c) 163#define bind(a,b,c) rump_sys_bind(a,b,c)
156#define connect(a,b,c) rump_sys_connect(a,b,c) 164#define connect(a,b,c) rump_sys_connect(a,b,c)
157#define getpeername(a,b,c) rump_sys_getpeername(a,b,c) 165#define getpeername(a,b,c) rump_sys_getpeername(a,b,c)
158#define getsockname(a,b,c) rump_sys_getsockname(a,b,c) 166#define getsockname(a,b,c) rump_sys_getsockname(a,b,c)
159#define listen(a,b) rump_sys_listen(a,b) 167#define listen(a,b) rump_sys_listen(a,b)
160#define recvfrom(a,b,c,d,e,f) rump_sys_recvfrom(a,b,c,d,e,f) 168#define recvfrom(a,b,c,d,e,f) rump_sys_recvfrom(a,b,c,d,e,f)
161#define sendto(a,b,c,d,e,f) rump_sys_sendto(a,b,c,d,e,f) 169#define sendto(a,b,c,d,e,f) rump_sys_sendto(a,b,c,d,e,f)
162#define getsockopt(a,b,c,d,e) rump_sys_getsockopt(a,b,c,d,e) 170#define getsockopt(a,b,c,d,e) rump_sys_getsockopt(a,b,c,d,e)
163#define setsockopt(a,b,c,d,e) rump_sys_setsockopt(a,b,c,d,e) 171#define setsockopt(a,b,c,d,e) rump_sys_setsockopt(a,b,c,d,e)
164#define shutdown(a,b) rump_sys_shutdown(a,b) 172#define shutdown(a,b) rump_sys_shutdown(a,b)
165#endif /* RUMP_SYS_NETWORKING */ 173#endif /* RUMP_SYS_NETWORKING */
166 174
167#ifdef RUMP_SYS_CLOSE 175#ifdef RUMP_SYS_CLOSE
168#define close(a) rump_sys_close(a) 176#define close(a) rump_sys_close(a)
169#endif /* RUMP_SYS_CLOSE */ 177#endif /* RUMP_SYS_CLOSE */
170 178
171#ifdef RUMP_SYS_READWRITE 179#ifdef RUMP_SYS_READWRITE
172#define read(a,b,c) rump_sys_read(a,b,c) 180#define read(a,b,c) rump_sys_read(a,b,c)
173#define readv(a,b,c) rump_sys_readv(a,b,c) 181#define readv(a,b,c) rump_sys_readv(a,b,c)
174#define pread(a,b,c,d) rump_sys_pread(a,b,c,d) 182#define pread(a,b,c,d) rump_sys_pread(a,b,c,d)
175#define preadv(a,b,c,d) rump_sys_preadv(a,b,c,d) 183#define preadv(a,b,c,d) rump_sys_preadv(a,b,c,d)
176#define write(a,b,c) rump_sys_write(a,b,c) 184#define write(a,b,c) rump_sys_write(a,b,c)
177#define writev(a,b,c) rump_sys_writev(a,b,c) 185#define writev(a,b,c) rump_sys_writev(a,b,c)
178#define pwrite(a,b,c,d) rump_sys_pwrite(a,b,c,d) 186#define pwrite(a,b,c,d) rump_sys_pwrite(a,b,c,d)
179#define pwritev(a,b,c,d) rump_sys_pwritev(a,b,c,d) 187#define pwritev(a,b,c,d) rump_sys_pwritev(a,b,c,d)
180#endif /* RUMP_SYS_READWRITE */ 188#endif /* RUMP_SYS_READWRITE */
181 189
182#endif /* _RUMP_RUMP_H_ */ 190#endif /* _RUMP_RUMP_H_ */

cvs diff -r1.105 -r1.106 src/sys/rump/librump/rumpkern/rump.c (switch to unified diff)

--- src/sys/rump/librump/rumpkern/rump.c 2009/04/30 16:59:32 1.105
+++ src/sys/rump/librump/rumpkern/rump.c 2009/05/02 15:20:08 1.106
@@ -1,538 +1,545 @@ @@ -1,538 +1,545 @@
1/* $NetBSD: rump.c,v 1.105 2009/04/30 16:59:32 pooka Exp $ */ 1/* $NetBSD: rump.c,v 1.106 2009/05/02 15:20:08 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Development of this software was supported by Google Summer of Code. 6 * Development of this software was supported by Google Summer of Code.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE. 27 * SUCH DAMAGE.
28 */ 28 */
29 29
30#include <sys/cdefs.h> 30#include <sys/cdefs.h>
31__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.105 2009/04/30 16:59:32 pooka Exp $"); 31__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.106 2009/05/02 15:20:08 pooka Exp $");
32 32
33#include <sys/param.h> 33#include <sys/param.h>
34#include <sys/atomic.h> 34#include <sys/atomic.h>
35#include <sys/buf.h> 35#include <sys/buf.h>
36#include <sys/callout.h> 36#include <sys/callout.h>
37#include <sys/conf.h> 37#include <sys/conf.h>
38#include <sys/cpu.h> 38#include <sys/cpu.h>
39#include <sys/evcnt.h> 39#include <sys/evcnt.h>
40#include <sys/event.h> 40#include <sys/event.h>
41#include <sys/filedesc.h> 41#include <sys/filedesc.h>
42#include <sys/iostat.h> 42#include <sys/iostat.h>
43#include <sys/kauth.h> 43#include <sys/kauth.h>
44#include <sys/kernel.h> 44#include <sys/kernel.h>
45#include <sys/kmem.h> 45#include <sys/kmem.h>
46#include <sys/kprintf.h> 46#include <sys/kprintf.h>
47#include <sys/ksyms.h> 47#include <sys/ksyms.h>
48#include <sys/msgbuf.h> 48#include <sys/msgbuf.h>
49#include <sys/module.h> 49#include <sys/module.h>
50#include <sys/once.h> 50#include <sys/once.h>
51#include <sys/percpu.h> 51#include <sys/percpu.h>
52#include <sys/queue.h> 52#include <sys/queue.h>
53#include <sys/resourcevar.h> 53#include <sys/resourcevar.h>
54#include <sys/select.h> 54#include <sys/select.h>
55#include <sys/sysctl.h> 55#include <sys/sysctl.h>
56#include <sys/syscall.h> 56#include <sys/syscall.h>
57#include <sys/tty.h> 57#include <sys/tty.h>
58#include <sys/uidinfo.h> 58#include <sys/uidinfo.h>
59#include <sys/vmem.h> 59#include <sys/vmem.h>
60 60
61#include <rump/rumpuser.h> 61#include <rump/rumpuser.h>
62 62
63#include <secmodel/secmodel.h> 63#include <secmodel/secmodel.h>
64 64
65#include "rump_private.h" 65#include "rump_private.h"
66#include "rump_net_private.h" 66#include "rump_net_private.h"
67#include "rump_vfs_private.h" 67#include "rump_vfs_private.h"
68 68
69struct proc proc0; 69struct proc proc0;
70struct session rump_session = { 70struct session rump_session = {
71 .s_count = 1, 71 .s_count = 1,
72 .s_flags = 0, 72 .s_flags = 0,
73 .s_leader = &proc0, 73 .s_leader = &proc0,
74 .s_login = "rumphobo", 74 .s_login = "rumphobo",
75 .s_sid = 0, 75 .s_sid = 0,
76}; 76};
77struct pgrp rump_pgrp = { 77struct pgrp rump_pgrp = {
78 .pg_members = LIST_HEAD_INITIALIZER(pg_members), 78 .pg_members = LIST_HEAD_INITIALIZER(pg_members),
79 .pg_session = &rump_session, 79 .pg_session = &rump_session,
80 .pg_jobc = 1, 80 .pg_jobc = 1,
81}; 81};
82struct pstats rump_stats; 82struct pstats rump_stats;
83struct plimit rump_limits; 83struct plimit rump_limits;
84struct cpu_info rump_cpu; 84struct cpu_info rump_cpu;
85struct filedesc rump_filedesc0; 85struct filedesc rump_filedesc0;
86struct proclist allproc; 86struct proclist allproc;
87char machine[] = "rump"; 87char machine[] = "rump";
88static kauth_cred_t rump_susercred; 88static kauth_cred_t rump_susercred;
89 89
90/* pretend the master rump proc is init */ 90/* pretend the master rump proc is init */
91struct proc *initproc = &proc0; 91struct proc *initproc = &proc0;
92 92
93struct rumpuser_mtx *rump_giantlock; 93struct rumpuser_mtx *rump_giantlock;
94 94
95sigset_t sigcantmask; 95sigset_t sigcantmask;
96 96
97#ifdef RUMP_WITHOUT_THREADS 97#ifdef RUMP_WITHOUT_THREADS
98int rump_threads = 0; 98int rump_threads = 0;
99#else 99#else
100int rump_threads = 1; 100int rump_threads = 1;
101#endif 101#endif
102 102
103static void 103static void
104rump_aiodone_worker(struct work *wk, void *dummy) 104rump_aiodone_worker(struct work *wk, void *dummy)
105{ 105{
106 struct buf *bp = (struct buf *)wk; 106 struct buf *bp = (struct buf *)wk;
107 107
108 KASSERT(&bp->b_work == wk); 108 KASSERT(&bp->b_work == wk);
109 bp->b_iodone(bp); 109 bp->b_iodone(bp);
110} 110}
111 111
112static int rump_inited; 112static int rump_inited;
113static struct emul emul_rump; 113static struct emul emul_rump;
114 114
115void rump__unavailable(void); 115void rump__unavailable(void);
116void rump__unavailable() {} 116void rump__unavailable() {}
117__weak_alias(rump_net_init,rump__unavailable); 117__weak_alias(rump_net_init,rump__unavailable);
118__weak_alias(rump_vfs_init,rump__unavailable); 118__weak_alias(rump_vfs_init,rump__unavailable);
119 119
120void rump__unavailable_vfs_panic(void); 120void rump__unavailable_vfs_panic(void);
121void rump__unavailable_vfs_panic() {panic("vfs component not available");} 121void rump__unavailable_vfs_panic() {panic("vfs component not available");}
122__weak_alias(vn_open,rump__unavailable_vfs_panic); 122__weak_alias(vn_open,rump__unavailable_vfs_panic);
123__weak_alias(vn_rdwr,rump__unavailable_vfs_panic); 123__weak_alias(vn_rdwr,rump__unavailable_vfs_panic);
124__weak_alias(vn_close,rump__unavailable_vfs_panic); 124__weak_alias(vn_close,rump__unavailable_vfs_panic);
125 125
126static void 126static void
127pvfsinit_nop(struct proc *p) 127pvfsinit_nop(struct proc *p)
128{ 128{
129 129
130 return; 130 return;
131} 131}
132 132
133static void 133static void
134pvfsrele_nop(struct proc *p) 134pvfsrele_nop(struct proc *p)
135{ 135{
136 136
137 return; 137 return;
138} 138}
139 139
140rump_proc_vfs_init_fn rump_proc_vfs_init = pvfsinit_nop; 140rump_proc_vfs_init_fn rump_proc_vfs_init = pvfsinit_nop;
141rump_proc_vfs_release_fn rump_proc_vfs_release = pvfsrele_nop; 141rump_proc_vfs_release_fn rump_proc_vfs_release = pvfsrele_nop;
142 142
143/* 143/*
144 * Stir up the stack a bit. These are exported functions to help 144 * Stir up the stack a bit. These are exported functions to help
145 * convince the compiler that we don't want these routines completely 145 * convince the compiler that we don't want these routines completely
146 * optimized out or inlined. Is there an easier way to do this? 146 * optimized out or inlined. Is there an easier way to do this?
147 */ 147 */
148void nullfn(uint32_t *); 148void nullfn(uint32_t *);
149void nullfn(uint32_t *arg){} 149void nullfn(uint32_t *arg){}
150void messthestack(void); 150void messthestack(void);
151void 151void
152messthestack(void) 152messthestack(void)
153{ 153{
154 uint32_t mess[64]; 154 uint32_t mess[64];
155 uint64_t d1, d2; 155 uint64_t d1, d2;
156 int i, error; 156 int i, error;
157 157
158 for (i = 0; i < 64; i++) { 158 for (i = 0; i < 64; i++) {
159 rumpuser_gettime(&d1, &d2, &error); 159 rumpuser_gettime(&d1, &d2, &error);
160 mess[i] = d2; 160 mess[i] = d2;
161 } 161 }
162 nullfn(mess); 162 nullfn(mess);
163} 163}
164 164
165int 165int
166rump__init(int rump_version) 166rump__init(int rump_version)
167{ 167{
168 char buf[256]; 168 char buf[256];
169 struct proc *p; 169 struct proc *p;
170 struct lwp *l; 170 struct lwp *l;
171 int error; 171 int error;
172 172
173 /* XXX */ 173 /* XXX */
174 if (rump_inited) 174 if (rump_inited)
175 return 0; 175 return 0;
176 rump_inited = 1; 176 rump_inited = 1;
177 177
178 /* 178 /*
179 * Seed arc4random() with a "reasonable" amount of randomness. 179 * Seed arc4random() with a "reasonable" amount of randomness.
180 * Yes, this is a quick kludge which depends on the arc4random 180 * Yes, this is a quick kludge which depends on the arc4random
181 * implementation. 181 * implementation.
182 */ 182 */
183 messthestack(); 183 messthestack();
184 arc4random(); 184 arc4random();
185 185
186 if (rump_version != RUMP_VERSION) { 186 if (rump_version != RUMP_VERSION) {
187 printf("rump version mismatch, %d vs. %d\n", 187 printf("rump version mismatch, %d vs. %d\n",
188 rump_version, RUMP_VERSION); 188 rump_version, RUMP_VERSION);
189 return EPROGMISMATCH; 189 return EPROGMISMATCH;
190 } 190 }
191 191
192 if (rumpuser_getenv("RUMP_THREADS", buf, sizeof(buf), &error) == 0) { 192 if (rumpuser_getenv("RUMP_THREADS", buf, sizeof(buf), &error) == 0) {
193 rump_threads = *buf != '0'; 193 rump_threads = *buf != '0';
194 } 194 }
195 rumpuser_thrinit(_kernel_lock, _kernel_unlock, rump_threads); 195 rumpuser_thrinit(_kernel_lock, _kernel_unlock, rump_threads);
196 196
197 mutex_init(&tty_lock, MUTEX_DEFAULT, IPL_NONE); 197 mutex_init(&tty_lock, MUTEX_DEFAULT, IPL_NONE);
198 rumpuser_mutex_recursive_init(&rump_giantlock); 198 rumpuser_mutex_recursive_init(&rump_giantlock);
199 ksyms_init(); 199 ksyms_init();
200 rumpvm_init(); 200 rumpvm_init();
201 evcnt_init(); 201 evcnt_init();
202 202
203 once_init(); 203 once_init();
204 204
205 rump_sleepers_init(); 205 rump_sleepers_init();
206 206
207 pool_subsystem_init(); 207 pool_subsystem_init();
208 kmem_init(); 208 kmem_init();
209 209
210 kprintf_init(); 210 kprintf_init();
211 loginit(); 211 loginit();
212 212
213 kauth_init(); 213 kauth_init();
214 rump_susercred = rump_cred_create(0, 0, 0, NULL); 214 rump_susercred = rump_cred_create(0, 0, 0, NULL);
215 215
216 l = &lwp0; 216 l = &lwp0;
217 p = &proc0; 217 p = &proc0;
218 p->p_stats = &rump_stats; 218 p->p_stats = &rump_stats;
219 p->p_limit = &rump_limits; 219 p->p_limit = &rump_limits;
220 p->p_pgrp = &rump_pgrp; 220 p->p_pgrp = &rump_pgrp;
221 p->p_pid = 0; 221 p->p_pid = 0;
222 p->p_fd = &rump_filedesc0; 222 p->p_fd = &rump_filedesc0;
223 p->p_vmspace = &rump_vmspace; 223 p->p_vmspace = &rump_vmspace;
224 p->p_emul = &emul_rump; 224 p->p_emul = &emul_rump;
225 p->p_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 225 p->p_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
226 l->l_cred = rump_cred_suserget(); 226 l->l_cred = rump_cred_suserget();
227 l->l_proc = p; 227 l->l_proc = p;
228 l->l_lid = 1; 228 l->l_lid = 1;
229 LIST_INIT(&allproc); 229 LIST_INIT(&allproc);
230 LIST_INSERT_HEAD(&allproc, &proc0, p_list); 230 LIST_INSERT_HEAD(&allproc, &proc0, p_list);
231 proc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 231 proc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
232 232
233 rump_limits.pl_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; 233 rump_limits.pl_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
234 rump_limits.pl_rlimit[RLIMIT_NOFILE].rlim_cur = RLIM_INFINITY; 234 rump_limits.pl_rlimit[RLIMIT_NOFILE].rlim_cur = RLIM_INFINITY;
235 rump_limits.pl_rlimit[RLIMIT_SBSIZE].rlim_cur = RLIM_INFINITY; 235 rump_limits.pl_rlimit[RLIMIT_SBSIZE].rlim_cur = RLIM_INFINITY;
236 236
237 callout_startup(); 237 callout_startup();
238 callout_init_cpu(&rump_cpu); 238 callout_init_cpu(&rump_cpu);
239 239
240 kqueue_init(); 240 kqueue_init();
241 iostat_init(); 241 iostat_init();
242 uid_init(); 242 uid_init();
243 percpu_init(); 243 percpu_init();
244 fd_sys_init(); 244 fd_sys_init();
245 module_init(); 245 module_init();
246 sysctl_init(); 246 sysctl_init();
247 softint_init(&rump_cpu); 247 softint_init(&rump_cpu);
248 cold = 0; 248 cold = 0;
249 devsw_init(); 249 devsw_init();
250 secmodel_start(); 250 secmodel_start();
251 251
252 /* these do nothing if not present */ 252 /* these do nothing if not present */
253 rump_vfs_init(); 253 rump_vfs_init();
254 rump_net_init(); 254 rump_net_init();
255 255
256 /* aieeeedondest */ 256 /* aieeeedondest */
257 if (rump_threads) { 257 if (rump_threads) {
258 if (workqueue_create(&uvm.aiodone_queue, "aiodoned", 258 if (workqueue_create(&uvm.aiodone_queue, "aiodoned",
259 rump_aiodone_worker, NULL, 0, 0, 0)) 259 rump_aiodone_worker, NULL, 0, 0, 0))
260 panic("aiodoned"); 260 panic("aiodoned");
261 } 261 }
262 262
263 rumpuser_gethostname(hostname, MAXHOSTNAMELEN, &error); 263 rumpuser_gethostname(hostname, MAXHOSTNAMELEN, &error);
264 hostnamelen = strlen(hostname); 264 hostnamelen = strlen(hostname);
265 265
266 sigemptyset(&sigcantmask); 266 sigemptyset(&sigcantmask);
267 267
268 lwp0.l_fd = proc0.p_fd = fd_init(&rump_filedesc0); 268 lwp0.l_fd = proc0.p_fd = fd_init(&rump_filedesc0);
269 269
270#ifdef RUMP_USE_REAL_ALLOCATORS 270#ifdef RUMP_USE_REAL_ALLOCATORS
271 if (rump_threads) 271 if (rump_threads)
272 vmem_rehash_start(); 272 vmem_rehash_start();
273#endif 273#endif
274 274
275 return 0; 275 return 0;
276} 276}
277 277
278struct uio * 278struct uio *
279rump_uio_setup(void *buf, size_t bufsize, off_t offset, enum rump_uiorw rw) 279rump_uio_setup(void *buf, size_t bufsize, off_t offset, enum rump_uiorw rw)
280{ 280{
281 struct uio *uio; 281 struct uio *uio;
282 enum uio_rw uiorw; 282 enum uio_rw uiorw;
283 283
284 switch (rw) { 284 switch (rw) {
285 case RUMPUIO_READ: 285 case RUMPUIO_READ:
286 uiorw = UIO_READ; 286 uiorw = UIO_READ;
287 break; 287 break;
288 case RUMPUIO_WRITE: 288 case RUMPUIO_WRITE:
289 uiorw = UIO_WRITE; 289 uiorw = UIO_WRITE;
290 break; 290 break;
291 default: 291 default:
292 panic("%s: invalid rw %d", __func__, rw); 292 panic("%s: invalid rw %d", __func__, rw);
293 } 293 }
294 294
295 uio = kmem_alloc(sizeof(struct uio), KM_SLEEP); 295 uio = kmem_alloc(sizeof(struct uio), KM_SLEEP);
296 uio->uio_iov = kmem_alloc(sizeof(struct iovec), KM_SLEEP); 296 uio->uio_iov = kmem_alloc(sizeof(struct iovec), KM_SLEEP);
297 297
298 uio->uio_iov->iov_base = buf; 298 uio->uio_iov->iov_base = buf;
299 uio->uio_iov->iov_len = bufsize; 299 uio->uio_iov->iov_len = bufsize;
300 300
301 uio->uio_iovcnt = 1; 301 uio->uio_iovcnt = 1;
302 uio->uio_offset = offset; 302 uio->uio_offset = offset;
303 uio->uio_resid = bufsize; 303 uio->uio_resid = bufsize;
304 uio->uio_rw = uiorw; 304 uio->uio_rw = uiorw;
305 uio->uio_vmspace = UIO_VMSPACE_SYS; 305 uio->uio_vmspace = UIO_VMSPACE_SYS;
306 306
307 return uio; 307 return uio;
308} 308}
309 309
310size_t 310size_t
311rump_uio_getresid(struct uio *uio) 311rump_uio_getresid(struct uio *uio)
312{ 312{
313 313
314 return uio->uio_resid; 314 return uio->uio_resid;
315} 315}
316 316
317off_t 317off_t
318rump_uio_getoff(struct uio *uio) 318rump_uio_getoff(struct uio *uio)
319{ 319{
320 320
321 return uio->uio_offset; 321 return uio->uio_offset;
322} 322}
323 323
324size_t 324size_t
325rump_uio_free(struct uio *uio) 325rump_uio_free(struct uio *uio)
326{ 326{
327 size_t resid; 327 size_t resid;
328 328
329 resid = uio->uio_resid; 329 resid = uio->uio_resid;
330 kmem_free(uio->uio_iov, sizeof(*uio->uio_iov)); 330 kmem_free(uio->uio_iov, sizeof(*uio->uio_iov));
331 kmem_free(uio, sizeof(*uio)); 331 kmem_free(uio, sizeof(*uio));
332 332
333 return resid; 333 return resid;
334} 334}
335 335
336/* public interface */ 336/* public interface */
337static pid_t nextpid = 1; 337static pid_t nextpid = 1;
338struct lwp * 338struct lwp *
339rump_newproc_switch() 339rump_newproc_switch()
340{ 340{
341 struct lwp *oldlwp = curlwp; 341 struct lwp *oldlwp = curlwp;
342 pid_t mypid; 342 pid_t mypid;
343 343
344 mypid = atomic_inc_uint_nv(&nextpid); 344 mypid = atomic_inc_uint_nv(&nextpid);
345 if (__predict_false(mypid == 0)) 345 if (__predict_false(mypid == 0))
346 mypid = atomic_inc_uint_nv(&nextpid); 346 mypid = atomic_inc_uint_nv(&nextpid);
347 347
348 rumpuser_set_curlwp(NULL); 348 rumpuser_set_curlwp(NULL);
349 rump_setup_curlwp(mypid, 0, 1); 349 rump_setup_curlwp(mypid, 0, 1);
350 350
351 return oldlwp; 351 return oldlwp;
352} 352}
353 353
354/* rump private */ 354/* rump private */
355struct lwp * 355struct lwp *
356rump_setup_curlwp(pid_t pid, lwpid_t lid, int set) 356rump_setup_curlwp(pid_t pid, lwpid_t lid, int set)
357{ 357{
358 struct lwp *l; 358 struct lwp *l;
359 struct proc *p; 359 struct proc *p;
360 360
361 l = kmem_zalloc(sizeof(struct lwp), KM_SLEEP); 361 l = kmem_zalloc(sizeof(struct lwp), KM_SLEEP);
362 if (pid != 0) { 362 if (pid != 0) {
363 p = kmem_zalloc(sizeof(struct proc), KM_SLEEP); 363 p = kmem_zalloc(sizeof(struct proc), KM_SLEEP);
364 rump_proc_vfs_init(p); 364 rump_proc_vfs_init(p);
365 p->p_stats = &rump_stats; 365 p->p_stats = &rump_stats;
366 p->p_limit = &rump_limits; 366 p->p_limit = &rump_limits;
367 p->p_pid = pid; 367 p->p_pid = pid;
368 p->p_vmspace = &rump_vmspace; 368 p->p_vmspace = &rump_vmspace;
369 p->p_fd = fd_init(NULL); 369 p->p_fd = fd_init(NULL);
370 } else { 370 } else {
371 p = &proc0; 371 p = &proc0;
372 } 372 }
373 373
374 l->l_cred = rump_cred_suserget(); 374 l->l_cred = rump_cred_suserget();
375 l->l_proc = p; 375 l->l_proc = p;
376 l->l_lid = lid; 376 l->l_lid = lid;
377 l->l_fd = p->p_fd; 377 l->l_fd = p->p_fd;
378 l->l_mutex = RUMP_LMUTEX_MAGIC; 378 l->l_mutex = RUMP_LMUTEX_MAGIC;
379 l->l_cpu = &rump_cpu; 379 l->l_cpu = &rump_cpu;
380 380
381 if (set) 381 if (set)
382 rumpuser_set_curlwp(l); 382 rumpuser_set_curlwp(l);
383 383
384 return l; 384 return l;
385} 385}
386 386
387/* rump private. NEEDS WORK! */ 387/* rump private. NEEDS WORK! */
388void 388void
389rump_set_vmspace(struct vmspace *vm) 389rump_set_vmspace(struct vmspace *vm)
390{ 390{
391 struct proc *p = curproc; 391 struct proc *p = curproc;
392 392
393 p->p_vmspace = vm; 393 p->p_vmspace = vm;
394} 394}
395 395
396void 396void
397rump_clear_curlwp(void) 397rump_clear_curlwp(void)
398{ 398{
399 struct lwp *l; 399 struct lwp *l;
400 struct proc *p; 400 struct proc *p;
401 401
402 l = rumpuser_get_curlwp(); 402 l = rumpuser_get_curlwp();
403 p = l->l_proc; 403 p = l->l_proc;
404 if (p->p_pid != 0) { 404 if (p->p_pid != 0) {
405 fd_free(); 405 fd_free();
406 rump_proc_vfs_release(p); 406 rump_proc_vfs_release(p);
407 rump_cred_destroy(l->l_cred); 407 rump_cred_destroy(l->l_cred);
408 kmem_free(p, sizeof(*p)); 408 kmem_free(p, sizeof(*p));
409 } 409 }
410 kmem_free(l, sizeof(*l)); 410 kmem_free(l, sizeof(*l));
411 rumpuser_set_curlwp(NULL); 411 rumpuser_set_curlwp(NULL);
412} 412}
413 413
414struct lwp * 414struct lwp *
415rump_get_curlwp(void) 415rump_get_curlwp(void)
416{ 416{
417 struct lwp *l; 417 struct lwp *l;
418 418
419 l = rumpuser_get_curlwp(); 419 l = rumpuser_get_curlwp();
420 if (l == NULL) 420 if (l == NULL)
421 l = &lwp0; 421 l = &lwp0;
422 422
423 return l; 423 return l;
424} 424}
425 425
426kauth_cred_t 426kauth_cred_t
427rump_cred_create(uid_t uid, gid_t gid, size_t ngroups, gid_t *groups) 427rump_cred_create(uid_t uid, gid_t gid, size_t ngroups, gid_t *groups)
428{ 428{
429 kauth_cred_t cred; 429 kauth_cred_t cred;
430 int rv; 430 int rv;
431 431
432 cred = kauth_cred_alloc(); 432 cred = kauth_cred_alloc();
433 kauth_cred_setuid(cred, uid); 433 kauth_cred_setuid(cred, uid);
434 kauth_cred_seteuid(cred, uid); 434 kauth_cred_seteuid(cred, uid);
435 kauth_cred_setsvuid(cred, uid); 435 kauth_cred_setsvuid(cred, uid);
436 kauth_cred_setgid(cred, gid); 436 kauth_cred_setgid(cred, gid);
437 kauth_cred_setgid(cred, gid); 437 kauth_cred_setgid(cred, gid);
438 kauth_cred_setegid(cred, gid); 438 kauth_cred_setegid(cred, gid);
439 kauth_cred_setsvgid(cred, gid); 439 kauth_cred_setsvgid(cred, gid);
440 rv = kauth_cred_setgroups(cred, groups, ngroups, 0, UIO_SYSSPACE); 440 rv = kauth_cred_setgroups(cred, groups, ngroups, 0, UIO_SYSSPACE);
441 /* oh this is silly. and by "this" I mean kauth_cred_setgroups() */ 441 /* oh this is silly. and by "this" I mean kauth_cred_setgroups() */
442 assert(rv == 0); 442 assert(rv == 0);
443 443
444 return cred; 444 return cred;
445} 445}
446 446
447void 447void
448rump_cred_destroy(kauth_cred_t cred) 448rump_cred_destroy(kauth_cred_t cred)
449{ 449{
450 450
451 kauth_cred_free(cred); 451 kauth_cred_free(cred);
452} 452}
453 453
454kauth_cred_t 454kauth_cred_t
455rump_cred_suserget(void) 455rump_cred_suserget(void)
456{ 456{
457 457
458 kauth_cred_hold(rump_susercred); 458 kauth_cred_hold(rump_susercred);
459 return rump_susercred; 459 return rump_susercred;
460} 460}
461 461
462/* 462/*
463 * Return the next system lwpid 463 * Return the next system lwpid
464 */ 464 */
465lwpid_t 465lwpid_t
466rump_nextlid(void) 466rump_nextlid(void)
467{ 467{
468 lwpid_t retid; 468 lwpid_t retid;
469 469
470 mutex_enter(proc0.p_lock); 470 mutex_enter(proc0.p_lock);
471 /* 471 /*
472 * Take next one, don't return 0 472 * Take next one, don't return 0
473 * XXX: most likely we'll have collisions in case this 473 * XXX: most likely we'll have collisions in case this
474 * wraps around. 474 * wraps around.
475 */ 475 */
476 if (++proc0.p_nlwpid == 0) 476 if (++proc0.p_nlwpid == 0)
477 ++proc0.p_nlwpid; 477 ++proc0.p_nlwpid;
478 retid = proc0.p_nlwpid; 478 retid = proc0.p_nlwpid;
479 mutex_exit(proc0.p_lock); 479 mutex_exit(proc0.p_lock);
480 480
481 return retid; 481 return retid;
482} 482}
483 483
484int 484int
485rump_module_load(struct modinfo **mi) 485rump_module_init(struct modinfo *mi, prop_dictionary_t props)
486{ 486{
487 487
488 if (!module_compatible((*mi)->mi_version, __NetBSD_Version__)) 488 if (!module_compatible(mi->mi_version, __NetBSD_Version__))
489 return EPROGMISMATCH; 489 return EPROGMISMATCH;
490 490
491 return (*mi)->mi_modcmd(MODULE_CMD_INIT, NULL); 491 return mi->mi_modcmd(MODULE_CMD_INIT, props);
 492}
 493
 494int
 495rump_module_fini(struct modinfo *mi)
 496{
 497
 498 return mi->mi_modcmd(MODULE_CMD_FINI, NULL);
492} 499}
493 500
494int _syspuffs_stub(int, int *); 501int _syspuffs_stub(int, int *);
495int 502int
496_syspuffs_stub(int fd, int *newfd) 503_syspuffs_stub(int fd, int *newfd)
497{ 504{
498 505
499 return ENODEV; 506 return ENODEV;
500} 507}
501__weak_alias(rump_syspuffs_glueinit,_syspuffs_stub); 508__weak_alias(rump_syspuffs_glueinit,_syspuffs_stub);
502 509
503static int 510static int
504rump_sysproxy_local(int num, void *arg, uint8_t *data, size_t dlen, 511rump_sysproxy_local(int num, void *arg, uint8_t *data, size_t dlen,
505 register_t *retval) 512 register_t *retval)
506{ 513{
507 struct lwp *l; 514 struct lwp *l;
508 struct sysent *callp; 515 struct sysent *callp;
509 516
510 if (__predict_false(num >= SYS_NSYSENT)) 517 if (__predict_false(num >= SYS_NSYSENT))
511 return ENOSYS; 518 return ENOSYS;
512 519
513 l = curlwp; 520 l = curlwp;
514 callp = rump_sysent + num; 521 callp = rump_sysent + num;
515 return callp->sy_call(l, (void *)data, retval); 522 return callp->sy_call(l, (void *)data, retval);
516} 523}
517 524
518rump_sysproxy_t rump_sysproxy = rump_sysproxy_local; 525rump_sysproxy_t rump_sysproxy = rump_sysproxy_local;
519void *rump_sysproxy_arg; 526void *rump_sysproxy_arg;
520 527
521/* 528/*
522 * This whole syscall-via-rpc is still taking form. For example, it 529 * This whole syscall-via-rpc is still taking form. For example, it
523 * may be necessary to set syscalls individually instead of lobbing 530 * may be necessary to set syscalls individually instead of lobbing
524 * them all to the same place. So don't think this interface is 531 * them all to the same place. So don't think this interface is
525 * set in stone. 532 * set in stone.
526 */ 533 */
527int 534int
528rump_sysproxy_set(rump_sysproxy_t proxy, void *arg) 535rump_sysproxy_set(rump_sysproxy_t proxy, void *arg)
529{ 536{
530 537
531 if (rump_sysproxy_arg) 538 if (rump_sysproxy_arg)
532 return EBUSY; 539 return EBUSY;
533 540
534 rump_sysproxy_arg = arg; 541 rump_sysproxy_arg = arg;
535 rump_sysproxy = proxy; 542 rump_sysproxy = proxy;
536 543
537 return 0; 544 return 0;
538} 545}