From 7fbdeacc9ea31534984c24dd4ba540ff0e898153 Mon Sep 17 00:00:00 2001 From: Tomasz Zawadzki Date: Fri, 17 Apr 2020 10:52:54 -0400 Subject: [PATCH] nvme: do not allow the same nvme_io_msg_producer to register twice Previous to this change it was possible to register same nvme_io_msg_producer twice. This kind of functionality does not make sense in current scope of it, as each message to/from io_msg_producer does not have identifier other than this pointer. In case of nvme_cuse this allowed creation of multiple /dev/spdk/nvme* devices and caused an infinite loop when detaching an nvme controller. This patch disallows that and adds test for nvme_cuse. Signed-off-by: Tomasz Zawadzki Change-Id: I5f56548d1bce878417323c12909d6970416d2020 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1938 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Jim Harris --- lib/nvme/nvme_io_msg.c | 22 ++++++++++++++++++++++ test/nvme/cuse/nvme_cuse.sh | 8 ++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/nvme/nvme_io_msg.c b/lib/nvme/nvme_io_msg.c index b0819fa3e..4223fe1a6 100644 --- a/lib/nvme/nvme_io_msg.c +++ b/lib/nvme/nvme_io_msg.c @@ -106,6 +106,20 @@ spdk_nvme_io_msg_process(struct spdk_nvme_ctrlr *ctrlr) return count; } +static bool +nvme_io_msg_is_producer_registered(struct spdk_nvme_ctrlr *ctrlr, + struct nvme_io_msg_producer *io_msg_producer) +{ + struct nvme_io_msg_producer *tmp; + + STAILQ_FOREACH(tmp, &ctrlr->io_producers, link) { + if (tmp == io_msg_producer) { + return true; + } + } + return false; +} + int nvme_io_msg_ctrlr_register(struct spdk_nvme_ctrlr *ctrlr, struct nvme_io_msg_producer *io_msg_producer) @@ -115,6 +129,10 @@ nvme_io_msg_ctrlr_register(struct spdk_nvme_ctrlr *ctrlr, return -EINVAL; } + if (nvme_io_msg_is_producer_registered(ctrlr, io_msg_producer)) { + return -EEXIST; + } + if (!STAILQ_EMPTY(&ctrlr->io_producers) || ctrlr->is_resetting) { /* There are registered producers - IO messaging already started */ STAILQ_INSERT_TAIL(&ctrlr->io_producers, io_msg_producer, link); @@ -173,6 +191,10 @@ nvme_io_msg_ctrlr_unregister(struct spdk_nvme_ctrlr *ctrlr, { assert(io_msg_producer != NULL); + if (!nvme_io_msg_is_producer_registered(ctrlr, io_msg_producer)) { + return; + } + STAILQ_REMOVE(&ctrlr->io_producers, io_msg_producer, nvme_io_msg_producer, link); if (STAILQ_EMPTY(&ctrlr->io_producers)) { nvme_io_msg_ctrlr_detach(ctrlr); diff --git a/test/nvme/cuse/nvme_cuse.sh b/test/nvme/cuse/nvme_cuse.sh index 3098df6e5..19bc59ce2 100755 --- a/test/nvme/cuse/nvme_cuse.sh +++ b/test/nvme/cuse/nvme_cuse.sh @@ -46,6 +46,14 @@ if [ ! -c "${ctrlr_base}0" ]; then exit 1 fi +# Verify adding same nvme controller twice fails +$rpc_py bdev_nvme_cuse_register -n Nvme0 && false +sleep 1 + +if [ -c "${ctrlr_base}1" ]; then + exit 1 +fi + $rpc_py bdev_nvme_detach_controller Nvme0 trap - SIGINT SIGTERM EXIT