From 5410ca8ea917a24e19a6f3f094341caf23f5cb58 Mon Sep 17 00:00:00 2001 From: Xiaodong Liu Date: Mon, 4 Dec 2017 00:46:13 -0500 Subject: [PATCH] nbd: link multiple nbd-disks together Record multiple nbd-disks by linking them into g_spdk_nbd. Multiple nbd-disks cat be created or stopped by upcoming nbd RPC. Change-Id: I868d07d33981c94c1f06a1b31cf55e91d9df4fa8 Signed-off-by: Xiaodong Liu Reviewed-on: https://review.gerrithub.io/390170 Tested-by: SPDK Automated Test System Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris Reviewed-by: Daniel Verkamp --- lib/nbd/nbd.c | 78 ++++++++++++++++++++++++++++++++++++++++++ lib/nbd/nbd_internal.h | 6 ++++ 2 files changed, 84 insertions(+) diff --git a/lib/nbd/nbd.c b/lib/nbd/nbd.c index 15b8ddfad..83897f967 100644 --- a/lib/nbd/nbd.c +++ b/lib/nbd/nbd.c @@ -79,6 +79,8 @@ struct spdk_nbd_disk { struct nbd_io io; struct spdk_poller *nbd_poller; uint32_t buf_align; + + TAILQ_ENTRY(spdk_nbd_disk) tailq; }; struct spdk_nbd_disk_globals { @@ -98,6 +100,74 @@ spdk_nbd_init(void) void spdk_nbd_fini(void) { + struct spdk_nbd_disk *nbd_idx, *nbd_tmp; + + /* + * Stop running spdk_nbd_disk. + * Here, nbd removing are unnecessary, but _SAFE variant + * is needed, since internal spdk_nbd_disk_unregister will + * remove nbd from TAILQ. + */ + TAILQ_FOREACH_SAFE(nbd_idx, &g_spdk_nbd.disk_head, tailq, nbd_tmp) { + spdk_nbd_stop(nbd_idx); + } +} + +static int +spdk_nbd_disk_register(struct spdk_nbd_disk *nbd) +{ + if (spdk_nbd_disk_find_by_nbd_path(nbd->nbd_path)) { + SPDK_NOTICELOG("%s is already exported\n", nbd->nbd_path); + return -1; + } + + TAILQ_INSERT_TAIL(&g_spdk_nbd.disk_head, nbd, tailq); + + return 0; +} + +static void +spdk_nbd_disk_unregister(struct spdk_nbd_disk *nbd) +{ + struct spdk_nbd_disk *nbd_idx, *nbd_tmp; + + /* + * nbd disk may be stopped before registered. + * check whether it was registered. + */ + TAILQ_FOREACH_SAFE(nbd_idx, &g_spdk_nbd.disk_head, tailq, nbd_tmp) { + if (nbd == nbd_idx) { + TAILQ_REMOVE(&g_spdk_nbd.disk_head, nbd_idx, tailq); + break; + } + } +} + +struct spdk_nbd_disk * +spdk_nbd_disk_find_by_nbd_path(const char *nbd_path) +{ + struct spdk_nbd_disk *nbd; + + /* + * check whether nbd has already been registered by nbd path. + */ + TAILQ_FOREACH(nbd, &g_spdk_nbd.disk_head, tailq) { + if (!strcmp(nbd->nbd_path, nbd_path)) { + return nbd; + } + } + + return NULL; +} + +struct spdk_nbd_disk *spdk_nbd_disk_first(void) +{ + return TAILQ_FIRST(&g_spdk_nbd.disk_head); +} + +struct spdk_nbd_disk *spdk_nbd_disk_next(struct spdk_nbd_disk *prev) +{ + return TAILQ_NEXT(prev, tailq); } const char * @@ -165,6 +235,8 @@ _nbd_stop(struct spdk_nbd_disk *nbd) spdk_poller_unregister(&nbd->nbd_poller); } + spdk_nbd_disk_unregister(nbd); + free(nbd); } @@ -480,6 +552,7 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path) nbd->io.ref = 1; nbd->bdev = bdev; + nbd->ch = spdk_bdev_get_io_channel(nbd->bdev_desc); nbd->buf_align = spdk_max(spdk_bdev_get_buf_align(bdev), 64); @@ -496,6 +569,11 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path) SPDK_ERRLOG("strdup allocation failure\n"); goto err; } + /* Add nbd_disk to the end of disk list */ + rc = spdk_nbd_disk_register(nbd); + if (rc != 0) { + goto err; + } nbd->dev_fd = open(nbd_path, O_RDWR); if (nbd->dev_fd == -1) { diff --git a/lib/nbd/nbd_internal.h b/lib/nbd/nbd_internal.h index 4b173c733..413dfde9a 100644 --- a/lib/nbd/nbd_internal.h +++ b/lib/nbd/nbd_internal.h @@ -37,6 +37,12 @@ #include "spdk/stdinc.h" #include "spdk/nbd.h" +struct spdk_nbd_disk *spdk_nbd_disk_find_by_nbd_path(const char *nbd_path); + +struct spdk_nbd_disk *spdk_nbd_disk_first(void); + +struct spdk_nbd_disk *spdk_nbd_disk_next(struct spdk_nbd_disk *prev); + const char *spdk_nbd_disk_get_nbd_path(struct spdk_nbd_disk *nbd); const char *spdk_nbd_disk_get_bdev_name(struct spdk_nbd_disk *nbd);