From 76126989bdbabd0ff2f74d3cfb0987c45e25828f Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Wed, 13 Feb 2019 00:08:22 -0500 Subject: [PATCH] bdev/nvme: don't attach user deleted controllers automaticlly When hotplug feature is enabled by NVMe driver, users may call delete_nvme_controller() RPC to delete one controller, however, the hotplug monitor will probe this controller automaticlly and attach it back to NVMe driver. We added a skip list, for those user deleted controllers so that NVMe driver will not attach it again. Fix issue #602. Change-Id: Ibbe21ff8a021f968305271acdae86207e6228e20 Signed-off-by: Changpeng Liu Reviewed-on: https://review.gerrithub.io/c/444323 Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Jim Harris --- lib/bdev/nvme/bdev_nvme.c | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/lib/bdev/nvme/bdev_nvme.c b/lib/bdev/nvme/bdev_nvme.c index 88c34ade6..5981fe48c 100644 --- a/lib/bdev/nvme/bdev_nvme.c +++ b/lib/bdev/nvme/bdev_nvme.c @@ -91,6 +91,14 @@ struct nvme_probe_ctx { const char *hostnqn; }; +struct nvme_probe_skip_entry { + struct spdk_nvme_transport_id trid; + TAILQ_ENTRY(nvme_probe_skip_entry) tailq; +}; +/* All the controllers deleted by users via RPC are skipped by hotplug monitor */ +static TAILQ_HEAD(, nvme_probe_skip_entry) g_skipped_nvme_ctrlrs = TAILQ_HEAD_INITIALIZER( + g_skipped_nvme_ctrlrs); + static struct spdk_bdev_nvme_opts g_opts = { .action_on_timeout = SPDK_BDEV_NVME_TIMEOUT_ACTION_NONE, .timeout_us = 0, @@ -801,6 +809,14 @@ static bool hotplug_probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, struct spdk_nvme_ctrlr_opts *opts) { + struct nvme_probe_skip_entry *entry; + + TAILQ_FOREACH(entry, &g_skipped_nvme_ctrlrs, tailq) { + if (spdk_nvme_transport_id_compare(trid, &entry->trid) == 0) { + return false; + } + } + SPDK_DEBUGLOG(SPDK_LOG_BDEV_NVME, "Attaching to %s\n", trid->traddr); return true; @@ -1200,6 +1216,7 @@ spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid, struct nvme_bdev *nvme_bdev; uint32_t i, nsid; size_t j; + struct nvme_probe_skip_entry *entry, *tmp; if (nvme_ctrlr_get(trid) != NULL) { SPDK_ERRLOG("A controller with the provided trid (traddr: %s) already exists.\n", trid->traddr); @@ -1211,6 +1228,16 @@ spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid, return -1; } + if (trid->trtype == SPDK_NVME_TRANSPORT_PCIE) { + TAILQ_FOREACH_SAFE(entry, &g_skipped_nvme_ctrlrs, tailq, tmp) { + if (spdk_nvme_transport_id_compare(trid, &entry->trid) == 0) { + TAILQ_REMOVE(&g_skipped_nvme_ctrlrs, entry, tailq); + free(entry); + break; + } + } + } + spdk_nvme_ctrlr_get_default_ctrlr_opts(&opts, sizeof(opts)); if (hostnqn) { @@ -1273,6 +1300,7 @@ int spdk_bdev_nvme_delete(const char *name) { struct nvme_ctrlr *nvme_ctrlr = NULL; + struct nvme_probe_skip_entry *entry; if (name == NULL) { return -EINVAL; @@ -1284,6 +1312,15 @@ spdk_bdev_nvme_delete(const char *name) return -ENODEV; } + if (nvme_ctrlr->trid.trtype == SPDK_NVME_TRANSPORT_PCIE) { + entry = calloc(1, sizeof(*entry)); + if (!entry) { + return -ENOMEM; + } + entry->trid = nvme_ctrlr->trid; + TAILQ_INSERT_TAIL(&g_skipped_nvme_ctrlrs, entry, tailq); + } + remove_cb(NULL, nvme_ctrlr->ctrlr); return 0; } @@ -1499,9 +1536,15 @@ static void bdev_nvme_library_fini(void) { struct nvme_ctrlr *nvme_ctrlr, *tmp; + struct nvme_probe_skip_entry *entry, *entry_tmp; spdk_poller_unregister(&g_hotplug_poller); + TAILQ_FOREACH_SAFE(entry, &g_skipped_nvme_ctrlrs, tailq, entry_tmp) { + TAILQ_REMOVE(&g_skipped_nvme_ctrlrs, entry, tailq); + free(entry); + } + pthread_mutex_lock(&g_bdev_nvme_mutex); TAILQ_FOREACH_SAFE(nvme_ctrlr, &g_nvme_ctrlrs, tailq, tmp) { if (nvme_ctrlr->ref > 0) {