Home | History | Annotate | Line # | Download | only in rumpkern
rump.c revision 1.7
      1 /*	$NetBSD: rump.c,v 1.7 2007/08/16 19:50:19 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 <miscfs/specfs/specdev.h>
     42 
     43 #include "rump.h"
     44 #include "rumpuser.h"
     45 
     46 struct proc rump_proc;
     47 struct cwdinfo rump_cwdi;
     48 struct pstats rump_stats;
     49 struct plimit rump_limits;
     50 kauth_cred_t rump_cred;
     51 struct cpu_info rump_cpu;
     52 
     53 struct fakeblk {
     54 	char path[MAXPATHLEN];
     55 	LIST_ENTRY(fakeblk) entries;
     56 };
     57 
     58 static LIST_HEAD(, fakeblk) fakeblks = LIST_HEAD_INITIALIZER(fakeblks);
     59 
     60 void
     61 rump_init()
     62 {
     63 	extern char hostname[];
     64 	extern size_t hostnamelen;
     65 	int error;
     66 
     67 	curlwp = &lwp0;
     68 	rumpvm_init();
     69 
     70 	curlwp->l_proc = &rump_proc;
     71 	curlwp->l_cred = rump_cred;
     72 	rump_proc.p_stats = &rump_stats;
     73 	rump_proc.p_cwdi = &rump_cwdi;
     74 	rump_limits.pl_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
     75 	rump_proc.p_limit = &rump_limits;
     76 
     77 	vfsinit();
     78 	bufinit();
     79 
     80 	rumpuser_gethostname(hostname, MAXHOSTNAMELEN, &error);
     81 	hostnamelen = strlen(hostname);
     82 }
     83 
     84 void
     85 rump_mountinit(struct mount **mpp, struct vfsops *vfsops)
     86 {
     87 	struct mount *mp;
     88 
     89 	mp = rumpuser_malloc(sizeof(struct mount), 0);
     90 	memset(mp, 0, sizeof(struct mount));
     91 
     92 	mp->mnt_op = vfsops;
     93 	TAILQ_INIT(&mp->mnt_vnodelist);
     94 	*mpp = mp;
     95 }
     96 
     97 void
     98 rump_mountdestroy(struct mount *mp)
     99 {
    100 
    101 	rumpuser_free(mp);
    102 }
    103 
    104 struct componentname *
    105 rump_makecn(u_long nameiop, u_long flags, const char *name, size_t namelen,
    106 	struct lwp *l)
    107 {
    108 	struct componentname *cnp;
    109 
    110 	cnp = rumpuser_malloc(sizeof(struct componentname), 0);
    111 	memset(cnp, 0, sizeof(struct componentname));
    112 
    113 	cnp->cn_nameiop = nameiop;
    114 	cnp->cn_flags = flags;
    115 
    116 	cnp->cn_pnbuf = PNBUF_GET();
    117 	strcpy(cnp->cn_pnbuf, name);
    118 	cnp->cn_nameptr = cnp->cn_pnbuf;
    119 	cnp->cn_namelen = namelen;
    120 
    121 	cnp->cn_cred = l->l_cred;
    122 	cnp->cn_lwp = l;
    123 
    124 	return cnp;
    125 }
    126 
    127 void
    128 rump_freecn(struct componentname *cnp, int islookup)
    129 {
    130 
    131 	if (cnp->cn_flags & SAVENAME) {
    132 		if (islookup || cnp->cn_flags & SAVESTART)
    133 			PNBUF_PUT(cnp->cn_pnbuf);
    134 	} else {
    135 		PNBUF_PUT(cnp->cn_pnbuf);
    136 	}
    137 	rumpuser_free(cnp);
    138 }
    139 
    140 int
    141 rump_recyclenode(struct vnode *vp)
    142 {
    143 
    144 	return vrecycle(vp, NULL, curlwp);
    145 }
    146 
    147 static struct fakeblk *
    148 _rump_fakeblk_find(const char *path)
    149 {
    150 	char buf[MAXPATHLEN];
    151 	struct fakeblk *fblk;
    152 	int error;
    153 
    154 	if (rumpuser_realpath(path, buf, &error) == NULL)
    155 		return NULL;
    156 
    157 	LIST_FOREACH(fblk, &fakeblks, entries)
    158 		if (strcmp(fblk->path, buf) == 0)
    159 			return fblk;
    160 
    161 	return NULL;
    162 }
    163 
    164 int
    165 rump_fakeblk_register(const char *path)
    166 {
    167 	char buf[MAXPATHLEN];
    168 	struct fakeblk *fblk;
    169 	int error;
    170 
    171 	if (_rump_fakeblk_find(path))
    172 		return EEXIST;
    173 
    174 	if (rumpuser_realpath(path, buf, &error) == NULL)
    175 		return error;
    176 
    177 	fblk = rumpuser_malloc(sizeof(struct fakeblk), 1);
    178 	if (fblk == NULL)
    179 		return ENOMEM;
    180 
    181 	strlcpy(fblk->path, buf, MAXPATHLEN);
    182 	LIST_INSERT_HEAD(&fakeblks, fblk, entries);
    183 
    184 	return 0;
    185 }
    186 
    187 int
    188 rump_fakeblk_find(const char *path)
    189 {
    190 
    191 	return _rump_fakeblk_find(path) != NULL;
    192 }
    193 
    194 void
    195 rump_fakeblk_deregister(const char *path)
    196 {
    197 	struct fakeblk *fblk;
    198 
    199 	fblk = _rump_fakeblk_find(path);
    200 	if (fblk == NULL)
    201 		return;
    202 
    203 	LIST_REMOVE(fblk, entries);
    204 	rumpuser_free(fblk);
    205 }
    206 
    207 void
    208 rump_getvninfo(struct vnode *vp, enum vtype *vtype, voff_t *vsize, dev_t *vdev)
    209 {
    210 
    211 	*vtype = vp->v_type;
    212 	*vsize = vp->v_size;
    213 	if (vp->v_specinfo)
    214 		*vdev = vp->v_rdev;
    215 	else
    216 		*vdev = 0;
    217 }
    218 
    219 struct vfsops *
    220 rump_vfslist_iterate(struct vfsops *ops)
    221 {
    222 
    223 	if (ops == NULL)
    224 		return LIST_FIRST(&vfs_list);
    225 	else
    226 		return LIST_NEXT(ops, vfs_list);
    227 }
    228 
    229 struct vfsops *
    230 rump_vfs_getopsbyname(const char *name)
    231 {
    232 
    233 	return vfs_getopsbyname(name);
    234 }
    235 
    236 void
    237 rump_vattr_null(struct vattr *vap)
    238 {
    239 
    240 	vattr_null(vap);
    241 }
    242