From 4185f77862288996d9d8d75a0547f7d7b7a97329 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Sat, 30 Sep 2017 11:23:27 +0900 Subject: [PATCH] iscsi: check duplication of portal by portal list Check duplication of registration of portals by using a global portal list Change-Id: I608fc9bd4473c11e69686e6474892f3f4272cd53 Signed-off-by: Shuhei Matsumoto Reviewed-on: https://review.gerrithub.io/379929 Reviewed-by: Jim Harris Tested-by: SPDK Automated Test System Reviewed-by: Daniel Verkamp --- lib/iscsi/acceptor.c | 2 +- lib/iscsi/iscsi.h | 1 + lib/iscsi/iscsi_rpc.c | 8 ++++---- lib/iscsi/iscsi_subsystem.c | 2 +- lib/iscsi/portal_grp.c | 32 ++++++++++++++++++++++++++++---- lib/iscsi/portal_grp.h | 3 ++- lib/iscsi/tgt_node.c | 2 +- 7 files changed, 38 insertions(+), 12 deletions(-) diff --git a/lib/iscsi/acceptor.c b/lib/iscsi/acceptor.c index d10e65973..5ccdd7084 100644 --- a/lib/iscsi/acceptor.c +++ b/lib/iscsi/acceptor.c @@ -85,7 +85,7 @@ spdk_acceptor(void *arg) struct spdk_iscsi_portal *portal; TAILQ_FOREACH(portal_group, &iscsi->pg_head, tailq) { - TAILQ_FOREACH(portal, &portal_group->head, tailq) { + TAILQ_FOREACH(portal, &portal_group->head, per_pg_tailq) { spdk_iscsi_portal_accept(portal); } } diff --git a/lib/iscsi/iscsi.h b/lib/iscsi/iscsi.h index b75b6bd29..45aee16cc 100644 --- a/lib/iscsi/iscsi.h +++ b/lib/iscsi/iscsi.h @@ -260,6 +260,7 @@ struct spdk_iscsi_globals { char *authfile; char *nodebase; pthread_mutex_t mutex; + TAILQ_HEAD(, spdk_iscsi_portal) portal_head; TAILQ_HEAD(, spdk_iscsi_portal_grp) pg_head; TAILQ_HEAD(, spdk_iscsi_init_grp) ig_head; int ntargets; diff --git a/lib/iscsi/iscsi_rpc.c b/lib/iscsi/iscsi_rpc.c index e405b3112..1fc762e32 100644 --- a/lib/iscsi/iscsi_rpc.c +++ b/lib/iscsi/iscsi_rpc.c @@ -638,7 +638,7 @@ spdk_rpc_get_portal_groups(struct spdk_jsonrpc_request *request, spdk_json_write_name(w, "portals"); spdk_json_write_array_begin(w); - TAILQ_FOREACH(portal, &pg->head, tailq) { + TAILQ_FOREACH(portal, &pg->head, per_pg_tailq) { spdk_json_write_object_begin(w); spdk_json_write_name(w, "host"); spdk_json_write_string(w, portal->host); @@ -737,7 +737,7 @@ spdk_rpc_add_portal_group(struct spdk_jsonrpc_request *request, struct rpc_portal_group req = {}; struct spdk_iscsi_portal *portal_list[MAX_PORTAL] = {}; struct spdk_json_write_ctx *w; - size_t i; + size_t i = 0; int rc = -1; if (spdk_json_decode_object(params, rpc_portal_group_decoders, @@ -773,8 +773,8 @@ out: } else { spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); - for (i = 0; i < req.portal_list.num_portals; i++) { - spdk_iscsi_portal_destroy(portal_list[i]); + for (; i > 0; --i) { + spdk_iscsi_portal_destroy(portal_list[i - 1]); } } free_rpc_portal_group(&req); diff --git a/lib/iscsi/iscsi_subsystem.c b/lib/iscsi/iscsi_subsystem.c index 86cee3f81..f5442fcf2 100644 --- a/lib/iscsi/iscsi_subsystem.c +++ b/lib/iscsi/iscsi_subsystem.c @@ -147,7 +147,7 @@ spdk_iscsi_config_dump_portal_groups(FILE *fp) if (NULL == pg) continue; fprintf(fp, PORTAL_GROUP_TMPL, pg->tag, pg->tag); /* Dump portals */ - TAILQ_FOREACH(p, &pg->head, tailq) { + TAILQ_FOREACH(p, &pg->head, per_pg_tailq) { if (NULL == p) continue; fprintf(fp, PORTAL_TMPL, p->host, p->port); } diff --git a/lib/iscsi/portal_grp.c b/lib/iscsi/portal_grp.c index c85fe3628..87fac87d9 100644 --- a/lib/iscsi/portal_grp.c +++ b/lib/iscsi/portal_grp.c @@ -49,6 +49,20 @@ static int spdk_iscsi_portal_grp_open(struct spdk_iscsi_portal_grp *pg); +static struct spdk_iscsi_portal * +spdk_iscsi_portal_find_by_addr(const char *host, const char *port) +{ + struct spdk_iscsi_portal *p; + + TAILQ_FOREACH(p, &g_spdk_iscsi.portal_head, g_tailq) { + if (!strcmp(p->host, host) && !strcmp(p->port, port)) { + return p; + } + } + + return NULL; +} + /* Assumes caller allocated host and port strings on the heap */ struct spdk_iscsi_portal * spdk_iscsi_portal_create(const char *host, const char *port, uint64_t cpumask) @@ -58,6 +72,12 @@ spdk_iscsi_portal_create(const char *host, const char *port, uint64_t cpumask) assert(host != NULL); assert(port != NULL); + p = spdk_iscsi_portal_find_by_addr(host, port); + if (p != NULL) { + SPDK_ERRLOG("portal (%s, %s) already exists\n", host, port); + return NULL; + } + p = malloc(sizeof(*p)); if (!p) { SPDK_ERRLOG("portal malloc error (%s, %s)\n", host, port); @@ -69,6 +89,8 @@ spdk_iscsi_portal_create(const char *host, const char *port, uint64_t cpumask) p->sock = -1; p->group = NULL; /* set at a later time by caller */ + TAILQ_INSERT_TAIL(&g_spdk_iscsi.portal_head, p, g_tailq); + return p; } @@ -78,6 +100,7 @@ spdk_iscsi_portal_destroy(struct spdk_iscsi_portal *p) assert(p != NULL); SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "spdk_iscsi_portal_destroy\n"); + TAILQ_REMOVE(&g_spdk_iscsi.portal_head, p, g_tailq); free(p->host); free(p->port); free(p); @@ -304,7 +327,7 @@ spdk_iscsi_portal_grp_destroy(struct spdk_iscsi_portal_grp *pg) SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "spdk_iscsi_portal_grp_destroy\n"); while (!TAILQ_EMPTY(&pg->head)) { p = TAILQ_FIRST(&pg->head); - TAILQ_REMOVE(&pg->head, p, tailq); + TAILQ_REMOVE(&pg->head, p, per_pg_tailq); spdk_iscsi_portal_destroy(p); } free(pg); @@ -466,7 +489,7 @@ spdk_iscsi_portal_grp_add_portal(struct spdk_iscsi_portal_grp *pg, assert(p != NULL); p->group = pg; - TAILQ_INSERT_TAIL(&pg->head, p, tailq); + TAILQ_INSERT_TAIL(&pg->head, p, per_pg_tailq); } struct spdk_iscsi_portal_grp * @@ -489,6 +512,7 @@ spdk_iscsi_portal_grp_array_create(void) int rc = 0; struct spdk_conf_section *sp; + TAILQ_INIT(&g_spdk_iscsi.portal_head); TAILQ_INIT(&g_spdk_iscsi.pg_head); sp = spdk_conf_first_section(NULL); while (sp != NULL) { @@ -531,7 +555,7 @@ spdk_iscsi_portal_grp_open(struct spdk_iscsi_portal_grp *pg) struct spdk_iscsi_portal *p; int rc; - TAILQ_FOREACH(p, &pg->head, tailq) { + TAILQ_FOREACH(p, &pg->head, per_pg_tailq) { rc = spdk_iscsi_portal_open(p); if (rc < 0) { return rc; @@ -564,7 +588,7 @@ spdk_iscsi_portal_grp_close(struct spdk_iscsi_portal_grp *pg) { struct spdk_iscsi_portal *p; - TAILQ_FOREACH(p, &pg->head, tailq) { + TAILQ_FOREACH(p, &pg->head, per_pg_tailq) { spdk_iscsi_portal_close(p); } } diff --git a/lib/iscsi/portal_grp.h b/lib/iscsi/portal_grp.h index c5fcc798b..7690a79fe 100644 --- a/lib/iscsi/portal_grp.h +++ b/lib/iscsi/portal_grp.h @@ -43,7 +43,8 @@ struct spdk_iscsi_portal { char *port; int sock; uint64_t cpumask; - TAILQ_ENTRY(spdk_iscsi_portal) tailq; + TAILQ_ENTRY(spdk_iscsi_portal) per_pg_tailq; + TAILQ_ENTRY(spdk_iscsi_portal) g_tailq; }; struct spdk_iscsi_portal_grp { diff --git a/lib/iscsi/tgt_node.c b/lib/iscsi/tgt_node.c index 107c06a80..2a1e12b3b 100644 --- a/lib/iscsi/tgt_node.c +++ b/lib/iscsi/tgt_node.c @@ -398,7 +398,7 @@ spdk_iscsi_send_tgts(struct spdk_iscsi_conn *conn, const char *iiqn, TAILQ_FOREACH(pg, &g_spdk_iscsi.pg_head, tailq) { if (pg->tag != pg_tag) continue; - TAILQ_FOREACH(p, &pg->head, tailq) { + TAILQ_FOREACH(p, &pg->head, per_pg_tailq) { if (alloc_len - total < 1) { pthread_mutex_unlock(&g_spdk_iscsi.mutex); SPDK_ERRLOG("data space small %d\n", alloc_len);