rump.c revision 1.2 1 /* $NetBSD: rump.c,v 1.2 2007/08/06 22:20:57 pooka Exp $ */
2
3 /*
4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
5 *
6 * Development of this software was supported by Google Summer of Code.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
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
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #include <sys/param.h>
31 #include <sys/filedesc.h>
32 #include <sys/kauth.h>
33 #include <sys/mount.h>
34 #include <sys/namei.h>
35 #include <sys/queue.h>
36 #include <sys/resourcevar.h>
37 #include <sys/vnode.h>
38
39 #include <machine/cpu.h>
40
41 #include "rump.h"
42 #include "rumpuser.h"
43
44 struct proc rump_proc;
45 struct cwdinfo rump_cwdi;
46 struct pstats rump_stats;
47 struct plimit rump_limits;
48 kauth_cred_t rump_cred;
49 struct cpu_info rump_cpu;
50
51 struct fakeblk {
52 char path[MAXPATHLEN];
53 LIST_ENTRY(fakeblk) entries;
54 };
55
56 static LIST_HEAD(, fakeblk) fakeblks = LIST_HEAD_INITIALIZER(fakeblks);
57
58 void
59 rump_init()
60 {
61 extern char hostname[];
62 extern size_t hostnamelen;
63 int error;
64
65 curlwp = &lwp0;
66 rumpvm_init();
67
68 curlwp->l_proc = &rump_proc;
69 curlwp->l_cred = rump_cred;
70 rump_proc.p_stats = &rump_stats;
71 rump_proc.p_cwdi = &rump_cwdi;
72 rump_limits.pl_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
73 rump_proc.p_limit = &rump_limits;
74
75 vfsinit();
76
77 rumpuser_gethostname(hostname, MAXHOSTNAMELEN, &error);
78 hostnamelen = strlen(hostname);
79 }
80
81 void
82 rump_mountinit(struct mount **mpp, struct vfsops *vfsops)
83 {
84 struct mount *mp;
85
86 mp = rumpuser_malloc(sizeof(struct mount), 0);
87 memset(mp, 0, sizeof(struct mount));
88
89 mp->mnt_op = vfsops;
90 TAILQ_INIT(&mp->mnt_vnodelist);
91 *mpp = mp;
92 }
93
94 void
95 rump_mountdestroy(struct mount *mp)
96 {
97
98 rumpuser_free(mp);
99 }
100
101 struct componentname *
102 rump_makecn(u_long nameiop, u_long flags, const char *name, size_t namelen,
103 struct lwp *l)
104 {
105 struct componentname *cnp;
106
107 cnp = rumpuser_malloc(sizeof(struct componentname), 0);
108 memset(cnp, 0, sizeof(struct componentname));
109
110 cnp->cn_nameiop = nameiop;
111 cnp->cn_flags = flags;
112
113 cnp->cn_pnbuf = PNBUF_GET();
114 strcpy(cnp->cn_pnbuf, name);
115 cnp->cn_nameptr = cnp->cn_pnbuf;
116 cnp->cn_namelen = namelen;
117
118 cnp->cn_cred = l->l_cred;
119 cnp->cn_lwp = l;
120
121 return cnp;
122 }
123
124 void
125 rump_freecn(struct componentname *cnp, int islookup)
126 {
127
128 if (cnp->cn_flags & SAVENAME) {
129 if (islookup || cnp->cn_flags & SAVESTART)
130 PNBUF_PUT(cnp->cn_pnbuf);
131 } else {
132 PNBUF_PUT(cnp->cn_pnbuf);
133 }
134 rumpuser_free(cnp);
135 }
136
137 int
138 rump_recyclenode(struct vnode *vp)
139 {
140
141 return vrecycle(vp, NULL, curlwp);
142 }
143
144 static struct fakeblk *
145 _rump_fakeblk_find(const char *path)
146 {
147 char buf[MAXPATHLEN];
148 struct fakeblk *fblk;
149
150 rumpuser_realpath(path, buf);
151
152 LIST_FOREACH(fblk, &fakeblks, entries)
153 if (strcmp(fblk->path, buf) == 0)
154 return fblk;
155
156 return NULL;
157 }
158
159 int
160 rump_fakeblk_register(const char *path)
161 {
162 char buf[MAXPATHLEN];
163 struct fakeblk *fblk;
164
165 if (_rump_fakeblk_find(path))
166 return EEXIST;
167
168 fblk = rumpuser_malloc(sizeof(struct fakeblk), 1);
169 if (fblk == NULL)
170 return ENOMEM;
171
172 strlcpy(fblk->path, rumpuser_realpath(path, buf), MAXPATHLEN);
173 LIST_INSERT_HEAD(&fakeblks, fblk, entries);
174
175 return 0;
176 }
177
178 int
179 rump_fakeblk_find(const char *path)
180 {
181
182 return _rump_fakeblk_find(path) != NULL;
183 }
184
185 void
186 rump_fakeblk_deregister(const char *path)
187 {
188 struct fakeblk *fblk;
189
190 fblk = _rump_fakeblk_find(path);
191 if (fblk == NULL)
192 panic("%s: invalid path \"%s\"", __func__, path);
193
194 LIST_REMOVE(fblk, entries);
195 rumpuser_free(fblk);
196 }
197