From a85a4452f3c148ec90554df605b8c487a936a2ab Mon Sep 17 00:00:00 2001 From: Pawel Wodkowski Date: Tue, 3 Oct 2017 20:23:37 +0200 Subject: [PATCH] bdev_virtio/rpc: add construct_virtio_user_scsi_bdev Change-Id: I2a351442ead0874d98bdfb23079a723d7665dbb1 Signed-off-by: Pawel Wodkowski Reviewed-on: https://review.gerrithub.io/381186 Tested-by: SPDK Automated Test System Reviewed-by: Dariusz Stojaczyk Reviewed-by: Daniel Verkamp --- lib/bdev/virtio/Makefile | 2 +- lib/bdev/virtio/bdev_virtio.c | 204 ++++++++++++------ lib/bdev/virtio/bdev_virtio.h | 66 ++++++ lib/bdev/virtio/bdev_virtio_rpc.c | 140 ++++++++++++ lib/bdev/virtio/rte_virtio/virtio_dev.h | 3 + lib/bdev/virtio/rte_virtio/virtio_pci.c | 8 + .../rte_virtio/virtio_user/virtio_user_dev.c | 22 +- .../rte_virtio/virtio_user/virtio_user_dev.h | 4 +- scripts/rpc.py | 18 ++ 9 files changed, 398 insertions(+), 69 deletions(-) create mode 100644 lib/bdev/virtio/bdev_virtio.h create mode 100644 lib/bdev/virtio/bdev_virtio_rpc.c diff --git a/lib/bdev/virtio/Makefile b/lib/bdev/virtio/Makefile index 3e3cdfc836..65aa0c470c 100644 --- a/lib/bdev/virtio/Makefile +++ b/lib/bdev/virtio/Makefile @@ -37,7 +37,7 @@ include $(SPDK_ROOT_DIR)/mk/spdk.common.mk CFLAGS += $(ENV_CFLAGS) -I$(SPDK_ROOT_DIR)/lib/bdev/ -Irte_virtio CFLAGS += -I$(SPDK_ROOT_DIR)/lib/vhost/linux -C_SRCS = bdev_virtio.c +C_SRCS = bdev_virtio.c bdev_virtio_rpc.c C_SRCS += rte_virtio/virtio_dev.c rte_virtio/virtio_pci.c C_SRCS += rte_virtio/virtio_user.c C_SRCS += rte_virtio/virtio_user/vhost_user.c rte_virtio/virtio_user/virtio_user_dev.c diff --git a/lib/bdev/virtio/bdev_virtio.c b/lib/bdev/virtio/bdev_virtio.c index e34639b9bd..332e6a05b1 100644 --- a/lib/bdev/virtio/bdev_virtio.c +++ b/lib/bdev/virtio/bdev_virtio.c @@ -51,6 +51,8 @@ #include #include +#include "bdev_virtio.h" + #define BDEV_VIRTIO_MAX_TARGET 64 #define BDEV_VIRTIO_SCAN_PAYLOAD_SIZE 256 #define CTRLQ_POLL_PERIOD_US (1000 * 5) @@ -81,6 +83,9 @@ struct virtio_scsi_scan_base { /** Virtqueue used for the scan I/O. */ struct virtqueue *vq; + virtio_create_device_cb cb_fn; + void *cb_arg; + /* Currently queried target */ unsigned target; @@ -539,7 +544,7 @@ bdev_virtio_destroy_cb(void *io_device, void *ctx_buf) } static void -scan_target_abort(struct virtio_scsi_scan_base *base) +scan_target_abort(struct virtio_scsi_scan_base *base, int error) { struct virtio_scsi_disk *disk; @@ -550,16 +555,20 @@ scan_target_abort(struct virtio_scsi_scan_base *base) TAILQ_REMOVE(&g_virtio_driver.init_ctrlrs, base->vdev, tailq); virtio_dev_free(base->vdev); - spdk_dma_free(base); - if (TAILQ_EMPTY(&g_virtio_driver.init_ctrlrs)) { - spdk_bdev_module_init_done(SPDK_GET_BDEV_MODULE(virtio_scsi)); + + if (base->cb_fn) { + base->cb_fn(base->cb_arg, error, NULL, 0); } + + spdk_dma_free(base); } static void scan_target_finish(struct virtio_scsi_scan_base *base) { + size_t bdevs_cnt = 0; + struct spdk_bdev *bdevs[BDEV_VIRTIO_MAX_TARGET]; struct virtio_scsi_disk *disk; struct virtqueue *ctrlq; struct spdk_ring *ctrlq_ring; @@ -582,7 +591,7 @@ scan_target_finish(struct virtio_scsi_scan_base *base) SPDK_ENV_SOCKET_ID_ANY); if (ctrlq_ring == NULL) { SPDK_ERRLOG("Failed to allocate send ring for the controlq.\n"); - scan_target_abort(base); + scan_target_abort(base, -ENOMEM); return; } @@ -591,7 +600,7 @@ scan_target_finish(struct virtio_scsi_scan_base *base) SPDK_ERRLOG("Failed to acquire the controlq.\n"); assert(false); spdk_ring_free(ctrlq_ring); - scan_target_abort(base); + scan_target_abort(base, rc); return; } @@ -604,16 +613,18 @@ scan_target_finish(struct virtio_scsi_scan_base *base) spdk_io_device_register(&disk->vdev, bdev_virtio_create_cb, bdev_virtio_destroy_cb, sizeof(struct bdev_virtio_io_channel)); spdk_bdev_register(&disk->bdev); + bdevs[bdevs_cnt] = &disk->bdev; + bdevs_cnt++; } TAILQ_REMOVE(&g_virtio_driver.init_ctrlrs, base->vdev, tailq); TAILQ_INSERT_TAIL(&g_virtio_driver.attached_ctrlrs, base->vdev, tailq); - spdk_dma_free(base); - - if (TAILQ_EMPTY(&g_virtio_driver.init_ctrlrs)) { - spdk_bdev_module_init_done(SPDK_GET_BDEV_MODULE(virtio_scsi)); + if (base->cb_fn) { + base->cb_fn(base->cb_arg, 0, bdevs, bdevs_cnt); } + + spdk_dma_free(base); } static void @@ -702,7 +713,7 @@ alloc_virtio_disk(struct virtio_scsi_scan_base *base, uint8_t target_id, uint64_ disk->target = target_id; bdev = &disk->bdev; - bdev->name = spdk_sprintf_alloc("VirtioScsi%"PRIu32"t%"PRIu8, disk->vdev->id, target_id); + bdev->name = spdk_sprintf_alloc("%st%"PRIu8, base->vdev->name, target_id); if (bdev->name == NULL) { SPDK_ERRLOG("Couldn't alloc memory for the bdev name.\n"); free(disk); @@ -856,7 +867,8 @@ bdev_virtio_process_config(void) { struct spdk_conf_section *sp; struct virtio_dev *vdev = NULL; - char *path; + char *default_name = NULL; + char *path, *name; unsigned vdev_num; int num_queues; bool enable_pci; @@ -886,8 +898,17 @@ bdev_virtio_process_config(void) num_queues = 1; } - vdev = virtio_user_dev_init(path, num_queues, 512, - SPDK_VIRTIO_SCSI_QUEUE_NUM_FIXED); + name = spdk_conf_section_get_val(sp, "Name"); + if (name == NULL) { + default_name = spdk_sprintf_alloc("VirtioScsi%u", vdev_num); + name = default_name; + } + + vdev = virtio_user_dev_init(name, path, num_queues, 512, SPDK_VIRTIO_SCSI_QUEUE_NUM_FIXED); + + free(default_name); + default_name = NULL; + if (vdev == NULL) { rc = -1; goto out; @@ -908,14 +929,87 @@ out: return rc; } +static void +bdev_virtio_scsi_free(struct virtio_dev *vdev) +{ + struct virtqueue *vq; + + if (virtio_dev_queue_is_acquired(vdev, VIRTIO_SCSI_REQUESTQ)) { + vq = vdev->vqs[VIRTIO_SCSI_REQUESTQ]; + spdk_bdev_poller_stop(&vq->poller); + spdk_dma_free(vq->poller_ctx); + vq->poller_ctx = NULL; + virtio_dev_release_queue(vdev, VIRTIO_SCSI_REQUESTQ); + } + + virtio_dev_free(vdev); +} + +static int +bdev_virtio_scsi_scan(struct virtio_dev *vdev, virtio_create_device_cb cb_fn, void *cb_arg) +{ + struct virtio_scsi_scan_base *base = spdk_dma_zmalloc(sizeof(struct virtio_scsi_scan_base), 64, + NULL); + struct virtqueue *vq; + int rc; + + if (base == NULL) { + SPDK_ERRLOG("couldn't allocate memory for scsi target scan.\n"); + return -ENOMEM; + } + + base->cb_fn = cb_fn; + base->cb_arg = cb_arg; + + rc = virtio_dev_init(vdev, VIRTIO_SCSI_DEV_SUPPORTED_FEATURES); + if (rc != 0) { + spdk_dma_free(base); + return rc; + } + + rc = virtio_dev_start(vdev); + if (rc != 0) { + spdk_dma_free(base); + return rc; + } + + base->vdev = vdev; + TAILQ_INIT(&base->found_disks); + + rc = virtio_dev_acquire_queue(vdev, VIRTIO_SCSI_REQUESTQ); + if (rc != 0) { + SPDK_ERRLOG("Couldn't acquire requestq for the target scan.\n"); + spdk_dma_free(base); + return rc; + } + + vq = vdev->vqs[VIRTIO_SCSI_REQUESTQ]; + base->vq = vq; + vq->poller_ctx = base; + spdk_bdev_poller_start(&vq->poller, bdev_scan_poll, base, 0); + rc = scan_target(base); + if (rc) { + SPDK_ERRLOG("Failed to start target scan.\n"); + } + + return rc; +} + +static void +bdev_virtio_initial_scan_complete(void *ctx __attribute__((unused)), + int result __attribute__((unused)), + struct spdk_bdev **bdevs __attribute__((unused)), size_t bdevs_cnt __attribute__((unused))) +{ + if (TAILQ_EMPTY(&g_virtio_driver.init_ctrlrs)) { + spdk_bdev_module_init_done(SPDK_GET_BDEV_MODULE(virtio_scsi)); + } +} static int bdev_virtio_initialize(void) { - struct virtio_scsi_scan_base *base; struct virtio_dev *vdev, *next_vdev; - struct virtqueue *vq; - int rc = 0; + int rc; rc = bdev_virtio_process_config(); if (rc != 0) { @@ -929,43 +1023,8 @@ bdev_virtio_initialize(void) /* Initialize all created devices and scan available targets */ TAILQ_FOREACH(vdev, &g_virtio_driver.init_ctrlrs, tailq) { - base = spdk_dma_zmalloc(sizeof(*base), 64, NULL); - if (base == NULL) { - SPDK_ERRLOG("couldn't allocate memory for scsi target scan.\n"); - rc = -1; - goto out; - } - - rc = virtio_dev_init(vdev, VIRTIO_SCSI_DEV_SUPPORTED_FEATURES); + rc = bdev_virtio_scsi_scan(vdev, bdev_virtio_initial_scan_complete, NULL); if (rc != 0) { - spdk_dma_free(base); - goto out; - } - - rc = virtio_dev_start(vdev); - if (rc != 0) { - spdk_dma_free(base); - goto out; - } - - base->vdev = vdev; - TAILQ_INIT(&base->found_disks); - - rc = virtio_dev_acquire_queue(vdev, VIRTIO_SCSI_REQUESTQ); - if (rc != 0) { - SPDK_ERRLOG("Couldn't acquire requestq for the target scan.\n"); - spdk_dma_free(base); - goto out; - } - - vq = vdev->vqs[VIRTIO_SCSI_REQUESTQ]; - base->vq = vq; - vq->poller_ctx = base; - spdk_bdev_poller_start(&vq->poller, bdev_scan_poll, base, 0); - - rc = scan_target(base); - if (rc != 0) { - SPDK_ERRLOG("Failed to start target scan.\n"); goto out; } } @@ -976,24 +1035,15 @@ out: /* Remove any created devices */ TAILQ_FOREACH_SAFE(vdev, &g_virtio_driver.init_ctrlrs, tailq, next_vdev) { TAILQ_REMOVE(&g_virtio_driver.init_ctrlrs, vdev, tailq); - if (virtio_dev_queue_is_acquired(vdev, VIRTIO_SCSI_REQUESTQ)) { - vq = vdev->vqs[VIRTIO_SCSI_REQUESTQ]; - spdk_bdev_poller_stop(&vq->poller); - spdk_dma_free(vq->poller_ctx); - vq->poller_ctx = NULL; - virtio_dev_release_queue(vdev, VIRTIO_SCSI_REQUESTQ); - } - /* since scan pollers couldn't do a single tick yet. - * it's safe just to free the vdev now. - */ - virtio_dev_free(vdev); + bdev_virtio_scsi_free(vdev); } spdk_bdev_module_init_done(SPDK_GET_BDEV_MODULE(virtio_scsi)); return rc; } -static void bdev_virtio_finish(void) +static void +bdev_virtio_finish(void) { struct virtio_dev *vdev, *next; struct virtqueue *vq; @@ -1015,4 +1065,28 @@ static void bdev_virtio_finish(void) } } +int +create_virtio_user_scsi_device(const char *base_name, const char *path, unsigned num_queues, + unsigned queue_size, virtio_create_device_cb cb_fn, void *cb_arg) +{ + struct virtio_dev *vdev; + int rc; + + vdev = virtio_user_dev_init(base_name, path, num_queues, queue_size, + SPDK_VIRTIO_SCSI_QUEUE_NUM_FIXED); + if (!vdev) { + SPDK_ERRLOG("Failed to create virito device %s: %s\n", base_name, path); + return -EINVAL; + } + + rc = bdev_virtio_scsi_scan(vdev, cb_fn, cb_arg); + if (rc) { + TAILQ_REMOVE(&g_virtio_driver.init_ctrlrs, vdev, tailq); + bdev_virtio_scsi_free(vdev); + } + + return rc; +} + + SPDK_LOG_REGISTER_TRACE_FLAG("virtio", SPDK_TRACE_VIRTIO) diff --git a/lib/bdev/virtio/bdev_virtio.h b/lib/bdev/virtio/bdev_virtio.h new file mode 100644 index 0000000000..c360ae9f96 --- /dev/null +++ b/lib/bdev/virtio/bdev_virtio.h @@ -0,0 +1,66 @@ +/*- + * BSD LICENSE + * + * Copyright (c) Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SPDK_BDEV_VIRTIO_H +#define SPDK_BDEV_VIRTIO_H + +#include "spdk/bdev.h" + +typedef void (*virtio_create_device_cb)(void *, int, struct spdk_bdev **, size_t size); + +/** + * Add new Virtio SCSI device and scan it. When LUN is found bdev is automaticly + * added to point this LUN. + * + * \param path + * Path to socket. + * \param base_name + * Name to used for all bdevs created from this device. + * \param vq_size + * Max queue size. + * \param cb_fn + * An optional callback to be called after scanning all targets on the controller. + * First parameter is \c cb_arg + * Second parameter is error code. Zero on succes or negative error code. + * Third parameter is bdevs array found on created device. NULL in case of error. + * Fourth is number of bdevs in array. Zero in case of error. + * \param cb_arg1 + * First argument of \c cb_fn + * \return + * Zero on success (device scan is started) or negative error code. + * In case of error \c done_cb is not called. + */ +int create_virtio_user_scsi_device(const char *base_name, const char *path, unsigned num_queues, + unsigned queue_size, virtio_create_device_cb cb_fn, void *cb_arg); + +#endif /* SPDK_BDEV_VIRTIO_H */ diff --git a/lib/bdev/virtio/bdev_virtio_rpc.c b/lib/bdev/virtio/bdev_virtio_rpc.c new file mode 100644 index 0000000000..bd28c0a54a --- /dev/null +++ b/lib/bdev/virtio/bdev_virtio_rpc.c @@ -0,0 +1,140 @@ +/*- + * BSD LICENSE + * + * Copyright (c) Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "spdk/stdinc.h" + +#include "spdk/string.h" +#include "spdk/rpc.h" +#include "spdk/util.h" +#include "spdk_internal/log.h" + +#include "bdev_virtio.h" + +struct rpc_virtio_user_scsi_dev { + char *path; + char *name; + uint32_t vq_count; + uint32_t vq_size; + struct spdk_jsonrpc_request *request; + +}; + +static const struct spdk_json_object_decoder rpc_construct_virtio_user_scsi_dev[] = { + {"path", offsetof(struct rpc_virtio_user_scsi_dev, path), spdk_json_decode_string }, + {"name", offsetof(struct rpc_virtio_user_scsi_dev, name), spdk_json_decode_string }, + {"vq_count", offsetof(struct rpc_virtio_user_scsi_dev, vq_size), spdk_json_decode_uint32, true }, + {"vq_size", offsetof(struct rpc_virtio_user_scsi_dev, vq_size), spdk_json_decode_uint32, true }, +}; + +static void +free_rpc_connect_virtio_user_scsi_dev(struct rpc_virtio_user_scsi_dev *req) +{ + if (!req) { + return; + } + + free(req->path); + free(req->name); + free(req); +} + +static void +rpc_create_virtio_user_scsi_bdev_cb(void *ctx, int result, struct spdk_bdev **bdevs, size_t cnt) +{ + struct rpc_virtio_user_scsi_dev *req = ctx; + struct spdk_json_write_ctx *w; + char buf[64]; + size_t i; + + if (result) { + spdk_strerror_r(-result, buf, sizeof(buf)); + spdk_jsonrpc_send_error_response(req->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, buf); + free_rpc_connect_virtio_user_scsi_dev(req); + return; + } + + w = spdk_jsonrpc_begin_result(req->request); + if (w) { + spdk_json_write_array_begin(w); + + for (i = 0; i < cnt; i++) { + spdk_json_write_string(w, spdk_bdev_get_name(bdevs[i])); + bdevs++; + } + + spdk_json_write_array_end(w); + spdk_jsonrpc_end_result(req->request, w); + } + + free_rpc_connect_virtio_user_scsi_dev(ctx); +} + +static void +spdk_rpc_create_virtio_user_scsi_bdev(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_virtio_user_scsi_dev *req; + char buf[64]; + int rc; + + req = calloc(1, sizeof(*req)); + if (!req) { + rc = -ENOMEM; + goto invalid; + } + + req->vq_count = 1; + req->vq_size = 512; + + if (spdk_json_decode_object(params, rpc_construct_virtio_user_scsi_dev, + SPDK_COUNTOF(rpc_construct_virtio_user_scsi_dev), + req)) { + rc = -EINVAL; + goto invalid; + } + + req->request = request; + rc = create_virtio_user_scsi_device(req->name, req->path, req->vq_count, req->vq_size, + rpc_create_virtio_user_scsi_bdev_cb, req); + if (rc < 0) { + goto invalid; + } + + return; + +invalid: + spdk_strerror_r(-rc, buf, sizeof(buf)); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, buf); + free_rpc_connect_virtio_user_scsi_dev(req); +} +SPDK_RPC_REGISTER("construct_virtio_user_scsi_bdev", spdk_rpc_create_virtio_user_scsi_bdev); diff --git a/lib/bdev/virtio/rte_virtio/virtio_dev.h b/lib/bdev/virtio/rte_virtio/virtio_dev.h index 0589bd37c6..7eb40eaacc 100644 --- a/lib/bdev/virtio/rte_virtio/virtio_dev.h +++ b/lib/bdev/virtio/rte_virtio/virtio_dev.h @@ -73,6 +73,9 @@ struct virtio_dev { struct virtqueue **vqs; + + /** Name of this virtio dev set by backend */ + char *name; uint16_t started; /** Max number of queues the host supports. */ diff --git a/lib/bdev/virtio/rte_virtio/virtio_pci.c b/lib/bdev/virtio/rte_virtio/virtio_pci.c index 36babbe5e6..a47716c827 100644 --- a/lib/bdev/virtio/rte_virtio/virtio_pci.c +++ b/lib/bdev/virtio/rte_virtio/virtio_pci.c @@ -36,6 +36,7 @@ #include #include "spdk/mmio.h" +#include "spdk/string.h" #include "virtio_pci.h" @@ -86,6 +87,7 @@ free_virtio_hw(struct virtio_dev *dev) spdk_pci_device_unmap_bar(hw->pci_dev, i, hw->pci_bar[i].vaddr); } + free(dev->name); free(hw); } @@ -716,10 +718,16 @@ pci_enum_virtio_probe_cb(void *ctx, struct spdk_pci_device *pci_dev) } #endif + vdev->name = spdk_sprintf_alloc("VirtioScsi%"PRIu32, vdev->id); + if (!vdev->name) { + goto err; + } + rc = vtpci_init(vdev, &legacy_ops); if (rc != 0) { goto err; } + vdev->modern = 0; virtio_dev_pci_init(vdev); return 0; diff --git a/lib/bdev/virtio/rte_virtio/virtio_user/virtio_user_dev.c b/lib/bdev/virtio/rte_virtio/virtio_user/virtio_user_dev.c index fe876ef967..af19e7472d 100644 --- a/lib/bdev/virtio/rte_virtio/virtio_user/virtio_user_dev.c +++ b/lib/bdev/virtio/rte_virtio/virtio_user/virtio_user_dev.c @@ -38,6 +38,7 @@ #include "../virtio_dev.h" #include "spdk/string.h" +#include "spdk/util.h" static int virtio_user_create_queue(struct virtio_user_dev *dev, uint32_t queue_sel) @@ -166,14 +167,23 @@ virtio_user_dev_setup(struct virtio_user_dev *dev) } struct virtio_dev * -virtio_user_dev_init(char *path, uint16_t requested_queues, - uint32_t queue_size, uint16_t fixed_queue_num) +virtio_user_dev_init(const char *name, const char *path, uint16_t requested_queues, + uint32_t queue_size, + uint16_t fixed_queue_num) { struct virtio_dev *vdev; struct virtio_user_dev *dev; uint64_t max_queues; char err_str[64]; + if (name == NULL) { + SPDK_ERRLOG("No name gived for controller: %s\n", path); + return NULL; + } else if (requested_queues == 0) { + SPDK_ERRLOG("Can't create controller with no queues: %s\n", path); + return NULL; + } + dev = calloc(1, sizeof(*dev)); if (dev == NULL) { return NULL; @@ -181,6 +191,11 @@ virtio_user_dev_init(char *path, uint16_t requested_queues, vdev = &dev->vdev; vdev->is_hw = 0; + vdev->name = strdup(name); + if (!vdev->name) { + SPDK_ERRLOG("Failed to reserve memory for controller name: %s\n", path); + goto err; + } if (vtpci_init(vdev, &virtio_user_ops) != 0) { SPDK_ERRLOG("Failed to init device: %s\n", path); @@ -219,6 +234,7 @@ virtio_user_dev_init(char *path, uint16_t requested_queues, return vdev; err: + free(vdev->name); free(dev); return NULL; } @@ -227,4 +243,6 @@ void virtio_user_dev_uninit(struct virtio_user_dev *dev) { close(dev->vhostfd); + free(dev->vdev.name); + free(dev); } diff --git a/lib/bdev/virtio/rte_virtio/virtio_user/virtio_user_dev.h b/lib/bdev/virtio/rte_virtio/virtio_user/virtio_user_dev.h index 0997da5be8..501bf7f537 100644 --- a/lib/bdev/virtio/rte_virtio/virtio_user/virtio_user_dev.h +++ b/lib/bdev/virtio/rte_virtio/virtio_user/virtio_user_dev.h @@ -67,6 +67,7 @@ int virtio_user_stop_device(struct virtio_user_dev *dev); /** * Connect to a vhost-user device and create corresponding virtio_dev. * + * \param name name of this virtio device * \param path path to the Unix domain socket of the vhost-user device * \param requested_queues maximum number of request queues that this * device will support @@ -76,7 +77,8 @@ int virtio_user_stop_device(struct virtio_user_dev *dev); * additional event and control queues. * \return virtio device */ -struct virtio_dev *virtio_user_dev_init(char *path, uint16_t requested_queues, +struct virtio_dev *virtio_user_dev_init(const char *name, const char *path, + uint16_t requested_queues, uint32_t queue_size, uint16_t fixed_queue_num); void virtio_user_dev_uninit(struct virtio_user_dev *dev); diff --git a/scripts/rpc.py b/scripts/rpc.py index 8b304adb07..1f563b82af 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -663,6 +663,24 @@ p = subparsers.add_parser('remove_vhost_controller', help='Remove a vhost contro p.add_argument('ctrlr', help='controller name') p.set_defaults(func=remove_vhost_controller) +def construct_virtio_user_scsi_bdev(args): + params = {'path': args.path} + if args.vq_count: + params['vq_count'] = args.vq_count + if args.vq_size: + params['vq_size'] = args.vq_size + print_dict(jsonrpc_call('construct_virtio_user_scsi_bdev', params)) + +p = subparsers.add_parser('construct_virtio_user_scsi_bdev', help="""Connect to virtio user scsi device. +This imply scan and add bdevs offered by remote side. +Result is array of added bdevs.""") +p.add_argument('path', help='Path to Virtio SCSI socket') +p.add_argument('-b', '--name', help="""Use this name as base instead of 'VirtioScsiN' +Base will be used to construct new bdev's found on target by adding 't' sufix.""", required=True) +p.add_argument('--vq-count', help='Number of virtual queues to be used.', type=int) +p.add_argument('--vq-size', help='Size of each queue', type=int) +p.set_defaults(func=construct_virtio_user_scsi_bdev) + def get_rpc_methods(args): print_dict(jsonrpc_call('get_rpc_methods'))