int rump_shmif_create(const char *path, int *ifnum) { struct shmif_sc *sc; vmem_addr_t t; int unit, error; int memfd = -1; /* XXXgcc */ if (path) { error = rumpuser_open(path, RUMPUSER_OPEN_RDWR | RUMPUSER_OPEN_CREATE, &memfd); if (error) return error; } error = vmem_xalloc(shmif_units, 1, 0, 0, 0, VMEM_ADDR_MIN, VMEM_ADDR_MAX, VM_INSTANTFIT | VM_SLEEP, &t); if (error != 0) { if (path) rumpuser_close(memfd); return error; } unit = t - 1; if ((error = allocif(unit, &sc)) != 0) { if (path) rumpuser_close(memfd); return error; } if (!path) goto out; error = initbackend(sc, memfd); if (error) { shmif_unclone(&sc->sc_ec.ec_if); return error; } sc->sc_backfilelen = strlen(path)+1; sc->sc_backfile = kmem_alloc(sc->sc_backfilelen, KM_SLEEP); strcpy(sc->sc_backfile, path); out: if (ifnum) *ifnum = unit; return 0; }
int scsitest_match(device_t parent, cfdata_t match, void *aux) { #ifdef USE_TOSI_ISO uint64_t fsize; int error, ft; if (rumpuser_getfileinfo(MYCDISO, &fsize, &ft, &error)) return 0; if (ft != RUMPUSER_FT_REG) return 0; mycdsize = fsize / CDBLOCKSIZE; if ((isofd = rumpuser_open(MYCDISO, RUMPUSER_OPEN_RDWR, &error)) == -1) return 0; #else /* * We pretend to have a medium present initially, so != -1. */ isofd = -2; #endif return 1; }
static int shmif_ioctl(struct ifnet *ifp, u_long cmd, void *data) { struct shmif_sc *sc = ifp->if_softc; struct ifdrv *ifd; char *path; int s, rv, memfd; s = splnet(); switch (cmd) { case SIOCGLINKSTR: ifd = data; if (sc->sc_backfilelen == 0) { rv = ENOENT; break; } ifd->ifd_len = sc->sc_backfilelen; if (ifd->ifd_cmd == IFLINKSTR_QUERYLEN) { rv = 0; break; } if (ifd->ifd_cmd != 0) { rv = EINVAL; break; } rv = copyoutstr(sc->sc_backfile, ifd->ifd_data, MIN(sc->sc_backfilelen, ifd->ifd_len), NULL); break; case SIOCSLINKSTR: if (ifp->if_flags & IFF_UP) { rv = EBUSY; break; } ifd = data; if (ifd->ifd_cmd == IFLINKSTR_UNSET) { finibackend(sc); rv = 0; break; } else if (ifd->ifd_cmd != 0) { rv = EINVAL; break; } else if (sc->sc_backfile) { rv = EBUSY; break; } if (ifd->ifd_len > MAXPATHLEN) { rv = E2BIG; break; } else if (ifd->ifd_len < 1) { rv = EINVAL; break; } path = kmem_alloc(ifd->ifd_len, KM_SLEEP); rv = copyinstr(ifd->ifd_data, path, ifd->ifd_len, NULL); if (rv) { kmem_free(path, ifd->ifd_len); break; } rv = rumpuser_open(path, RUMPUSER_OPEN_RDWR | RUMPUSER_OPEN_CREATE, &memfd); if (rv) { kmem_free(path, ifd->ifd_len); break; } rv = initbackend(sc, memfd); if (rv) { kmem_free(path, ifd->ifd_len); rumpuser_close(memfd); break; } sc->sc_backfile = path; sc->sc_backfilelen = ifd->ifd_len; break; default: rv = ether_ioctl(ifp, cmd, data); if (rv == ENETRESET) rv = 0; break; } splx(s); return rv; }
static int virtif_create(struct ifaliasreq *ia, struct ifnet **ifpp) { struct virtif_sc *sc; struct ifreq ifr; struct ifnet *ifp; uint8_t enaddr[ETHER_ADDR_LEN] = { 0xb2, 0x0a, 0x00, 0x0b, 0x0e, 0x01 }; int fd, rv, error; int mynum; /* * XXX: this is currently un-sane. Need to figure out a way * to configure this with a bridge into a sane network without * hardcoding it. */ fd = rumpuser_open("/dev/tap0", O_RDWR, &error); if (fd == -1) { printf("virtif_create: can't open /dev/tap %d\n", error); return error; } sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); rv = rumpuser_ioctl(fd, TAPGIFNAME, &ifr, &error); if (rv == -1) { kmem_free(sc, sizeof(*sc)); return error; } strlcpy(sc->sc_tapname, ifr.ifr_name, IFNAMSIZ); sc->sc_tapfd = fd; ifp = &sc->sc_if; mynum = nunits++; sprintf(ifp->if_xname, "%s%d", VIRTIF_BASE, mynum); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_init = virtif_init; ifp->if_ioctl = virtif_ioctl; ifp->if_start = virtif_start; ifp->if_stop = virtif_stop; if (rump_threads) { rv = kthread_create(PRI_NONE, 0, NULL, virtif_worker, ifp, NULL, "virtifi"); if (rv) { kmem_free(sc, sizeof(*sc)); return rv; } } else { printf("WARNING: threads not enabled, receive NOT working\n"); } if_attach(ifp); ether_ifattach(ifp, enaddr); if (ia) configaddr(ifp, ia); if (ifpp) *ifpp = ifp; return 0; }