Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}