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().diff -r1.25 -r1.26 src/lib/libukfs/ukfs.c
(pooka)
--- 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 | |||
68 | struct ukfs { | 68 | struct 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 | |||
78 | struct mount * | 78 | struct mount * | |
79 | ukfs_getmp(struct ukfs *ukfs) | 79 | ukfs_getmp(struct ukfs *ukfs) | |
80 | { | 80 | { | |
81 | 81 | |||
82 | return ukfs->ukfs_mp; | 82 | return ukfs->ukfs_mp; | |
83 | } | 83 | } | |
84 | 84 | |||
85 | struct vnode * | 85 | struct vnode * | |
86 | ukfs_getrvp(struct ukfs *ukfs) | 86 | ukfs_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 | |||
103 | static pid_t | 103 | static pid_t | |
104 | nextpid(struct ukfs *ukfs) | 104 | nextpid(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 | |||
117 | static void | 117 | static void | |
118 | precall(struct ukfs *ukfs) | 118 | precall(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 | |||
131 | static void | 131 | static void | |
132 | postcall(struct ukfs *ukfs) | 132 | postcall(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 | |||
142 | int | 142 | int | |
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 | |||
162 | struct ukfs * | 162 | struct ukfs * | |
163 | ukfs_mount(const char *vfsname, const char *devpath, const char *mountpath, | 163 | ukfs_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 | |||
263 | void | 263 | void | |
264 | ukfs_release(struct ukfs *fs, int flags) | 264 | ukfs_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 | |||
300 | int | 300 | int | |
301 | ukfs_opendir(struct ukfs *ukfs, const char *dirname, struct ukfs_dircookie **c) | 301 | ukfs_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 | |||
323 | static int | 323 | static int | |
324 | getmydents(struct vnode *vp, off_t *off, uint8_t *buf, size_t bufsize) | 324 | getmydents(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*/ | |
349 | int | 349 | int | |
350 | ukfs_getdents_cookie(struct ukfs *ukfs, struct ukfs_dircookie *c, off_t *off, | 350 | ukfs_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 | |||
360 | int | 360 | int | |
361 | ukfs_getdents(struct ukfs *ukfs, const char *dirname, off_t *off, | 361 | ukfs_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*/ | |
382 | int | 382 | int | |
383 | ukfs_closedir(struct ukfs *ukfs, struct ukfs_dircookie *c) | 383 | ukfs_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 | |||
391 | int | 391 | int | |
392 | ukfs_open(struct ukfs *ukfs, const char *filename, int flags) | 392 | ukfs_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 | |||
405 | ssize_t | 405 | ssize_t | |
406 | ukfs_read(struct ukfs *ukfs, const char *filename, off_t off, | 406 | ukfs_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*/ | |
429 | ssize_t | 429 | ssize_t | |
430 | ukfs_read_fd(struct ukfs *ukfs, int fd, off_t off, uint8_t *buf, size_t buflen) | 430 | ukfs_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 | |||
436 | ssize_t | 436 | ssize_t | |
437 | ukfs_write(struct ukfs *ukfs, const char *filename, off_t off, | 437 | ukfs_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*/ | |
464 | ssize_t | 464 | ssize_t | |
465 | ukfs_write_fd(struct ukfs *ukfs, int fd, off_t off, uint8_t *buf, size_t buflen, | 465 | ukfs_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*/ | |
478 | int | 478 | int | |
479 | ukfs_close(struct ukfs *ukfs, int fd) | 479 | ukfs_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 | |||
486 | int | 486 | int | |
487 | ukfs_create(struct ukfs *ukfs, const char *filename, mode_t mode) | 487 | ukfs_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 | |||
501 | int | 501 | int | |
502 | ukfs_mknod(struct ukfs *ukfs, const char *path, mode_t mode, dev_t dev) | 502 | ukfs_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 | |||
508 | int | 508 | int | |
509 | ukfs_mkfifo(struct ukfs *ukfs, const char *path, mode_t mode) | 509 | ukfs_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 | |||
515 | int | 515 | int | |
516 | ukfs_mkdir(struct ukfs *ukfs, const char *filename, mode_t mode) | 516 | ukfs_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 | |||
522 | int | 522 | int | |
523 | ukfs_remove(struct ukfs *ukfs, const char *filename) | 523 | ukfs_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 | |||
529 | int | 529 | int | |
530 | ukfs_rmdir(struct ukfs *ukfs, const char *filename) | 530 | ukfs_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 | |||
536 | int | 536 | int | |
537 | ukfs_link(struct ukfs *ukfs, const char *filename, const char *f_create) | 537 | ukfs_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 | |||
543 | int | 543 | int | |
544 | ukfs_symlink(struct ukfs *ukfs, const char *filename, const char *linkname) | 544 | ukfs_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 | |||
550 | ssize_t | 550 | ssize_t | |
551 | ukfs_readlink(struct ukfs *ukfs, const char *filename, | 551 | ukfs_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 | |||
562 | int | 562 | int | |
563 | ukfs_rename(struct ukfs *ukfs, const char *from, const char *to) | 563 | ukfs_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 | |||
569 | int | 569 | int | |
570 | ukfs_chdir(struct ukfs *ukfs, const char *path) | 570 | ukfs_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 | |||
593 | int | 593 | int | |
594 | ukfs_stat(struct ukfs *ukfs, const char *filename, struct stat *file_stat) | 594 | ukfs_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 | |||
600 | int | 600 | int | |
601 | ukfs_lstat(struct ukfs *ukfs, const char *filename, struct stat *file_stat) | 601 | ukfs_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 | |||
607 | int | 607 | int | |
608 | ukfs_chmod(struct ukfs *ukfs, const char *filename, mode_t mode) | 608 | ukfs_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 | |||
614 | int | 614 | int | |
615 | ukfs_lchmod(struct ukfs *ukfs, const char *filename, mode_t mode) | 615 | ukfs_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 | |||
621 | int | 621 | int | |
622 | ukfs_chown(struct ukfs *ukfs, const char *filename, uid_t uid, gid_t gid) | 622 | ukfs_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 | |||
628 | int | 628 | int | |
629 | ukfs_lchown(struct ukfs *ukfs, const char *filename, uid_t uid, gid_t gid) | 629 | ukfs_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 | |||
635 | int | 635 | int | |
636 | ukfs_chflags(struct ukfs *ukfs, const char *filename, u_long flags) | 636 | ukfs_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 | |||
642 | int | 642 | int | |
643 | ukfs_lchflags(struct ukfs *ukfs, const char *filename, u_long flags) | 643 | ukfs_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 | |||
649 | int | 649 | int | |
650 | ukfs_utimes(struct ukfs *ukfs, const char *filename, const struct timeval *tptr) | 650 | ukfs_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 | |||
656 | int | 656 | int | |
657 | ukfs_lutimes(struct ukfs *ukfs, const char *filename, | 657 | ukfs_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 | */ | |
675 | int | 675 | int | |
676 | ukfs_modload(const char *fname) | 676 | ukfs_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 | |||
710 | struct loadfail { | 711 | struct 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 | |||
719 | int | 720 | int | |
720 | ukfs_modload_dir(const char *dir) | 721 | ukfs_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 */ | |
809 | ssize_t | 810 | ssize_t | |
810 | ukfs_vfstypes(char *buf, size_t buflen) | 811 | ukfs_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 | */ | |
851 | int | 852 | int | |
852 | ukfs_util_builddirs(struct ukfs *ukfs, const char *pathname, mode_t mode) | 853 | ukfs_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 | } |
--- 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 | |||
38 | struct mount; | 38 | struct mount; | |
39 | struct vnode; | 39 | struct vnode; | |
40 | struct vattr; | 40 | struct vattr; | |
41 | struct componentname; | 41 | struct componentname; | |
42 | struct vfsops; | 42 | struct vfsops; | |
43 | struct fid; | 43 | struct fid; | |
44 | struct statvfs; | 44 | struct statvfs; | |
45 | 45 | |||
46 | /* yetch */ | |||
46 | #if !defined(_RUMPKERNEL) && !defined(__NetBSD__) | 47 | #if !defined(_RUMPKERNEL) && !defined(__NetBSD__) | |
47 | struct kauth_cred; | 48 | struct kauth_cred; | |
48 | typedef struct kauth_cred *kauth_cred_t; | 49 | typedef struct kauth_cred *kauth_cred_t; | |
49 | #endif | 50 | #endif | |
51 | #if defined(__NetBSD__) | |||
52 | #include <prop/proplib.h> | |||
53 | #else | |||
54 | struct prop_dictionary; | |||
55 | typedef struct prop_dictionary *prop_dictionary_t; | |||
56 | #endif /* __NetBSD__ */ | |||
50 | 57 | |||
51 | struct lwp; | 58 | struct lwp; | |
52 | struct modinfo; | 59 | struct 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) | |
67 | int rump_module_load(struct modinfo **); | 74 | int rump_module_init(struct modinfo *, prop_dictionary_t props); | |
75 | int rump_module_fini(struct modinfo *); | |||
68 | 76 | |||
69 | int rump__init(int); | 77 | int rump__init(int); | |
70 | struct mount *rump_mnt_init(struct vfsops *, int); | 78 | struct mount *rump_mnt_init(struct vfsops *, int); | |
71 | int rump_mnt_mount(struct mount *, const char *, void *, size_t *); | 79 | int rump_mnt_mount(struct mount *, const char *, void *, size_t *); | |
72 | void rump_mnt_destroy(struct mount *); | 80 | void rump_mnt_destroy(struct mount *); | |
73 | 81 | |||
74 | struct componentname *rump_makecn(u_long, u_long, const char *, size_t, | 82 | struct componentname *rump_makecn(u_long, u_long, const char *, size_t, | |
75 | kauth_cred_t, struct lwp *); | 83 | kauth_cred_t, struct lwp *); | |
76 | void rump_freecn(struct componentname *, int); | 84 | void 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 | |
80 | int rump_namei(uint32_t, uint32_t, const char *, | 88 | int 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 | |||
84 | void rump_getvninfo(struct vnode *, enum vtype *, off_t * /*XXX*/, dev_t *); | 92 | void rump_getvninfo(struct vnode *, enum vtype *, off_t * /*XXX*/, dev_t *); | |
85 | 93 | |||
86 | int rump_fakeblk_register(const char *); | 94 | int rump_fakeblk_register(const char *); | |
87 | int rump_fakeblk_find(const char *); | 95 | int rump_fakeblk_find(const char *); | |
88 | void rump_fakeblk_deregister(const char *); | 96 | void rump_fakeblk_deregister(const char *); | |
89 | 97 | |||
90 | struct vfsops *rump_vfslist_iterate(struct vfsops *); | 98 | struct vfsops *rump_vfslist_iterate(struct vfsops *); | |
91 | struct vfsops *rump_vfs_getopsbyname(const char *); | 99 | struct vfsops *rump_vfs_getopsbyname(const char *); | |
92 | 100 | |||
93 | struct vattr *rump_vattr_init(void); | 101 | struct vattr *rump_vattr_init(void); | |
94 | void rump_vattr_settype(struct vattr *, enum vtype); | 102 | void rump_vattr_settype(struct vattr *, enum vtype); | |
95 | void rump_vattr_setmode(struct vattr *, mode_t); | 103 | void rump_vattr_setmode(struct vattr *, mode_t); | |
96 | void rump_vattr_setrdev(struct vattr *, dev_t); | 104 | void rump_vattr_setrdev(struct vattr *, dev_t); | |
97 | void rump_vattr_free(struct vattr *); | 105 | void rump_vattr_free(struct vattr *); | |
98 | 106 | |||
99 | void rump_vp_incref(struct vnode *); | 107 | void rump_vp_incref(struct vnode *); | |
100 | int rump_vp_getref(struct vnode *); | 108 | int rump_vp_getref(struct vnode *); | |
101 | void rump_vp_decref(struct vnode *); | 109 | void rump_vp_decref(struct vnode *); | |
102 | void rump_vp_recycle_nokidding(struct vnode *); | 110 | void rump_vp_recycle_nokidding(struct vnode *); | |
103 | void rump_vp_rele(struct vnode *); | 111 | void rump_vp_rele(struct vnode *); | |
104 | 112 | |||
105 | enum rump_uiorw { RUMPUIO_READ, RUMPUIO_WRITE }; | 113 | enum rump_uiorw { RUMPUIO_READ, RUMPUIO_WRITE }; | |
106 | struct uio *rump_uio_setup(void *, size_t, off_t, enum rump_uiorw); | 114 | struct uio *rump_uio_setup(void *, size_t, off_t, enum rump_uiorw); | |
107 | size_t rump_uio_getresid(struct uio *); | 115 | size_t rump_uio_getresid(struct uio *); | |
108 | off_t rump_uio_getoff(struct uio *); | 116 | off_t rump_uio_getoff(struct uio *); | |
109 | size_t rump_uio_free(struct uio *); | 117 | size_t rump_uio_free(struct uio *); | |
110 | 118 | |||
111 | void rump_vp_interlock(struct vnode *); | 119 | void rump_vp_interlock(struct vnode *); | |
112 | 120 | |||
113 | kauth_cred_t rump_cred_create(uid_t, gid_t, size_t, gid_t *); | 121 | kauth_cred_t rump_cred_create(uid_t, gid_t, size_t, gid_t *); | |
114 | kauth_cred_t rump_cred_suserget(void); | 122 | kauth_cred_t rump_cred_suserget(void); | |
115 | void rump_cred_destroy(kauth_cred_t); | 123 | void 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 | |||
122 | int rump_vfs_unmount(struct mount *, int); | 130 | int rump_vfs_unmount(struct mount *, int); | |
123 | int rump_vfs_root(struct mount *, struct vnode **, int); | 131 | int rump_vfs_root(struct mount *, struct vnode **, int); | |
124 | int rump_vfs_statvfs(struct mount *, struct statvfs *); | 132 | int rump_vfs_statvfs(struct mount *, struct statvfs *); | |
125 | int rump_vfs_sync(struct mount *, int, kauth_cred_t); | 133 | int rump_vfs_sync(struct mount *, int, kauth_cred_t); | |
126 | int rump_vfs_fhtovp(struct mount *, struct fid *, struct vnode **); | 134 | int rump_vfs_fhtovp(struct mount *, struct fid *, struct vnode **); | |
127 | int rump_vfs_vptofh(struct vnode *, struct fid *, size_t *); | 135 | int rump_vfs_vptofh(struct vnode *, struct fid *, size_t *); | |
128 | void rump_vfs_syncwait(struct mount *); | 136 | void rump_vfs_syncwait(struct mount *); | |
129 | 137 | |||
130 | struct lwp *rump_newproc_switch(void); | 138 | struct lwp *rump_newproc_switch(void); | |
131 | struct lwp *rump_setup_curlwp(pid_t, lwpid_t, int); | 139 | struct lwp *rump_setup_curlwp(pid_t, lwpid_t, int); | |
132 | struct lwp *rump_get_curlwp(void); | 140 | struct lwp *rump_get_curlwp(void); | |
133 | void rump_clear_curlwp(void); | 141 | void rump_clear_curlwp(void); | |
134 | 142 | |||
135 | void rump_rcvp_set(struct vnode *, struct vnode *); | 143 | void rump_rcvp_set(struct vnode *, struct vnode *); | |
136 | struct vnode *rump_cdir_get(void); | 144 | struct 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 */ | |
139 | int rump_syspuffs_glueinit(int, int *); | 147 | int rump_syspuffs_glueinit(int, int *); | |
140 | 148 | |||
141 | int rump_virtif_create(int); | 149 | int rump_virtif_create(int); | |
142 | 150 | |||
143 | typedef int (*rump_sysproxy_t)(int, void *, uint8_t *, size_t, register_t *); | 151 | typedef int (*rump_sysproxy_t)(int, void *, uint8_t *, size_t, register_t *); | |
144 | int rump_sysproxy_set(rump_sysproxy_t, void *); | 152 | int rump_sysproxy_set(rump_sysproxy_t, void *); | |
145 | int rump_sysproxy_socket_setup_client(int); | 153 | int rump_sysproxy_socket_setup_client(int); | |
146 | int rump_sysproxy_socket_setup_server(int); | 154 | int 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_ */ |
--- 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 | |||
69 | struct proc proc0; | 69 | struct proc proc0; | |
70 | struct session rump_session = { | 70 | struct 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 | }; | |
77 | struct pgrp rump_pgrp = { | 77 | struct 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 | }; | |
82 | struct pstats rump_stats; | 82 | struct pstats rump_stats; | |
83 | struct plimit rump_limits; | 83 | struct plimit rump_limits; | |
84 | struct cpu_info rump_cpu; | 84 | struct cpu_info rump_cpu; | |
85 | struct filedesc rump_filedesc0; | 85 | struct filedesc rump_filedesc0; | |
86 | struct proclist allproc; | 86 | struct proclist allproc; | |
87 | char machine[] = "rump"; | 87 | char machine[] = "rump"; | |
88 | static kauth_cred_t rump_susercred; | 88 | static kauth_cred_t rump_susercred; | |
89 | 89 | |||
90 | /* pretend the master rump proc is init */ | 90 | /* pretend the master rump proc is init */ | |
91 | struct proc *initproc = &proc0; | 91 | struct proc *initproc = &proc0; | |
92 | 92 | |||
93 | struct rumpuser_mtx *rump_giantlock; | 93 | struct rumpuser_mtx *rump_giantlock; | |
94 | 94 | |||
95 | sigset_t sigcantmask; | 95 | sigset_t sigcantmask; | |
96 | 96 | |||
97 | #ifdef RUMP_WITHOUT_THREADS | 97 | #ifdef RUMP_WITHOUT_THREADS | |
98 | int rump_threads = 0; | 98 | int rump_threads = 0; | |
99 | #else | 99 | #else | |
100 | int rump_threads = 1; | 100 | int rump_threads = 1; | |
101 | #endif | 101 | #endif | |
102 | 102 | |||
103 | static void | 103 | static void | |
104 | rump_aiodone_worker(struct work *wk, void *dummy) | 104 | rump_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 | |||
112 | static int rump_inited; | 112 | static int rump_inited; | |
113 | static struct emul emul_rump; | 113 | static struct emul emul_rump; | |
114 | 114 | |||
115 | void rump__unavailable(void); | 115 | void rump__unavailable(void); | |
116 | void rump__unavailable() {} | 116 | void 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 | |||
120 | void rump__unavailable_vfs_panic(void); | 120 | void rump__unavailable_vfs_panic(void); | |
121 | void rump__unavailable_vfs_panic() {panic("vfs component not available");} | 121 | void 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 | |||
126 | static void | 126 | static void | |
127 | pvfsinit_nop(struct proc *p) | 127 | pvfsinit_nop(struct proc *p) | |
128 | { | 128 | { | |
129 | 129 | |||
130 | return; | 130 | return; | |
131 | } | 131 | } | |
132 | 132 | |||
133 | static void | 133 | static void | |
134 | pvfsrele_nop(struct proc *p) | 134 | pvfsrele_nop(struct proc *p) | |
135 | { | 135 | { | |
136 | 136 | |||
137 | return; | 137 | return; | |
138 | } | 138 | } | |
139 | 139 | |||
140 | rump_proc_vfs_init_fn rump_proc_vfs_init = pvfsinit_nop; | 140 | rump_proc_vfs_init_fn rump_proc_vfs_init = pvfsinit_nop; | |
141 | rump_proc_vfs_release_fn rump_proc_vfs_release = pvfsrele_nop; | 141 | rump_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 | */ | |
148 | void nullfn(uint32_t *); | 148 | void nullfn(uint32_t *); | |
149 | void nullfn(uint32_t *arg){} | 149 | void nullfn(uint32_t *arg){} | |
150 | void messthestack(void); | 150 | void messthestack(void); | |
151 | void | 151 | void | |
152 | messthestack(void) | 152 | messthestack(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 | |||
165 | int | 165 | int | |
166 | rump__init(int rump_version) | 166 | rump__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 | |||
278 | struct uio * | 278 | struct uio * | |
279 | rump_uio_setup(void *buf, size_t bufsize, off_t offset, enum rump_uiorw rw) | 279 | rump_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 | |||
310 | size_t | 310 | size_t | |
311 | rump_uio_getresid(struct uio *uio) | 311 | rump_uio_getresid(struct uio *uio) | |
312 | { | 312 | { | |
313 | 313 | |||
314 | return uio->uio_resid; | 314 | return uio->uio_resid; | |
315 | } | 315 | } | |
316 | 316 | |||
317 | off_t | 317 | off_t | |
318 | rump_uio_getoff(struct uio *uio) | 318 | rump_uio_getoff(struct uio *uio) | |
319 | { | 319 | { | |
320 | 320 | |||
321 | return uio->uio_offset; | 321 | return uio->uio_offset; | |
322 | } | 322 | } | |
323 | 323 | |||
324 | size_t | 324 | size_t | |
325 | rump_uio_free(struct uio *uio) | 325 | rump_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 */ | |
337 | static pid_t nextpid = 1; | 337 | static pid_t nextpid = 1; | |
338 | struct lwp * | 338 | struct lwp * | |
339 | rump_newproc_switch() | 339 | rump_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 */ | |
355 | struct lwp * | 355 | struct lwp * | |
356 | rump_setup_curlwp(pid_t pid, lwpid_t lid, int set) | 356 | rump_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! */ | |
388 | void | 388 | void | |
389 | rump_set_vmspace(struct vmspace *vm) | 389 | rump_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 | |||
396 | void | 396 | void | |
397 | rump_clear_curlwp(void) | 397 | rump_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 | |||
414 | struct lwp * | 414 | struct lwp * | |
415 | rump_get_curlwp(void) | 415 | rump_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 | |||
426 | kauth_cred_t | 426 | kauth_cred_t | |
427 | rump_cred_create(uid_t uid, gid_t gid, size_t ngroups, gid_t *groups) | 427 | rump_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 | |||
447 | void | 447 | void | |
448 | rump_cred_destroy(kauth_cred_t cred) | 448 | rump_cred_destroy(kauth_cred_t cred) | |
449 | { | 449 | { | |
450 | 450 | |||
451 | kauth_cred_free(cred); | 451 | kauth_cred_free(cred); | |
452 | } | 452 | } | |
453 | 453 | |||
454 | kauth_cred_t | 454 | kauth_cred_t | |
455 | rump_cred_suserget(void) | 455 | rump_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 | */ | |
465 | lwpid_t | 465 | lwpid_t | |
466 | rump_nextlid(void) | 466 | rump_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 | |||
484 | int | 484 | int | |
485 | rump_module_load(struct modinfo **mi) | 485 | rump_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 | ||||
494 | int | |||
495 | rump_module_fini(struct modinfo *mi) | |||
496 | { | |||
497 | ||||
498 | return mi->mi_modcmd(MODULE_CMD_FINI, NULL); | |||
492 | } | 499 | } | |
493 | 500 | |||
494 | int _syspuffs_stub(int, int *); | 501 | int _syspuffs_stub(int, int *); | |
495 | int | 502 | int | |
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 | |||
503 | static int | 510 | static int | |
504 | rump_sysproxy_local(int num, void *arg, uint8_t *data, size_t dlen, | 511 | rump_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 | |||
518 | rump_sysproxy_t rump_sysproxy = rump_sysproxy_local; | 525 | rump_sysproxy_t rump_sysproxy = rump_sysproxy_local; | |
519 | void *rump_sysproxy_arg; | 526 | void *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 | */ | |
527 | int | 534 | int | |
528 | rump_sysproxy_set(rump_sysproxy_t proxy, void *arg) | 535 | rump_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 | } |