Commit 1dae5633 authored by Darek Stojaczyk's avatar Darek Stojaczyk Committed by Tomasz Zawadzki
Browse files

vhost: move rte_vhost socket creation to rte_vhost_compat.c



rte_vhost_compat.c will now not only handle vhost-user
messages over the unix domain socket, but also setup
that unix domain socket with rte_vhost's APIs.

What was previously called vhost_dev_install_rte_compat_hooks()
is now called vhost_register_unix_socket() and is responsible
for creating the entire unix domain socket.

This enables us to write more advanced unit tests for vhost.
Instead of mocking low-level rte_vhost APIs, we could
now potentially mock vhost_register_unix_socket() and
create vhost devices and sessions without any actual
unix domain sockets involved.

Change-Id: Ifb18b92b37915c3f683b6d4fcdcc9259a3770561
Signed-off-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Signed-off-by: default avatarVitaliy Mysak <vitaliy.mysak@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/470455


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 8e68dfd9
Loading
Loading
Loading
Loading
+61 −15
Original line number Diff line number Diff line
@@ -48,9 +48,10 @@

#include "spdk_internal/vhost_user.h"

#ifndef SPDK_CONFIG_VHOST_INTERNAL_LIB
extern const struct vhost_device_ops g_spdk_vhost_ops;

#ifndef SPDK_CONFIG_VHOST_INTERNAL_LIB

static enum rte_vhost_msg_result
spdk_extern_vhost_pre_msg_handler(int vid, void *_msg)
{
@@ -215,26 +216,71 @@ vhost_session_install_rte_compat_hooks(struct spdk_vhost_session *vsession)
	}
}

void
vhost_dev_install_rte_compat_hooks(struct spdk_vhost_dev *vdev)
{
	uint64_t protocol_features = 0;

	rte_vhost_driver_get_protocol_features(vdev->path, &protocol_features);
	protocol_features |= (1ULL << VHOST_USER_PROTOCOL_F_CONFIG);
	rte_vhost_driver_set_protocol_features(vdev->path, protocol_features);
}

#else /* SPDK_CONFIG_VHOST_INTERNAL_LIB */

void
vhost_session_install_rte_compat_hooks(struct spdk_vhost_session *vsession)
{
	/* nothing to do. all the changes are already incorporated into rte_vhost */
}

void
vhost_dev_install_rte_compat_hooks(struct spdk_vhost_dev *vdev)
#endif

int
vhost_register_unix_socket(const char *path, const char *ctrl_name,
			   uint64_t virtio_features, uint64_t disabled_features)
{
	/* nothing to do */
	struct stat file_stat;
#ifndef SPDK_CONFIG_VHOST_INTERNAL_LIB
	uint64_t protocol_features = 0;
#endif

	/* Register vhost driver to handle vhost messages. */
	if (stat(path, &file_stat) != -1) {
		if (!S_ISSOCK(file_stat.st_mode)) {
			SPDK_ERRLOG("Cannot create a domain socket at path \"%s\": "
				    "The file already exists and is not a socket.\n",
				    path);
			return -EIO;
		} else if (unlink(path) != 0) {
			SPDK_ERRLOG("Cannot create a domain socket at path \"%s\": "
				    "The socket already exists and failed to unlink.\n",
				    path);
			return -EIO;
		}
	}

	if (rte_vhost_driver_register(path, 0) != 0) {
		SPDK_ERRLOG("Could not register controller %s with vhost library\n", ctrl_name);
		SPDK_ERRLOG("Check if domain socket %s already exists\n", path);
		return -EIO;
	}
	if (rte_vhost_driver_set_features(path, virtio_features) ||
	    rte_vhost_driver_disable_features(path, disabled_features)) {
		SPDK_ERRLOG("Couldn't set vhost features for controller %s\n", ctrl_name);

		rte_vhost_driver_unregister(path);
		return -EIO;
	}

	if (rte_vhost_driver_callback_register(path, &g_spdk_vhost_ops) != 0) {
		rte_vhost_driver_unregister(path);
		SPDK_ERRLOG("Couldn't register callbacks for controller %s\n", ctrl_name);
		return -EIO;
	}

#ifndef SPDK_CONFIG_VHOST_INTERNAL_LIB
	rte_vhost_driver_get_protocol_features(path, &protocol_features);
	protocol_features |= (1ULL << VHOST_USER_PROTOCOL_F_CONFIG);
	rte_vhost_driver_set_protocol_features(path, protocol_features);
#endif

	if (rte_vhost_driver_start(path) != 0) {
		SPDK_ERRLOG("Failed to start vhost driver for controller %s (%d): %s\n",
			    ctrl_name, errno, spdk_strerror(errno));
		rte_vhost_driver_unregister(path);
		return -EIO;
	}

	return 0;
}
+1 −47
Original line number Diff line number Diff line
@@ -675,7 +675,6 @@ vhost_dev_register(struct spdk_vhost_dev *vdev, const char *name, const char *ma
		   const struct spdk_vhost_dev_backend *backend)
{
	char path[PATH_MAX];
	struct stat file_stat;
	struct spdk_cpuset *cpumask;
	int rc;

@@ -711,51 +710,11 @@ vhost_dev_register(struct spdk_vhost_dev *vdev, const char *name, const char *ma
		goto out;
	}

	/* Register vhost driver to handle vhost messages. */
	if (stat(path, &file_stat) != -1) {
		if (!S_ISSOCK(file_stat.st_mode)) {
			SPDK_ERRLOG("Cannot create a domain socket at path \"%s\": "
				    "The file already exists and is not a socket.\n",
				    path);
			rc = -EIO;
			goto out;
		} else if (unlink(path) != 0) {
			SPDK_ERRLOG("Cannot create a domain socket at path \"%s\": "
				    "The socket already exists and failed to unlink.\n",
				    path);
			rc = -EIO;
			goto out;
		}
	}

	if (rte_vhost_driver_register(path, 0) != 0) {
		SPDK_ERRLOG("Could not register controller %s with vhost library\n", name);
		SPDK_ERRLOG("Check if domain socket %s already exists\n", path);
		rc = -EIO;
		goto out;
	}
	if (rte_vhost_driver_set_features(path, backend->virtio_features) ||
	    rte_vhost_driver_disable_features(path, backend->disabled_features)) {
		SPDK_ERRLOG("Couldn't set vhost features for controller %s\n", name);

		rte_vhost_driver_unregister(path);
		rc = -EIO;
		goto out;
	}

	if (rte_vhost_driver_callback_register(path, &g_spdk_vhost_ops) != 0) {
		rte_vhost_driver_unregister(path);
		SPDK_ERRLOG("Couldn't register callbacks for controller %s\n", name);
		rc = -EIO;
		goto out;
	}

	vdev->name = strdup(name);
	vdev->path = strdup(path);
	if (vdev->name == NULL || vdev->path == NULL) {
		free(vdev->name);
		free(vdev->path);
		rte_vhost_driver_unregister(path);
		rc = -EIO;
		goto out;
	}
@@ -769,12 +728,7 @@ vhost_dev_register(struct spdk_vhost_dev *vdev, const char *name, const char *ma
	vhost_dev_set_coalescing(vdev, SPDK_VHOST_COALESCING_DELAY_BASE_US,
				 SPDK_VHOST_VQ_IOPS_COALESCING_THRESHOLD);

	vhost_dev_install_rte_compat_hooks(vdev);

	if (rte_vhost_driver_start(path) != 0) {
		SPDK_ERRLOG("Failed to start vhost driver for controller %s (%d): %s\n",
			    name, errno, spdk_strerror(errno));
		rte_vhost_driver_unregister(path);
	if (vhost_register_unix_socket(path, name, backend->virtio_features, backend->disabled_features)) {
		TAILQ_REMOVE(&g_vhost_devices, vdev, tailq);
		free(vdev->name);
		free(vdev->path);
+3 −1
Original line number Diff line number Diff line
@@ -385,7 +385,9 @@ void vhost_session_stop_done(struct spdk_vhost_session *vsession, int response);

struct spdk_vhost_session *vhost_session_find_by_vid(int vid);
void vhost_session_install_rte_compat_hooks(struct spdk_vhost_session *vsession);
void vhost_dev_install_rte_compat_hooks(struct spdk_vhost_dev *vdev);

int vhost_register_unix_socket(const char *path, const char *ctrl_name,
			       uint64_t virtio_features, uint64_t disabled_features);

struct vhost_poll_group *vhost_get_poll_group(struct spdk_cpuset *cpumask);

+2 −2
Original line number Diff line number Diff line
@@ -48,8 +48,8 @@ DEFINE_STUB(rte_vhost_get_vring_base, int, (int vid, uint16_t queue_id,
		uint16_t *last_avail_idx, uint16_t *last_used_idx), 0);
DEFINE_STUB_V(vhost_session_install_rte_compat_hooks,
	      (struct spdk_vhost_session *vsession));
DEFINE_STUB_V(vhost_dev_install_rte_compat_hooks,
	      (struct spdk_vhost_dev *vdev));
DEFINE_STUB(vhost_register_unix_socket, int, (const char *path, const char *name,
		uint64_t virtio_features, uint64_t disabled_features), 0);
DEFINE_STUB(rte_vhost_driver_unregister, int, (const char *path), 0);
DEFINE_STUB(spdk_mem_register, int, (void *vaddr, size_t len), 0);
DEFINE_STUB(spdk_mem_unregister, int, (void *vaddr, size_t len), 0);