From 35cd600535146454520eec7fd1aa3fe4747d2454 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Tue, 5 Dec 2017 15:52:50 +0900 Subject: [PATCH] iscsi: Dynamic reconfiguration of PG-IG maps This patch add the internal mechanism to add/remove PG-IG maps to/from an existing iSCSI target. Next patch will add new JSON-RPC commands and python scripts. Change-Id: Ib75d180197c5cb679ebfd21324dc36790b50a7aa Signed-off-by: Shuhei Matsumoto Reviewed-on: https://review.gerrithub.io/389667 Tested-by: SPDK Automated Test System Reviewed-by: Jim Harris Reviewed-by: Daniel Verkamp --- lib/iscsi/tgt_node.c | 124 +++++++++++++++++++++++++++++++++++++------ lib/iscsi/tgt_node.h | 7 +++ 2 files changed, 114 insertions(+), 17 deletions(-) diff --git a/lib/iscsi/tgt_node.c b/lib/iscsi/tgt_node.c index 40d82460c..1ad488d2d 100644 --- a/lib/iscsi/tgt_node.c +++ b/lib/iscsi/tgt_node.c @@ -633,8 +633,47 @@ spdk_iscsi_tgt_node_destruct(struct spdk_iscsi_tgt_node *target) } static int -spdk_iscsi_tgt_node_add_map(struct spdk_iscsi_tgt_node *target, - int pg_tag, int ig_tag) +spdk_iscsi_tgt_node_delete_pg_ig_map(struct spdk_iscsi_tgt_node *target, + int pg_tag, int ig_tag) +{ + struct spdk_iscsi_portal_grp *pg; + struct spdk_iscsi_init_grp *ig; + struct spdk_iscsi_pg_map *pg_map; + struct spdk_iscsi_ig_map *ig_map; + + pg = spdk_iscsi_portal_grp_find_by_tag(pg_tag); + if (pg == NULL) { + SPDK_ERRLOG("%s: PortalGroup%d not found\n", target->name, pg_tag); + return -ENOENT; + } + ig = spdk_iscsi_init_grp_find_by_tag(ig_tag); + if (ig == NULL) { + SPDK_ERRLOG("%s: InitiatorGroup%d not found\n", target->name, ig_tag); + return -ENOENT; + } + + pg_map = spdk_iscsi_tgt_node_find_pg_map(target, pg); + if (pg_map == NULL) { + SPDK_ERRLOG("%s: PortalGroup%d is not mapped\n", target->name, pg_tag); + return -ENOENT; + } + ig_map = spdk_iscsi_pg_map_find_ig_map(pg_map, ig); + if (ig_map == NULL) { + SPDK_ERRLOG("%s: InitiatorGroup%d is not mapped\n", target->name, pg_tag); + return -ENOENT; + } + + _spdk_iscsi_pg_map_delete_ig_map(pg_map, ig_map); + if (pg_map->num_ig_maps == 0) { + _spdk_iscsi_tgt_node_delete_pg_map(target, pg_map); + } + + return 0; +} + +static int +spdk_iscsi_tgt_node_add_pg_ig_map(struct spdk_iscsi_tgt_node *target, + int pg_tag, int ig_tag) { struct spdk_iscsi_portal_grp *pg; struct spdk_iscsi_pg_map *pg_map; @@ -642,16 +681,13 @@ spdk_iscsi_tgt_node_add_map(struct spdk_iscsi_tgt_node *target, struct spdk_iscsi_ig_map *ig_map; bool new_pg_map = false; - pthread_mutex_lock(&g_spdk_iscsi.mutex); pg = spdk_iscsi_portal_grp_find_by_tag(pg_tag); if (pg == NULL) { - pthread_mutex_unlock(&g_spdk_iscsi.mutex); SPDK_ERRLOG("%s: PortalGroup%d not found\n", target->name, pg_tag); return -ENOENT; } ig = spdk_iscsi_init_grp_find_by_tag(ig_tag); if (ig == NULL) { - pthread_mutex_unlock(&g_spdk_iscsi.mutex); SPDK_ERRLOG("%s: InitiatorGroup%d not found\n", target->name, ig_tag); return -ENOENT; } @@ -672,14 +708,72 @@ spdk_iscsi_tgt_node_add_map(struct spdk_iscsi_tgt_node *target, goto failed; } - pthread_mutex_unlock(&g_spdk_iscsi.mutex); return 0; failed: if (new_pg_map) { - spdk_iscsi_tgt_node_delete_pg_map(target, pg); + _spdk_iscsi_tgt_node_delete_pg_map(target, pg_map); } + return -1; +} + +int +spdk_iscsi_tgt_node_add_pg_ig_maps(struct spdk_iscsi_tgt_node *target, + int *pg_tag_list, int *ig_tag_list, uint16_t num_maps) +{ + uint16_t i; + int rc; + + pthread_mutex_lock(&g_spdk_iscsi.mutex); + for (i = 0; i < num_maps; i++) { + rc = spdk_iscsi_tgt_node_add_pg_ig_map(target, pg_tag_list[i], + ig_tag_list[i]); + if (rc != 0) { + SPDK_ERRLOG("could not add map to target\n"); + goto invalid; + } + } + pthread_mutex_unlock(&g_spdk_iscsi.mutex); + return 0; + +invalid: + for (; i > 0; --i) { + spdk_iscsi_tgt_node_delete_pg_ig_map(target, pg_tag_list[i - 1], + ig_tag_list[i - 1]); + } + pthread_mutex_unlock(&g_spdk_iscsi.mutex); + return -1; +} + +int +spdk_iscsi_tgt_node_delete_pg_ig_maps(struct spdk_iscsi_tgt_node *target, + int *pg_tag_list, int *ig_tag_list, uint16_t num_maps) +{ + uint16_t i; + int rc; + + pthread_mutex_lock(&g_spdk_iscsi.mutex); + for (i = 0; i < num_maps; i++) { + rc = spdk_iscsi_tgt_node_delete_pg_ig_map(target, pg_tag_list[i], + ig_tag_list[i]); + if (rc != 0) { + SPDK_ERRLOG("could not delete map from target\n"); + goto invalid; + } + } + pthread_mutex_unlock(&g_spdk_iscsi.mutex); + return 0; + +invalid: + for (; i > 0; --i) { + rc = spdk_iscsi_tgt_node_add_pg_ig_map(target, pg_tag_list[i - 1], + ig_tag_list[i - 1]); + if (rc != 0) { + spdk_iscsi_tgt_node_delete_all_pg_maps(target); + break; + } + } pthread_mutex_unlock(&g_spdk_iscsi.mutex); return -1; } @@ -737,7 +831,7 @@ spdk_iscsi_tgt_node_construct(int target_index, { char fullname[MAX_TMPBUF]; struct spdk_iscsi_tgt_node *target; - int i, rc; + int rc; if (auth_chap_disabled && auth_chap_required) { SPDK_ERRLOG("auth_chap_disabled and auth_chap_required are mutually exclusive\n"); @@ -812,15 +906,11 @@ spdk_iscsi_tgt_node_construct(int target_index, } TAILQ_INIT(&target->pg_map_head); - for (i = 0; i < num_maps; i++) { - rc = spdk_iscsi_tgt_node_add_map(target, pg_tag_list[i], - ig_tag_list[i]); - - if (rc != 0) { - SPDK_ERRLOG("could not add map to target\n"); - spdk_iscsi_tgt_node_destruct(target); - return NULL; - } + rc = spdk_iscsi_tgt_node_add_pg_ig_maps(target, pg_tag_list, ig_tag_list, num_maps); + if (rc != 0) { + SPDK_ERRLOG("could not add map to target\n"); + spdk_iscsi_tgt_node_destruct(target); + return NULL; } target->auth_chap_disabled = auth_chap_disabled; diff --git a/lib/iscsi/tgt_node.h b/lib/iscsi/tgt_node.h index 084cf3426..e3eb20f29 100644 --- a/lib/iscsi/tgt_node.h +++ b/lib/iscsi/tgt_node.h @@ -109,6 +109,13 @@ spdk_iscsi_tgt_node_construct(int target_index, int no_auth_chap, int auth_chap, int auth_chap_mutual, int auth_group, int header_digest, int data_digest); +int spdk_iscsi_tgt_node_add_pg_ig_maps(struct spdk_iscsi_tgt_node *target, + int *pg_tag_list, int *ig_tag_list, + uint16_t num_maps); +int spdk_iscsi_tgt_node_delete_pg_ig_maps(struct spdk_iscsi_tgt_node *target, + int *pg_tag_list, int *ig_tag_list, + uint16_t num_maps); + bool spdk_iscsi_tgt_node_access(struct spdk_iscsi_conn *conn, struct spdk_iscsi_tgt_node *target, const char *iqn, const char *addr);