Commit c5e5047d authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Jim Harris
Browse files

iscsi: Manage PG-IG maps of the target by linked list



This patch is a preparation for dynamic reconfiguration of PG-IG maps.

Current PG-IG map is implemented by a fixed-size array. Linked list
will make much easier to support dynamic reconfiguration of PG-IG maps.

Current:
target - (1..n) ---> PG_map (1..1) -> PG
                 |
                 --> IG_map (1..1) -> IG

This proposal:
target - (1..n) -> PG_map --- (1..1) -> PG
                           |
                           -- (1..m) -> IG_map - (1..1) -> IG

Change-Id: I92f668b81cdd8003aff222926f8f1ed96b61e56d
Signed-off-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/385532


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
parent d07df584
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -255,6 +255,8 @@ spdk_rpc_get_target_nodes(struct spdk_jsonrpc_request *request,
{
	struct spdk_json_write_ctx *w;
	struct spdk_iscsi_tgt_node *tgtnode;
	struct spdk_iscsi_pg_map *pg_map;
	struct spdk_iscsi_ig_map *ig_map;
	int i;

	if (params != NULL) {
@@ -283,14 +285,16 @@ spdk_rpc_get_target_nodes(struct spdk_jsonrpc_request *request,

		spdk_json_write_name(w, "pg_ig_maps");
		spdk_json_write_array_begin(w);
		for (i = 0; i < tgtnode->maxmap; i++) {
		TAILQ_FOREACH(pg_map, &tgtnode->pg_map_head, tailq) {
			TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
				spdk_json_write_object_begin(w);
				spdk_json_write_name(w, "pg_tag");
			spdk_json_write_int32(w, tgtnode->map[i].pg->tag);
				spdk_json_write_int32(w, pg_map->pg->tag);
				spdk_json_write_name(w, "ig_tag");
			spdk_json_write_int32(w, tgtnode->map[i].ig->tag);
				spdk_json_write_int32(w, ig_map->ig->tag);
				spdk_json_write_object_end(w);
			}
		}
		spdk_json_write_array_end(w);

		spdk_json_write_name(w, "luns");
+9 −8
Original line number Diff line number Diff line
@@ -228,9 +228,11 @@ static const char *target_nodes_section = \
static void
spdk_iscsi_config_dump_target_nodes(FILE *fp)
{
	int l = 0, m = 0;
	int l = 0;
	struct spdk_scsi_dev *dev = NULL;
	struct spdk_iscsi_tgt_node *target = NULL;
	struct spdk_iscsi_pg_map *pg_map;
	struct spdk_iscsi_ig_map *ig_map;

	/* Create target nodes section */
	fprintf(fp, "%s", target_nodes_section);
@@ -247,13 +249,12 @@ spdk_iscsi_config_dump_target_nodes(FILE *fp)
		idx = target->num;
		fprintf(fp, TARGET_NODE_TMPL, idx, idx, target->name, spdk_scsi_dev_get_name(dev));

		for (m = 0; m < target->maxmap; m++) {
			if (NULL == target->map[m].pg) continue;
			if (NULL == target->map[m].ig) continue;

		TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
			TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
				fprintf(fp, TARGET_NODE_PGIG_MAPPING_TMPL,
				target->map[m].pg->tag,
				target->map[m].ig->tag);
					pg_map->pg->tag,
					ig_map->ig->tag);
			}
		}

		if (target->auth_chap_disabled)
+309 −177
Original line number Diff line number Diff line
@@ -214,13 +214,17 @@ spdk_iscsi_init_grp_allow_iscsi_name(struct spdk_iscsi_init_grp *igp,
	return -1;
}

static struct spdk_iscsi_pg_map *
spdk_iscsi_tgt_node_find_pg_map(struct spdk_iscsi_tgt_node *target,
				struct spdk_iscsi_portal_grp *pg);

bool
spdk_iscsi_tgt_node_access(struct spdk_iscsi_conn *conn,
			   struct spdk_iscsi_tgt_node *target, const char *iqn, const char *addr)
{
	struct spdk_iscsi_portal_grp *pg;
	struct spdk_iscsi_init_grp *igp;
	int i;
	struct spdk_iscsi_pg_map *pg_map;
	struct spdk_iscsi_ig_map *ig_map;
	int rc;
	bool allowed = false;

@@ -230,17 +234,17 @@ spdk_iscsi_tgt_node_access(struct spdk_iscsi_conn *conn,

	SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "pg=%d, iqn=%s, addr=%s\n",
		      pg->tag, iqn, addr);
	for (i = 0; i < target->maxmap; i++) {
		/* skip excluding self portal group tag */
		if (pg != target->map[i].pg)
			continue;
		igp = target->map[i].ig;
		rc = spdk_iscsi_init_grp_allow_iscsi_name(igp, iqn, &allowed);
	pg_map = spdk_iscsi_tgt_node_find_pg_map(target, pg);
	if (pg_map == NULL) {
		return false;
	}
	TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
		rc = spdk_iscsi_init_grp_allow_iscsi_name(ig_map->ig, iqn, &allowed);
		if (rc == 0) {
			if (allowed == false) {
				goto denied;
			} else {
				if (spdk_iscsi_init_grp_allow_addr(igp, addr)) {
				if (spdk_iscsi_init_grp_allow_addr(ig_map->ig, addr)) {
					return true;
				}
			}
@@ -259,28 +263,21 @@ denied:
static bool
spdk_iscsi_tgt_node_allow_iscsi_name(struct spdk_iscsi_tgt_node *target, const char *iqn)
{
	struct spdk_iscsi_init_grp *igp;
	int i, j;
	struct spdk_iscsi_pg_map *pg_map;
	struct spdk_iscsi_ig_map *ig_map;
	int rc;
	bool result = false;

	if (target == NULL || iqn == NULL)
		return false;

	for (i = 0; i < target->maxmap; i++) {
		igp = target->map[i].ig;
		/* skip same ig_tag */
		for (j = 0; j < i; j++) {
			if (target->map[j].ig->tag == igp->tag) {
				goto skip_ig_tag;
			}
		}
		rc = spdk_iscsi_init_grp_allow_iscsi_name(igp, iqn, &result);
	TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
		TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
			rc = spdk_iscsi_init_grp_allow_iscsi_name(ig_map->ig, iqn, &result);
			if (rc == 0) {
				return result;
			}
skip_ig_tag:
		;
		}
	}

	return false;
@@ -293,14 +290,13 @@ spdk_iscsi_send_tgts(struct spdk_iscsi_conn *conn, const char *iiqn,
{
	char buf[MAX_TMPBUF];
	struct spdk_iscsi_portal_grp	*pg;
	struct spdk_iscsi_pg_map	*pg_map;
	struct spdk_iscsi_portal	*p;
	struct spdk_iscsi_tgt_node	*target;
	char *host;
	int total;
	int len;
	int rc;
	int pg_tag;
	int i, j;

	if (conn == NULL)
		return 0;
@@ -336,18 +332,9 @@ spdk_iscsi_send_tgts(struct spdk_iscsi_conn *conn, const char *iiqn,
			       "TargetName=%s", target->name);
		total += len + 1;

		for (i = 0; i < target->maxmap; i++) {
			pg_tag = target->map[i].pg->tag;
			/* skip same pg_tag */
			for (j = 0; j < i; j++) {
				if (target->map[j].pg->tag == pg_tag) {
					goto skip_pg_tag;
				}
			}
		/* write to data */
			TAILQ_FOREACH(pg, &g_spdk_iscsi.pg_head, tailq) {
				if (pg->tag != pg_tag)
					continue;
		TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
			pg = pg_map->pg;
			TAILQ_FOREACH(p, &pg->head, per_pg_tailq) {
				if (alloc_len - total < 1) {
					pthread_mutex_unlock(&g_spdk_iscsi.mutex);
@@ -381,9 +368,6 @@ spdk_iscsi_send_tgts(struct spdk_iscsi_conn *conn, const char *iiqn,
				total += len + 1;
			}
		}
skip_pg_tag:
			;
		}
	}
	pthread_mutex_unlock(&g_spdk_iscsi.mutex);

@@ -446,104 +430,281 @@ spdk_iscsi_tgt_node_unregister(struct spdk_iscsi_tgt_node *target)
	return -1;
}

static struct spdk_iscsi_ig_map *
spdk_iscsi_pg_map_find_ig_map(struct spdk_iscsi_pg_map *pg_map,
			      struct spdk_iscsi_init_grp *ig)
{
	struct spdk_iscsi_ig_map *ig_map;

	TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
		if (ig_map->ig == ig) {
			return ig_map;
		}
	}

	return NULL;
}

static struct spdk_iscsi_ig_map *
spdk_iscsi_pg_map_add_ig_map(struct spdk_iscsi_pg_map *pg_map,
			     struct spdk_iscsi_init_grp *ig)
{
	struct spdk_iscsi_ig_map *ig_map;

	if (spdk_iscsi_pg_map_find_ig_map(pg_map, ig) != NULL) {
		return NULL;
	}

	ig_map = malloc(sizeof(*ig_map));
	if (ig_map == NULL) {
		return NULL;
	}

	ig_map->ig = ig;
	ig->ref++;
	pg_map->num_ig_maps++;
	TAILQ_INSERT_TAIL(&pg_map->ig_map_head, ig_map, tailq);

	return ig_map;
}

static void
_spdk_iscsi_pg_map_delete_ig_map(struct spdk_iscsi_pg_map *pg_map,
				 struct spdk_iscsi_ig_map *ig_map)
{
	TAILQ_REMOVE(&pg_map->ig_map_head, ig_map, tailq);
	pg_map->num_ig_maps--;
	ig_map->ig->ref--;
	free(ig_map);
}

static int
spdk_check_iscsi_name(const char *name)
spdk_iscsi_pg_map_delete_ig_map(struct spdk_iscsi_pg_map *pg_map,
				struct spdk_iscsi_init_grp *ig)
{
	const unsigned char *up = (const unsigned char *) name;
	size_t n;
	struct spdk_iscsi_ig_map *ig_map;

	/* valid iSCSI name? */
	for (n = 0; up[n] != 0; n++) {
		if (up[n] > 0x00U && up[n] <= 0x2cU)
			return -1;
		if (up[n] == 0x2fU)
			return -1;
		if (up[n] >= 0x3bU && up[n] <= 0x40U)
			return -1;
		if (up[n] >= 0x5bU && up[n] <= 0x60U)
			return -1;
		if (up[n] >= 0x7bU && up[n] <= 0x7fU)
			return -1;
		if (isspace(up[n]))
			return -1;
	ig_map = spdk_iscsi_pg_map_find_ig_map(pg_map, ig);
	if (ig_map == NULL) {
		return -ENOENT;
	}
	/* valid format? */
	if (strncasecmp(name, "iqn.", 4) == 0) {
		/* iqn.YYYY-MM.reversed.domain.name */
		if (!isdigit(up[4]) || !isdigit(up[5]) || !isdigit(up[6])
		    || !isdigit(up[7]) || up[8] != '-' || !isdigit(up[9])
		    || !isdigit(up[10]) || up[11] != '.') {
			SPDK_ERRLOG("invalid iqn format. "
				    "expect \"iqn.YYYY-MM.reversed.domain.name\"\n");
			return -1;

	_spdk_iscsi_pg_map_delete_ig_map(pg_map, ig_map);
	return 0;
}
	} else if (strncasecmp(name, "eui.", 4) == 0) {
		/* EUI-64 -> 16bytes */
		/* XXX */
	} else if (strncasecmp(name, "naa.", 4) == 0) {
		/* 64bit -> 16bytes, 128bit -> 32bytes */
		/* XXX */

static void
spdk_iscsi_pg_map_delete_all_ig_maps(struct spdk_iscsi_pg_map *pg_map)
{
	struct spdk_iscsi_ig_map *ig_map, *tmp;

	TAILQ_FOREACH_SAFE(ig_map, &pg_map->ig_map_head, tailq, tmp) {
		_spdk_iscsi_pg_map_delete_ig_map(pg_map, ig_map);
	}
	/* OK */
}

static struct spdk_iscsi_pg_map *
spdk_iscsi_tgt_node_find_pg_map(struct spdk_iscsi_tgt_node *target,
				struct spdk_iscsi_portal_grp *pg)
{
	struct spdk_iscsi_pg_map *pg_map;

	TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
		if (pg_map->pg == pg) {
			return pg_map;
		}
	}

	return NULL;
}

static struct spdk_iscsi_pg_map *
spdk_iscsi_tgt_node_add_pg_map(struct spdk_iscsi_tgt_node *target,
			       struct spdk_iscsi_portal_grp *pg)
{
	struct spdk_iscsi_pg_map *pg_map;

	if (spdk_iscsi_tgt_node_find_pg_map(target, pg) != NULL) {
		return NULL;
	}

	pg_map = malloc(sizeof(*pg_map));
	if (pg_map == NULL) {
		return NULL;
	}

	TAILQ_INIT(&pg_map->ig_map_head);
	pg_map->num_ig_maps = 0;
	pg->ref++;
	pg_map->pg = pg;
	target->num_pg_maps++;
	TAILQ_INSERT_TAIL(&target->pg_map_head, pg_map, tailq);

	return pg_map;
}

static void
_spdk_iscsi_tgt_node_delete_pg_map(struct spdk_iscsi_tgt_node *target,
				   struct spdk_iscsi_pg_map *pg_map)
{
	TAILQ_REMOVE(&target->pg_map_head, pg_map, tailq);
	target->num_pg_maps--;
	pg_map->pg->ref--;
	free(pg_map);
}

static int
spdk_iscsi_tgt_node_delete_pg_map(struct spdk_iscsi_tgt_node *target,
				  struct spdk_iscsi_portal_grp *pg)
{
	struct spdk_iscsi_pg_map *pg_map;

	pg_map = spdk_iscsi_tgt_node_find_pg_map(target, pg);
	if (pg_map == NULL) {
		return -ENOENT;
	}

	if (pg_map->num_ig_maps > 0) {
		return -ENOTEMPTY;
	}

	_spdk_iscsi_tgt_node_delete_pg_map(target, pg_map);
	return 0;
}

static void
spdk_iscsi_tgt_node_destruct(struct spdk_iscsi_tgt_node *target)
spdk_iscsi_tgt_node_delete_ig_maps(struct spdk_iscsi_tgt_node *target,
				   struct spdk_iscsi_init_grp *ig)
{
	int i;
	struct spdk_iscsi_pg_map *pg_map, *tmp;

	TAILQ_FOREACH_SAFE(pg_map, &target->pg_map_head, tailq, tmp) {
		spdk_iscsi_pg_map_delete_ig_map(pg_map, ig);
		if (pg_map->num_ig_maps == 0) {
			_spdk_iscsi_tgt_node_delete_pg_map(target, pg_map);
		}
	}
}

static void
spdk_iscsi_tgt_node_delete_all_pg_maps(struct spdk_iscsi_tgt_node *target)
{
	struct spdk_iscsi_pg_map *pg_map, *tmp;

	TAILQ_FOREACH_SAFE(pg_map, &target->pg_map_head, tailq, tmp) {
		spdk_iscsi_pg_map_delete_all_ig_maps(pg_map);
		_spdk_iscsi_tgt_node_delete_pg_map(target, pg_map);
	}
}

static void
spdk_iscsi_tgt_node_destruct(struct spdk_iscsi_tgt_node *target)
{
	if (target == NULL) {
		return;
	}

	free(target->name);
	free(target->alias);
	spdk_iscsi_tgt_node_delete_all_pg_maps(target);
	spdk_scsi_dev_destruct(target->dev);
	for (i = 0; i < target->maxmap; i++) {
		target->map[i].pg->ref--;
		target->map[i].ig->ref--;
	}

	pthread_mutex_destroy(&target->mutex);
	free(target);
}

static struct spdk_iscsi_tgt_node_map *
static int
spdk_iscsi_tgt_node_add_map(struct spdk_iscsi_tgt_node *target,
			    int pg_tag, int ig_tag)
{
	struct spdk_iscsi_tgt_node_map	*map;
	struct spdk_iscsi_portal_grp	*pg;
	struct spdk_iscsi_pg_map 	*pg_map;
	struct spdk_iscsi_init_grp	*ig;

	if (target->maxmap >= MAX_TARGET_MAP) {
		SPDK_ERRLOG("%s: no space for new map\n", target->name);
		return NULL;
	}
	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 NULL;
		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 NULL;
		return -ENOENT;
	}
	pg->ref++;
	ig->ref++;

	/* get existing pg_map or create new pg_map and add it to target */
	pg_map = spdk_iscsi_tgt_node_find_pg_map(target, pg);
	if (pg_map == NULL) {
		pg_map = spdk_iscsi_tgt_node_add_pg_map(target, pg);
		if (pg_map == NULL) {
			goto failed;
		}
		new_pg_map = true;
	}

	/* create new ig_map and add it to pg_map */
	ig_map = spdk_iscsi_pg_map_add_ig_map(pg_map, ig);
	if (ig_map == NULL) {
		goto failed;
	}

	pthread_mutex_unlock(&g_spdk_iscsi.mutex);
	map = &target->map[target->maxmap];
	map->pg = pg;
	map->ig = ig;
	target->maxmap++;
	return 0;

failed:
	if (new_pg_map) {
		spdk_iscsi_tgt_node_delete_pg_map(target, pg);
	}

	pthread_mutex_unlock(&g_spdk_iscsi.mutex);
	return -1;
}

static int
spdk_check_iscsi_name(const char *name)
{
	const unsigned char *up = (const unsigned char *) name;
	size_t n;

	return map;
	/* valid iSCSI name? */
	for (n = 0; up[n] != 0; n++) {
		if (up[n] > 0x00U && up[n] <= 0x2cU)
			return -1;
		if (up[n] == 0x2fU)
			return -1;
		if (up[n] >= 0x3bU && up[n] <= 0x40U)
			return -1;
		if (up[n] >= 0x5bU && up[n] <= 0x60U)
			return -1;
		if (up[n] >= 0x7bU && up[n] <= 0x7fU)
			return -1;
		if (isspace(up[n]))
			return -1;
	}
	/* valid format? */
	if (strncasecmp(name, "iqn.", 4) == 0) {
		/* iqn.YYYY-MM.reversed.domain.name */
		if (!isdigit(up[4]) || !isdigit(up[5]) || !isdigit(up[6])
		    || !isdigit(up[7]) || up[8] != '-' || !isdigit(up[9])
		    || !isdigit(up[10]) || up[11] != '.') {
			SPDK_ERRLOG("invalid iqn format. "
				    "expect \"iqn.YYYY-MM.reversed.domain.name\"\n");
			return -1;
		}
	} else if (strncasecmp(name, "eui.", 4) == 0) {
		/* EUI-64 -> 16bytes */
		/* XXX */
	} else if (strncasecmp(name, "naa.", 4) == 0) {
		/* 64bit -> 16bytes, 128bit -> 32bytes */
		/* XXX */
	}
	/* OK */
	return 0;
}

_spdk_iscsi_tgt_node *
@@ -557,19 +718,18 @@ spdk_iscsi_tgt_node_construct(int target_index,
{
	char				fullname[MAX_TMPBUF], port_name[MAX_TMPBUF];
	struct spdk_iscsi_tgt_node	*target;
	struct spdk_iscsi_tgt_node_map *map;
	struct spdk_iscsi_portal_grp	*unique_portal_groups[SPDK_SCSI_DEV_MAX_PORTS];
	struct spdk_iscsi_portal_grp	*pg;
	struct spdk_iscsi_pg_map	*pg_map;
	int				num_unique_portal_groups;
	int				i, j, rc;
	int				i, rc;

	if (auth_chap_disabled && auth_chap_required) {
		SPDK_ERRLOG("auth_chap_disabled and auth_chap_required are mutually exclusive\n");
		return NULL;
	}

	if ((num_maps > MAX_TARGET_MAP) || (num_maps == 0)) {
		SPDK_ERRLOG("num_maps = %d out of range\n", num_maps);
	if (num_maps == 0) {
		SPDK_ERRLOG("num_maps = 0\n");
		return NULL;
	}

@@ -635,37 +795,31 @@ spdk_iscsi_tgt_node_construct(int target_index,
		return NULL;
	}

	num_unique_portal_groups = 0;
	TAILQ_INIT(&target->pg_map_head);
	for (i = 0; i < num_maps; i++) {
		map = spdk_iscsi_tgt_node_add_map(target, pg_tag_list[i],
		rc = spdk_iscsi_tgt_node_add_map(target, pg_tag_list[i],
						 ig_tag_list[i]);

		if (map == NULL) {
		if (rc != 0) {
			SPDK_ERRLOG("could not add map to target\n");
			spdk_iscsi_tgt_node_destruct(target);
			return NULL;
		}

		for (j = 0; j < num_unique_portal_groups; j++) {
			if (unique_portal_groups[j] == map->pg) {
				break;
			}
	}

		if (j == SPDK_SCSI_DEV_MAX_PORTS) {
	num_unique_portal_groups = 0;
	TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {

		if (++num_unique_portal_groups > SPDK_SCSI_DEV_MAX_PORTS) {
			SPDK_ERRLOG("too many unique portal groups\n");
			spdk_iscsi_tgt_node_destruct(target);
			return NULL;
		}

		if (j == num_unique_portal_groups) {
			pg = map->pg;
		pg = pg_map->pg;
		snprintf(port_name, sizeof(port_name), "%s,t,0x%4.4x",
			 name, pg->tag);
		spdk_scsi_dev_add_port(target->dev, pg->tag, port_name);
			unique_portal_groups[j] = pg;
			num_unique_portal_groups++;
		}
	}

	target->auth_chap_disabled = auth_chap_disabled;
@@ -1002,37 +1156,15 @@ void spdk_iscsi_tgt_node_delete_map(struct spdk_iscsi_portal_grp *portal_group,
				    struct spdk_iscsi_init_grp *initiator_group)
{
	struct spdk_iscsi_tgt_node *target;
	int i = 0;
	int j = 0;
	int flag = 0;

	pthread_mutex_lock(&g_spdk_iscsi.mutex);
	TAILQ_FOREACH(target, &g_spdk_iscsi.target_head, tailq) {
loop:
		flag = 0;
		for (i = 0; i < target->maxmap; i++) {
		if (portal_group) {
				if (target->map[i].pg->tag == portal_group->tag) {
					flag = 1;
				}
			spdk_iscsi_tgt_node_delete_pg_map(target, portal_group);
		}
		if (initiator_group) {
				if (target->map[i].ig->tag == initiator_group->tag) {
					flag = 1;
				}
			}

			if (flag == 1) {
				target->map[i].pg->ref--;
				target->map[i].ig->ref--;
				for (j = i; j < target->maxmap - 1; j++) {
					target->map[j].pg = target->map[j + 1].pg;
					target->map[j].ig = target->map[j + 1].ig;
				}
				target->map[target->maxmap - 1].pg = NULL;
				target->map[target->maxmap - 1].ig = NULL;
				target->maxmap -= 1;
				goto loop;
			}
			spdk_iscsi_tgt_node_delete_ig_maps(target, initiator_group);
		}
	}
	pthread_mutex_unlock(&g_spdk_iscsi.mutex);
}
+15 −5
Original line number Diff line number Diff line
@@ -40,14 +40,24 @@
#include "spdk/scsi.h"

struct spdk_iscsi_conn;
struct spdk_iscsi_init_grp;
struct spdk_iscsi_portal_grp;
struct spdk_iscsi_portal;

#define SPDK_ISCSI_MAX_QUEUE_DEPTH	64
#define MAX_TARGET_MAP			256
#define SPDK_TN_TAG_MAX 0x0000ffff

struct spdk_iscsi_tgt_node_map {
	struct spdk_iscsi_portal_grp	*pg;
struct spdk_iscsi_ig_map {
	struct spdk_iscsi_init_grp *ig;
	TAILQ_ENTRY(spdk_iscsi_ig_map) tailq;
};

struct spdk_iscsi_pg_map {
	struct spdk_iscsi_portal_grp *pg;
	int num_ig_maps;
	TAILQ_HEAD(, spdk_iscsi_ig_map) ig_map_head;
	TAILQ_ENTRY(spdk_iscsi_pg_map) tailq ;
};

struct spdk_iscsi_tgt_node {
@@ -73,8 +83,8 @@ struct spdk_iscsi_tgt_node {
	uint32_t num_active_conns;
	int lcore;

	int maxmap;
	struct spdk_iscsi_tgt_node_map map[MAX_TARGET_MAP];
	int num_pg_maps;
	TAILQ_HEAD(, spdk_iscsi_pg_map) pg_map_head;
	TAILQ_ENTRY(spdk_iscsi_tgt_node) tailq;
};

+34 −17
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@ node_access_allowed(void)
	struct spdk_iscsi_portal portal;
	struct spdk_iscsi_initiator_name iname;
	struct spdk_iscsi_initiator_netmask imask;
	struct spdk_iscsi_pg_map *pg_map;
	char *iqn, *addr;
	bool result;

@@ -209,10 +210,10 @@ node_access_allowed(void)

	/* target initialization */
	memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
	tgtnode.maxmap = 1;
	tgtnode.name = "iqn.2017-10.spdk.io:0001";
	tgtnode.map[0].pg = &pg;
	tgtnode.map[0].ig = &ig;
	TAILQ_INIT(&tgtnode.pg_map_head);
	pg_map = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg);
	spdk_iscsi_pg_map_add_ig_map(pg_map, &ig);

	/* portal initialization */
	memset(&portal, 0, sizeof(struct spdk_iscsi_portal));
@@ -229,6 +230,9 @@ node_access_allowed(void)

	result = spdk_iscsi_tgt_node_access(&conn, &tgtnode, iqn, addr);
	CU_ASSERT(result == true);

	spdk_iscsi_pg_map_delete_ig_map(pg_map, &ig);
	spdk_iscsi_tgt_node_delete_pg_map(&tgtnode, &pg);
}

static void
@@ -240,6 +244,7 @@ node_access_denied_by_empty_netmask(void)
	struct spdk_iscsi_conn conn;
	struct spdk_iscsi_portal portal;
	struct spdk_iscsi_initiator_name iname;
	struct spdk_iscsi_pg_map *pg_map;
	char *iqn, *addr;
	bool result;

@@ -261,10 +266,10 @@ node_access_denied_by_empty_netmask(void)

	/* target initialization */
	memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
	tgtnode.maxmap = 1;
	tgtnode.name = "iqn.2017-10.spdk.io:0001";
	tgtnode.map[0].pg = &pg;
	tgtnode.map[0].ig = &ig;
	TAILQ_INIT(&tgtnode.pg_map_head);
	pg_map = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg);
	spdk_iscsi_pg_map_add_ig_map(pg_map, &ig);

	/* portal initialization */
	memset(&portal, 0, sizeof(struct spdk_iscsi_portal));
@@ -282,6 +287,8 @@ node_access_denied_by_empty_netmask(void)
	result = spdk_iscsi_tgt_node_access(&conn, &tgtnode, iqn, addr);
	CU_ASSERT(result == false);

	spdk_iscsi_pg_map_delete_ig_map(pg_map, &ig);
	spdk_iscsi_tgt_node_delete_pg_map(&tgtnode, &pg);
}

#define IQN1	"iqn.2017-11.spdk.io:0001"
@@ -300,18 +307,17 @@ node_access_multi_initiator_groups_cases(void)
	struct spdk_iscsi_init_grp ig1, ig2;
	struct spdk_iscsi_initiator_name iname1, iname2;
	struct spdk_iscsi_initiator_netmask imask1, imask2;
	struct spdk_iscsi_pg_map *pg_map;
	char *iqn, *addr;
	bool result;

	/* target initialization */
	memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
	tgtnode.maxmap = 2;
	tgtnode.name = IQN1;

	tgtnode.map[0].pg = &pg;
	tgtnode.map[0].ig = &ig1;
	tgtnode.map[1].pg = &pg;
	tgtnode.map[1].ig = &ig2;
	TAILQ_INIT(&tgtnode.pg_map_head);
	pg_map = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg);
	spdk_iscsi_pg_map_add_ig_map(pg_map, &ig1);
	spdk_iscsi_pg_map_add_ig_map(pg_map, &ig2);

	/* portal group initialization */
	memset(&pg, 0, sizeof(struct spdk_iscsi_portal_grp));
@@ -533,23 +539,30 @@ node_access_multi_initiator_groups_cases(void)

	result = spdk_iscsi_tgt_node_access(&conn, &tgtnode, iqn, addr);
	CU_ASSERT(result == false);

	spdk_iscsi_pg_map_delete_ig_map(pg_map, &ig1);
	spdk_iscsi_pg_map_delete_ig_map(pg_map, &ig2);
	spdk_iscsi_tgt_node_delete_pg_map(&tgtnode, &pg);
}

static void
allow_iscsi_name_multi_maps_case(void)
{
	struct spdk_iscsi_tgt_node tgtnode;
	struct spdk_iscsi_portal_grp pg1, pg2;
	struct spdk_iscsi_init_grp ig;
	struct spdk_iscsi_initiator_name iname;
	struct spdk_iscsi_pg_map *pg_map1, *pg_map2;
	char *iqn;
	bool result;

	/* target initialization */
	memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
	tgtnode.maxmap = 2;

	tgtnode.map[0].ig = &ig;
	tgtnode.map[1].ig = &ig;
	TAILQ_INIT(&tgtnode.pg_map_head);
	pg_map1 = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg1);
	pg_map2 = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg2);
	spdk_iscsi_pg_map_add_ig_map(pg_map1, &ig);
	spdk_iscsi_pg_map_add_ig_map(pg_map2, &ig);

	/* initiator group initialization */
	memset(&ig, 0, sizeof(struct spdk_iscsi_init_grp));
@@ -571,8 +584,12 @@ allow_iscsi_name_multi_maps_case(void)

	result = spdk_iscsi_tgt_node_allow_iscsi_name(&tgtnode, iqn);
	CU_ASSERT(result == false);
}

	spdk_iscsi_pg_map_delete_ig_map(pg_map1, &ig);
	spdk_iscsi_pg_map_delete_ig_map(pg_map2, &ig);
	spdk_iscsi_tgt_node_delete_pg_map(&tgtnode, &pg1);
	spdk_iscsi_tgt_node_delete_pg_map(&tgtnode, &pg2);
}

int
main(int argc, char **argv)