1/* 2 * rump_dev_xen.c 3 * 4 * Machinery for setting up the contents of /dev/xen* in a rumpkernel. 5 * 6 * Copyright (c) 2014 Citrix 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * of this source file (the "Software"), to deal in the Software without 10 * restriction, including without limitation the rights to use, copy, modify, 11 * merge, publish, distribute, sublicense, and/or sell copies of the Software, 12 * and to permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in 16 * all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 * IN THE SOFTWARE. 25 */ 26 27#include <sys/cdefs.h> 28__KERNEL_RCSID(0, "$NetBSD: $"); 29 30#include "rumpxen_xendev.h" 31 32#include "rump_private.h" 33#include "rump_vfs_private.h" 34 35#include <sys/vfs_syscalls.h> 36#include <sys/dirent.h> 37#include <miscfs/kernfs/kernfs.h> 38 39char *xbd_strdup(const char *s) 40{ 41 char *r; 42 size_t l = strlen(s) + 1; 43 r = xbd_malloc(l); 44 if (!r) 45 return r; 46 memcpy(r, s, l); 47 return r; 48} 49 50#define DEV_XEN "/dev/xen" 51 52static const struct xen_dev_info { 53 const char *path; 54 void (*xd_init)(void); 55 int (*xd_open)(struct file *fp, void **fdata_r); 56 const struct fileops *fo; 57} devs[] = { 58#define XDEV(cmin, path, init_fn, component) \ 59 [cmin] = { path, init_fn, component##_dev_open, \ 60 &component##_dev_fileops } 61 XDEV(0, DEV_XEN "/xenbus", NULL, xenbus), 62// XDEV(1, "/dev/xenevt", xenevt_dev_init, xenevt), XXX issue #73 63#undef XDEV 64}; 65 66#define NUM_DEV_INFOS (sizeof(devs)/sizeof(devs[0])) 67 68static int 69xen_dev_open(dev_t dev, int flags, int mode, struct lwp *l) 70{ 71 const struct xen_dev_info *xdinfo; 72 int fd, err; 73 struct file *fp; 74 void *fdata; 75 76 DPRINTF(("xen devsw: opening minor=%lu\n", (unsigned long)minor(dev))); 77 78 if (minor(dev) < 0 || minor(dev) >= NUM_DEV_INFOS) 79 return ENODEV; 80 81 xdinfo = &devs[minor(dev)]; 82 83 if (!xdinfo->xd_open) 84 return ENODEV; 85 86 err = fd_allocfile(&fp, &fd); 87 if (err) 88 return err; 89 90 DPRINTF(("%s: opening...\n", xdinfo->path)); 91 92 err = xdinfo->xd_open(fp, &fdata); 93 if (err) { 94 fd_abort(curproc, fp, fd); 95 return err; 96 } 97 98 DPRINTF(("%s: opened, fd_clone\n", xdinfo->path)); 99 100 return fd_clone(fp, fd, flags, xdinfo->fo, fdata); 101} 102 103static const struct cdevsw xen_dev_cdevsw = { 104 .d_open = xen_dev_open, 105 .d_close = nullclose, 106 .d_read = noread, 107 .d_write = nowrite, 108 .d_ioctl = noioctl, 109 .d_stop = nostop, 110 .d_tty = notty, 111 .d_poll = nopoll, 112 .d_mmap = nommap, 113 .d_kqfilter = nokqfilter, 114 .d_flag = D_OTHER 115}; 116 117#define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) 118kernfs_parentdir_t *kernxen_pkt; 119static void xenkernfs_init(void) 120{ 121 kernfs_entry_t *dkt; 122 KERNFS_ALLOCENTRY(dkt, M_TEMP, M_WAITOK); 123 KERNFS_INITENTRY(dkt, DT_DIR, "xen", NULL, KFSsubdir, VDIR, DIR_MODE); 124 kernfs_addentry(NULL, dkt); 125 kernxen_pkt = KERNFS_ENTOPARENTDIR(dkt); 126} 127 128RUMP_COMPONENT(RUMP_COMPONENT_DEV) 129{ 130 devmajor_t bmaj, cmaj; 131 devminor_t cmin; 132 int err; 133 const struct xen_dev_info *xdinfo; 134 135 DPRINTF(("xen devsw: attaching\n")); 136 137 err = do_sys_mkdir(DEV_XEN, 0755, UIO_SYSSPACE); 138 if (err && err != EEXIST) 139 panic("xen devsw: mkdir " DEV_XEN " failed: %d", err); 140 141 bmaj = cmaj = NODEVMAJOR; 142 err = devsw_attach("xen", NULL, &bmaj, &xen_dev_cdevsw, &cmaj); 143 if (err) 144 panic("xen devsw: attach failed: %d", err); 145 146 for (cmin = 0; cmin < NUM_DEV_INFOS; cmin++) { 147 xdinfo = &devs[cmin]; 148 err = rump_vfs_makeonedevnode(S_IFCHR, xdinfo->path, cmaj, cmin); 149 if (err) 150 panic("%s: cannot create device node: %d", 151 xdinfo->path, err); 152 if (xdinfo->xd_init) 153 xdinfo->xd_init(); 154 DPRINTF(("%s: created, %lu.%lu\n", 155 xdinfo->path, (unsigned long)cmaj, (unsigned long)cmin)); 156 } 157 158 xenkernfs_init(); 159// xenprivcmd_init(); XXX issue #73 160} 161 162/* 163 * Local variables: 164 * c-file-style: "linux" 165 * indent-tabs-mode: t 166 * c-indent-level: 8 167 * c-basic-offset: 8 168 * tab-width: 8 169 * End: 170 */ 171 172