From 8cc7b0bc4d1a85f18127613ad8c6b04dda1a540e Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Thu, 11 Apr 2019 09:34:42 +0900 Subject: [PATCH] lib/iscsi: Set destructed at the start of target node destruction Add the flag destructed to struct spdk_iscsi_tgt_node and iscsi_op_login_check_target() refers it and returns ISCSI_LOGIN_TARGET_REMOVED if it is true. When destructing iSCSI target node, it will be nice if iSCSI library can stop further connections are created but, connections are not associated with any target node until processing login. Hence stop creating sessions instead. Additionally, when destructing iSCSI target node, if the flag destructed is already set, return immediately, and the flag destructed does not affect discovery session. Change-Id: Ic73bdd93f2ca7d5ca1d2f897d5046cbc51650d5f Signed-off-by: Shuhei Matsumoto Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/450881 Reviewed-by: Jim Harris Reviewed-by: Changpeng Liu Reviewed-by: Ben Walker Tested-by: SPDK CI Jenkins --- lib/iscsi/iscsi.c | 6 ++++++ lib/iscsi/tgt_node.c | 13 +++++++++++++ lib/iscsi/tgt_node.h | 3 +++ test/unit/lib/iscsi/iscsi.c/iscsi_ut.c | 3 +++ 4 files changed, 25 insertions(+) diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 507a6f0e5..c059e2021 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -1428,6 +1428,12 @@ iscsi_op_login_check_target(struct spdk_iscsi_conn *conn, rsph->status_detail = ISCSI_LOGIN_TARGET_NOT_FOUND; return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; } + if (spdk_iscsi_tgt_node_is_destructed(*target)) { + SPDK_ERRLOG("target %s is removed\n", target_name); + rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; + rsph->status_detail = ISCSI_LOGIN_TARGET_REMOVED; + return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; + } result = spdk_iscsi_tgt_node_access(conn, *target, conn->initiator_name, conn->initiator_addr); diff --git a/lib/iscsi/tgt_node.c b/lib/iscsi/tgt_node.c index 064cf7827..04507ee60 100644 --- a/lib/iscsi/tgt_node.c +++ b/lib/iscsi/tgt_node.c @@ -631,6 +631,13 @@ iscsi_tgt_node_destruct(struct spdk_iscsi_tgt_node *target) return; } + if (target->destructed) { + SPDK_ERRLOG("Destructing %s is already started\n", target->name); + return; + } + + target->destructed = true; + spdk_scsi_dev_destruct(target->dev); free(target->name); @@ -1267,6 +1274,12 @@ spdk_iscsi_shutdown_tgt_node_by_name(const char *target_name) return -ENOENT; } +bool +spdk_iscsi_tgt_node_is_destructed(struct spdk_iscsi_tgt_node *target) +{ + return target->destructed; +} + int spdk_iscsi_tgt_node_cleanup_luns(struct spdk_iscsi_conn *conn, struct spdk_iscsi_tgt_node *target) diff --git a/lib/iscsi/tgt_node.h b/lib/iscsi/tgt_node.h index 1d54922a8..92c8e1b4a 100644 --- a/lib/iscsi/tgt_node.h +++ b/lib/iscsi/tgt_node.h @@ -86,12 +86,15 @@ struct spdk_iscsi_tgt_node { int num_pg_maps; TAILQ_HEAD(, spdk_iscsi_pg_map) pg_map_head; TAILQ_ENTRY(spdk_iscsi_tgt_node) tailq; + + bool destructed; }; int spdk_iscsi_parse_tgt_nodes(void); void spdk_iscsi_shutdown_tgt_nodes(void); int spdk_iscsi_shutdown_tgt_node_by_name(const char *target_name); +bool spdk_iscsi_tgt_node_is_destructed(struct spdk_iscsi_tgt_node *target); int spdk_iscsi_send_tgts(struct spdk_iscsi_conn *conn, const char *iiqn, const char *iaddr, const char *tiqn, uint8_t *data, int alloc_len, int data_len); diff --git a/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c b/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c index 8d9a09e84..2277d3a11 100644 --- a/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c +++ b/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c @@ -81,6 +81,9 @@ DEFINE_STUB(spdk_iscsi_send_tgts, int, const char *tiqn, uint8_t *data, int alloc_len, int data_len), 0); +DEFINE_STUB(spdk_iscsi_tgt_node_is_destructed, bool, + (struct spdk_iscsi_tgt_node *target), false); + DEFINE_STUB_V(spdk_iscsi_portal_grp_close_all, (void)); DEFINE_STUB_V(spdk_iscsi_conn_migration, (struct spdk_iscsi_conn *conn));