From 72343bcf23ebc13294a41c99e1803190da73fca5 Mon Sep 17 00:00:00 2001 From: Dariusz Stojaczyk Date: Wed, 28 Jun 2017 12:21:21 +0200 Subject: [PATCH] scsi: added lun hotremove callback Added optional callback inside scsi lun hotremove, so that higher-level abstraction can be notified about hotremove. Change-Id: I5f1bd8160e3d770a484068dd73928bc2b64c876f Signed-off-by: Dariusz Stojaczyk Reviewed-on: https://review.gerrithub.io/367309 Reviewed-by: Daniel Verkamp Tested-by: SPDK Automated Test System Reviewed-by: Jim Harris --- include/spdk/scsi.h | 8 +++++++- lib/iscsi/tgt_node.c | 2 +- lib/scsi/dev.c | 5 +++-- lib/scsi/lun.c | 21 +++++++++++++++++---- lib/scsi/scsi_internal.h | 10 +++++++++- lib/vhost/vhost_scsi.c | 2 +- test/unit/lib/iscsi/common.c | 4 +++- test/unit/lib/scsi/dev.c/dev_ut.c | 22 ++++++++++++---------- test/unit/lib/scsi/lun.c/lun_ut.c | 8 ++++---- 9 files changed, 57 insertions(+), 25 deletions(-) diff --git a/include/spdk/scsi.h b/include/spdk/scsi.h index 4d6fa948c..f93e99a11 100644 --- a/include/spdk/scsi.h +++ b/include/spdk/scsi.h @@ -162,6 +162,7 @@ int spdk_scsi_fini(void); int spdk_scsi_lun_get_id(const struct spdk_scsi_lun *lun); const char *spdk_scsi_lun_get_name(const struct spdk_scsi_lun *lun); +const struct spdk_scsi_dev *spdk_scsi_lun_get_dev(const struct spdk_scsi_lun *lun); const char *spdk_scsi_dev_get_name(const struct spdk_scsi_dev *dev); int spdk_scsi_dev_get_id(const struct spdk_scsi_dev *dev); @@ -189,13 +190,18 @@ void spdk_scsi_dev_free_io_channels(struct spdk_scsi_dev *dev); * responsible for managing the memory containing this list. * lun_id_list[x] is the LUN ID for lun_list[x]. * \param num_luns Number of entries in lun_list and lun_id_list. + * \param hotremove_cb Callback to lun hotremoval. Will be called + * once hotremove is first triggered. + * \param hotremove_ctx Additional argument to hotremove_cb * \return The constructed spdk_scsi_dev object. */ struct spdk_scsi_dev *spdk_scsi_dev_construct(const char *name, char *lun_name_list[], int *lun_id_list, int num_luns, - uint8_t protocol_id); + uint8_t protocol_id, + void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), + void *hotremove_ctx); void spdk_scsi_dev_delete_lun(struct spdk_scsi_dev *dev, struct spdk_scsi_lun *lun); diff --git a/lib/iscsi/tgt_node.c b/lib/iscsi/tgt_node.c index 158fa9943..438131acb 100644 --- a/lib/iscsi/tgt_node.c +++ b/lib/iscsi/tgt_node.c @@ -694,7 +694,7 @@ spdk_iscsi_tgt_node_construct(int target_index, } target->dev = spdk_scsi_dev_construct(name, lun_name_list, lun_id_list, num_luns, - SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI); + SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); if (!target->dev) { SPDK_ERRLOG("Could not construct SCSI device\n"); diff --git a/lib/scsi/dev.c b/lib/scsi/dev.c index e932d13d2..16b8b94b4 100644 --- a/lib/scsi/dev.c +++ b/lib/scsi/dev.c @@ -139,7 +139,8 @@ typedef struct spdk_scsi_dev _spdk_scsi_dev; _spdk_scsi_dev * spdk_scsi_dev_construct(const char *name, char *lun_name_list[], int *lun_id_list, int num_luns, - uint8_t protocol_id) + uint8_t protocol_id, void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), + void *hotremove_ctx) { struct spdk_scsi_dev *dev; struct spdk_bdev *bdev; @@ -181,7 +182,7 @@ spdk_scsi_dev_construct(const char *name, char *lun_name_list[], int *lun_id_lis goto error; } - lun = spdk_scsi_lun_construct(spdk_bdev_get_name(bdev), bdev); + lun = spdk_scsi_lun_construct(spdk_bdev_get_name(bdev), bdev, hotremove_cb, hotremove_ctx); if (lun == NULL) { goto error; } diff --git a/lib/scsi/lun.c b/lib/scsi/lun.c index 43fbf6557..7562c9a5d 100644 --- a/lib/scsi/lun.c +++ b/lib/scsi/lun.c @@ -232,13 +232,17 @@ spdk_scsi_lun_hotplug(void *arg) } } -static void spdk_scsi_lun_hot_remove(void *remove_ctx) +static void +spdk_scsi_lun_hot_remove(void *remove_ctx) { struct spdk_scsi_lun *lun = (struct spdk_scsi_lun *)remove_ctx; lun->removed = true; - spdk_poller_register(&lun->hotplug_poller, spdk_scsi_lun_hotplug, lun, - lun->lcore, 0); + if (lun->hotremove_cb) { + lun->hotremove_cb(lun, lun->hotremove_ctx); + } + + spdk_poller_register(&lun->hotplug_poller, spdk_scsi_lun_hotplug, lun, lun->lcore, 0); } /** @@ -251,7 +255,8 @@ static void spdk_scsi_lun_hot_remove(void *remove_ctx) * \return pointer to the new spdk_scsi_lun object otherwise */ _spdk_scsi_lun * -spdk_scsi_lun_construct(const char *name, struct spdk_bdev *bdev) +spdk_scsi_lun_construct(const char *name, struct spdk_bdev *bdev, + void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), void *hotremove_ctx) { struct spdk_scsi_lun *lun; int rc; @@ -284,6 +289,8 @@ spdk_scsi_lun_construct(const char *name, struct spdk_bdev *bdev) lun->bdev = bdev; snprintf(lun->name, sizeof(lun->name), "%s", name); + lun->hotremove_cb = hotremove_cb; + lun->hotremove_ctx = hotremove_ctx; rc = spdk_scsi_lun_db_add(lun); if (rc < 0) { @@ -403,3 +410,9 @@ spdk_scsi_lun_get_name(const struct spdk_scsi_lun *lun) { return lun->name; } + +const struct spdk_scsi_dev * +spdk_scsi_lun_get_dev(const struct spdk_scsi_lun *lun) +{ + return lun->dev; +} diff --git a/lib/scsi/scsi_internal.h b/lib/scsi/scsi_internal.h index a1ff18e06..9d483935e 100644 --- a/lib/scsi/scsi_internal.h +++ b/lib/scsi/scsi_internal.h @@ -108,6 +108,12 @@ struct spdk_scsi_lun { /** The LUN is clamed */ bool claimed; + /** Callback to be fired when LUN removal is first triggered. */ + void (*hotremove_cb)(const struct spdk_scsi_lun *lun, void *arg); + + /** Argument for hotremove_cb */ + void *hotremove_ctx; + TAILQ_HEAD(tasks, spdk_scsi_task) tasks; /* submitted tasks */ TAILQ_HEAD(pending_tasks, spdk_scsi_task) pending_tasks; /* pending tasks */ }; @@ -124,7 +130,9 @@ extern struct spdk_lun_db_entry *spdk_scsi_lun_list_head; */ typedef struct spdk_scsi_lun _spdk_scsi_lun; -_spdk_scsi_lun *spdk_scsi_lun_construct(const char *name, struct spdk_bdev *bdev); +_spdk_scsi_lun *spdk_scsi_lun_construct(const char *name, struct spdk_bdev *bdev, + void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), + void *hotremove_ctx); int spdk_scsi_lun_destruct(struct spdk_scsi_lun *lun); void spdk_scsi_lun_clear_all(struct spdk_scsi_lun *lun); diff --git a/lib/vhost/vhost_scsi.c b/lib/vhost/vhost_scsi.c index 4f8d3522a..14b5a53ab 100644 --- a/lib/vhost/vhost_scsi.c +++ b/lib/vhost/vhost_scsi.c @@ -635,7 +635,7 @@ spdk_vhost_scsi_dev_add_dev(const char *ctrlr_name, unsigned scsi_dev_num, const lun_names_list[0] = (char *)lun_name; svdev->scsi_dev[scsi_dev_num] = spdk_scsi_dev_construct(dev_name, lun_names_list, lun_id_list, 1, - SPDK_SPC_PROTOCOL_IDENTIFIER_SAS); + SPDK_SPC_PROTOCOL_IDENTIFIER_SAS, NULL, NULL); if (svdev->scsi_dev[scsi_dev_num] == NULL) { SPDK_ERRLOG("Couldn't create spdk SCSI device '%s' using lun device '%s' in controller: %s\n", diff --git a/test/unit/lib/iscsi/common.c b/test/unit/lib/iscsi/common.c index cff533998..dfdb12325 100644 --- a/test/unit/lib/iscsi/common.c +++ b/test/unit/lib/iscsi/common.c @@ -103,7 +103,9 @@ spdk_event_allocate(uint32_t core, spdk_event_fn fn, void *arg1, void *arg2) struct spdk_scsi_dev * spdk_scsi_dev_construct(const char *name, char **lun_name_list, - int *lun_id_list, int num_luns, uint8_t protocol_id) + int *lun_id_list, int num_luns, uint8_t protocol_id, + void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), + void *hotremove_ctx) { return NULL; } diff --git a/test/unit/lib/scsi/dev.c/dev_ut.c b/test/unit/lib/scsi/dev.c/dev_ut.c index a502acd23..d87d5e426 100644 --- a/test/unit/lib/scsi/dev.c/dev_ut.c +++ b/test/unit/lib/scsi/dev.c/dev_ut.c @@ -85,7 +85,9 @@ spdk_scsi_task_put(struct spdk_scsi_task *task) } _spdk_scsi_lun * -spdk_scsi_lun_construct(const char *name, struct spdk_bdev *bdev) +spdk_scsi_lun_construct(const char *name, struct spdk_bdev *bdev, + void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), + void *hotremove_ctx) { struct spdk_scsi_lun *lun; @@ -234,7 +236,7 @@ dev_construct_num_luns_zero(void) int lun_id_list[1] = { 0 }; dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 0, - SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI); + SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); /* dev should be null since we passed num_luns = 0 */ CU_ASSERT_TRUE(dev == NULL); @@ -250,7 +252,7 @@ dev_construct_no_lun_zero(void) lun_id_list[0] = 1; dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 1, - SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI); + SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); /* dev should be null since no LUN0 was specified (lun_id_list[0] = 1) */ CU_ASSERT_TRUE(dev == NULL); @@ -264,7 +266,7 @@ dev_construct_null_lun(void) int lun_id_list[1] = { 0 }; dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 1, - SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI); + SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); /* dev should be null since no LUN0 was specified (lun_list[0] = NULL) */ CU_ASSERT_TRUE(dev == NULL); @@ -278,7 +280,7 @@ dev_construct_success(void) int lun_id_list[1] = { 0 }; dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 1, - SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI); + SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); /* Successfully constructs and returns a dev */ CU_ASSERT_TRUE(dev != NULL); @@ -297,13 +299,13 @@ dev_construct_same_lun_two_devices(void) int lun_id_list[1] = { 0 }; dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 1, - SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI); + SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); /* Successfully constructs and returns a dev */ CU_ASSERT_TRUE(dev != NULL); dev2 = spdk_scsi_dev_construct("Name2", lun_name_list, lun_id_list, 1, - SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI); + SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); /* Fails to construct dev and returns NULL */ CU_ASSERT_TRUE(dev2 == NULL); @@ -322,7 +324,7 @@ dev_construct_same_lun_one_device(void) int lun_id_list[2] = { 0, 1 }; dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 2, - SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI); + SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); /* Fails to construct dev and returns NULL */ CU_ASSERT_TRUE(dev == NULL); @@ -339,7 +341,7 @@ dev_queue_mgmt_task_success(void) struct spdk_scsi_task *task; dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 1, - SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI); + SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); /* Successfully constructs and returns a dev */ CU_ASSERT_TRUE(dev != NULL); @@ -362,7 +364,7 @@ dev_queue_task_success(void) struct spdk_scsi_task *task; dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 1, - SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI); + SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); /* Successfully constructs and returns a dev */ CU_ASSERT_TRUE(dev != NULL); diff --git a/test/unit/lib/scsi/lun.c/lun_ut.c b/test/unit/lib/scsi/lun.c/lun_ut.c index 8600028a6..c2a576afd 100644 --- a/test/unit/lib/scsi/lun.c/lun_ut.c +++ b/test/unit/lib/scsi/lun.c/lun_ut.c @@ -211,7 +211,7 @@ lun_construct(void) struct spdk_scsi_lun *lun; struct spdk_bdev bdev; - lun = spdk_scsi_lun_construct("lun0", &bdev); + lun = spdk_scsi_lun_construct("lun0", &bdev, NULL, NULL); SPDK_CU_ASSERT_FATAL(lun != NULL); if (lun != NULL) { @@ -607,7 +607,7 @@ lun_construct_null_ctx(void) { struct spdk_scsi_lun *lun; - lun = spdk_scsi_lun_construct("lun0", NULL); + lun = spdk_scsi_lun_construct("lun0", NULL, NULL, NULL); /* lun should be NULL since we passed NULL for the ctx pointer. */ CU_ASSERT(lun == NULL); @@ -630,12 +630,12 @@ lun_construct_same_same_twice(void) struct spdk_scsi_lun *lun, *lun2; struct spdk_bdev bdev, bdev2; - lun = spdk_scsi_lun_construct("lun0", &bdev); + lun = spdk_scsi_lun_construct("lun0", &bdev, NULL, NULL); /* Successfully constructs and returns lun */ SPDK_CU_ASSERT_FATAL(lun != NULL); - lun2 = spdk_scsi_lun_construct("lun0", &bdev2); + lun2 = spdk_scsi_lun_construct("lun0", &bdev2, NULL, NULL); /* Fails to construct the same lun on another bdev and returns NULL */ CU_ASSERT(lun2 == NULL);