/*
 * cuse_info is populated and used to register the cuse device. vhost_net_device_ops are
 * also passed when the device is registered in main.c.
 */
int
register_cuse_device(const char *base_name, int index, struct vhost_net_device_ops const * const pops)
{
	struct cuse_info cuse_info;
	char device_name[PATH_MAX] = "";
	char char_device_name[PATH_MAX] = "";
	const char *device_argv[] = { device_name };

	char fuse_opt_dummy[] = FUSE_OPT_DUMMY;
	char fuse_opt_fore[] = FUSE_OPT_FORE;
	char fuse_opt_nomulti[] = FUSE_OPT_NOMULTI;
	char *fuse_argv[] = {fuse_opt_dummy, fuse_opt_fore, fuse_opt_nomulti};

	if (access(cuse_device_name, R_OK | W_OK) < 0) {
		RTE_LOG(ERR, CONFIG, "Character device %s can't be accessed, maybe not exist\n", cuse_device_name);
		return -1;
	}

	/*
	 * The device name is created. This is passed to QEMU so that it can register
	 * the device with our application. The index allows us to have multiple instances
	 * of userspace vhost which we can then add devices to separately.
	 */
	if (strncmp(base_name, default_cdev, PATH_MAX)!=0) {
		rte_snprintf(device_name, PATH_MAX, "DEVNAME=%s-%d", base_name, index);
		rte_snprintf(char_device_name, PATH_MAX, "/dev/%s-%d", base_name, index);
	} else {
		rte_snprintf(device_name, PATH_MAX, "DEVNAME=%s", base_name);
		rte_snprintf(char_device_name, PATH_MAX, "/dev/%s", base_name);
	}

	/* Check if device already exists. */
	if (access(char_device_name, F_OK) != -1) {
		RTE_LOG(ERR, CONFIG, "Character device %s already exists\n", char_device_name);
		return -1;
	}

	memset(&cuse_info, 0, sizeof(cuse_info));
	cuse_info.dev_major = default_major;
	cuse_info.dev_minor = default_minor + index;
	cuse_info.dev_info_argc = 1;
	cuse_info.dev_info_argv = device_argv;
	cuse_info.flags = CUSE_UNRESTRICTED_IOCTL;

	ops = pops;

	session = cuse_lowlevel_setup(3, fuse_argv,
				&cuse_info, &vhost_net_ops, 0, NULL);
	if (session == NULL)
		return -1;

	return 0;
}
Esempio n. 2
0
/*
 * cuse_info is populated and used to register the cuse device.
 * vhost_net_device_ops are also passed when the device is registered in app.
 */
int
rte_vhost_driver_register(const char *dev_name)
{
	struct cuse_info cuse_info;
	char device_name[PATH_MAX] = "";
	char char_device_name[PATH_MAX] = "";
	const char *device_argv[] = { device_name };

	char fuse_opt_dummy[] = FUSE_OPT_DUMMY;
	char fuse_opt_fore[] = FUSE_OPT_FORE;
	char fuse_opt_nomulti[] = FUSE_OPT_NOMULTI;
	char *fuse_argv[] = {fuse_opt_dummy, fuse_opt_fore, fuse_opt_nomulti};

	if (access(cuse_device_name, R_OK | W_OK) < 0) {
		RTE_LOG(ERR, VHOST_CONFIG,
			"char device %s can't be accessed, maybe not exist\n",
			cuse_device_name);
		return -1;
	}

	if (eventfd_init() < 0)
		return -1;

	/*
	 * The device name is created. This is passed to QEMU so that it can
	 * register the device with our application.
	 */
	snprintf(device_name, PATH_MAX, "DEVNAME=%s", dev_name);
	snprintf(char_device_name, PATH_MAX, "/dev/%s", dev_name);

	/* Check if device already exists. */
	if (access(char_device_name, F_OK) != -1) {
		RTE_LOG(ERR, VHOST_CONFIG,
			"char device %s already exists\n", char_device_name);
		return -1;
	}

	memset(&cuse_info, 0, sizeof(cuse_info));
	cuse_info.dev_major = default_major;
	cuse_info.dev_minor = default_minor;
	cuse_info.dev_info_argc = 1;
	cuse_info.dev_info_argv = device_argv;
	cuse_info.flags = CUSE_UNRESTRICTED_IOCTL;

	session = cuse_lowlevel_setup(3, fuse_argv,
			&cuse_info, &vhost_net_ops, 0, NULL);
	if (session == NULL)
		return -1;

	return 0;
}
int cuse_lowlevel_main(int argc, char *argv[], const struct cuse_info *ci,
		       const struct cuse_lowlevel_ops *clop, void *userdata)
{
	struct fuse_session *se;
	int multithreaded;
	int res;

	se = cuse_lowlevel_setup(argc, argv, ci, clop, &multithreaded,
				 userdata);
	if (se == NULL)
		return 1;

	if (multithreaded)
		res = fuse_session_loop_mt(se);
	else
		res = fuse_session_loop(se);

	cuse_lowlevel_teardown(se);
	if (res == -1)
		return 1;

	return 0;
}