From a5478cefbd76f36efc299dc78ebd953349cb6c49 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Fri, 12 Apr 2019 13:38:42 +0900 Subject: [PATCH] lib/iscsi: Exit related connections at the start of target node destruction When any iSCSI target is destructed, if the target exits all corresponding connections first, destructing SCSI device will be easier. Hence, iscsi_tgt_node_destruct() starts exiting all corresponding connections. Then it destructs SCSI device immediately if no active active connections, or waits for the completion if there is any active connection for the target. Change-Id: Ibd4a29789faecfefccefa1153a519c43d040a00d Signed-off-by: Shuhei Matsumoto Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/450737 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Changpeng Liu --- lib/iscsi/tgt_node.c | 48 ++++++++++++++++---- lib/iscsi/tgt_node.h | 1 + test/unit/lib/iscsi/tgt_node.c/tgt_node_ut.c | 1 + 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/lib/iscsi/tgt_node.c b/lib/iscsi/tgt_node.c index 04507ee60..71cb26cae 100644 --- a/lib/iscsi/tgt_node.c +++ b/lib/iscsi/tgt_node.c @@ -624,6 +624,37 @@ iscsi_tgt_node_delete_all_pg_maps(struct spdk_iscsi_tgt_node *target) } } +static void +_iscsi_tgt_node_destruct(struct spdk_iscsi_tgt_node *target) +{ + free(target->name); + free(target->alias); + + pthread_mutex_lock(&g_spdk_iscsi.mutex); + iscsi_tgt_node_delete_all_pg_maps(target); + pthread_mutex_unlock(&g_spdk_iscsi.mutex); + + pthread_mutex_destroy(&target->mutex); + free(target); +} + +static int +iscsi_tgt_node_check_active_conns(void *arg) +{ + struct spdk_iscsi_tgt_node *target = arg; + + if (spdk_iscsi_get_active_conns(target) != 0) { + return 1; + } + + spdk_poller_unregister(&target->destruct_poller); + + spdk_scsi_dev_destruct(target->dev); + _iscsi_tgt_node_destruct(target); + + return 1; +} + static void iscsi_tgt_node_destruct(struct spdk_iscsi_tgt_node *target) { @@ -638,17 +669,16 @@ iscsi_tgt_node_destruct(struct spdk_iscsi_tgt_node *target) target->destructed = true; - spdk_scsi_dev_destruct(target->dev); + spdk_iscsi_conns_start_exit(target); - free(target->name); - free(target->alias); + if (spdk_iscsi_get_active_conns(target) != 0) { + target->destruct_poller = spdk_poller_register(iscsi_tgt_node_check_active_conns, + target, 10); + } else { + spdk_scsi_dev_destruct(target->dev); + _iscsi_tgt_node_destruct(target); + } - pthread_mutex_lock(&g_spdk_iscsi.mutex); - iscsi_tgt_node_delete_all_pg_maps(target); - pthread_mutex_unlock(&g_spdk_iscsi.mutex); - - pthread_mutex_destroy(&target->mutex); - free(target); } static int diff --git a/lib/iscsi/tgt_node.h b/lib/iscsi/tgt_node.h index 92c8e1b4a..bb9732003 100644 --- a/lib/iscsi/tgt_node.h +++ b/lib/iscsi/tgt_node.h @@ -88,6 +88,7 @@ struct spdk_iscsi_tgt_node { TAILQ_ENTRY(spdk_iscsi_tgt_node) tailq; bool destructed; + struct spdk_poller *destruct_poller; }; int spdk_iscsi_parse_tgt_nodes(void); diff --git a/test/unit/lib/iscsi/tgt_node.c/tgt_node_ut.c b/test/unit/lib/iscsi/tgt_node.c/tgt_node_ut.c index bfaa6963f..50dbe1f31 100644 --- a/test/unit/lib/iscsi/tgt_node.c/tgt_node_ut.c +++ b/test/unit/lib/iscsi/tgt_node.c/tgt_node_ut.c @@ -42,6 +42,7 @@ #include "iscsi/tgt_node.c" #include "scsi/scsi_internal.h" #include "unit/lib/json_mock.c" +#include "common/lib/test_env.c" struct spdk_iscsi_globals g_spdk_iscsi;