Commit b8705bf4 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Daniel Verkamp
Browse files

iscsi: manage IG's name and mask by linked list



To add initiators to an existing target, manage name and netmask
of initiator group by linked list. It is not easy for array to
detect duplication and change configuration.

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


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarZiye Yang <optimistyzy@gmail.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
parent 92ef1a64
Loading
Loading
Loading
Loading
+144 −41
Original line number Diff line number Diff line
@@ -62,99 +62,203 @@ spdk_iscsi_init_grp_create(int tag)

	ig->tag = tag;
	ig->state = GROUP_INIT;
	TAILQ_INIT(&ig->initiator_head);
	TAILQ_INIT(&ig->netmask_head);
	return ig;
}

static struct spdk_iscsi_initiator_name *
spdk_iscsi_init_grp_find_initiator(struct spdk_iscsi_init_grp *ig, char *name)
{
	struct spdk_iscsi_initiator_name *iname;

	TAILQ_FOREACH(iname, &ig->initiator_head, tailq) {
		if (!strcmp(iname->name, name)) {
			return iname;
		}
	}
	return NULL;
}

static int
spdk_iscsi_init_grp_add_initiators(struct spdk_iscsi_init_grp *ig, int num_inames, char **inames)
spdk_iscsi_init_grp_add_initiator(struct spdk_iscsi_init_grp *ig, char *name)
{
	int i;
	struct spdk_iscsi_initiator_name *iname;

	if (num_inames > MAX_INITIATOR) {
		SPDK_ERRLOG("%d > MAX_INITIATOR\n", num_inames);
	if (ig->ninitiators >= MAX_INITIATOR) {
		SPDK_ERRLOG("> MAX_INITIATOR(=%d) is not allowed\n", MAX_INITIATOR);
		return -EPERM;
	}

	ig->initiators = calloc(num_inames, sizeof(char *));
	if (ig->initiators == NULL) {
	iname = spdk_iscsi_init_grp_find_initiator(ig, name);
	if (iname != NULL) {
		return -EEXIST;
	}

	iname = malloc(sizeof(*iname));
	if (iname == NULL) {
		return -ENOMEM;
	}
	ig->ninitiators = num_inames;

	for (i = 0; i < ig->ninitiators; i++) {
		SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "InitiatorName %s\n", inames[i]);
		ig->initiators[i] = strdup(inames[i]);
		if (ig->initiators[i] == NULL) {
			goto cleanup;
	iname->name = strdup(name);
	if (iname->name == NULL) {
		free(iname);
		return -ENOMEM;
	}

	TAILQ_INSERT_TAIL(&ig->initiator_head, iname, tailq);
	ig->ninitiators++;

	SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "InitiatorName %s\n", name);
	return 0;
}

static int
spdk_iscsi_init_grp_delete_initiator(struct spdk_iscsi_init_grp *ig, char *name)
{
	struct spdk_iscsi_initiator_name *iname;

	iname = spdk_iscsi_init_grp_find_initiator(ig, name);
	if (iname == NULL) {
		return -ENOENT;
	}

	TAILQ_REMOVE(&ig->initiator_head, iname, tailq);
	ig->ninitiators--;
	free(iname->name);
	free(iname);
	return 0;
}

static int
spdk_iscsi_init_grp_add_initiators(struct spdk_iscsi_init_grp *ig, int num_inames, char **inames)
{
	int i;
	int rc;

	for (i = 0; i < num_inames; i++) {
		rc = spdk_iscsi_init_grp_add_initiator(ig, inames[i]);
		if (rc < 0) {
			goto cleanup;
		}
	}
	return 0;

cleanup:
	for (; i > 0; --i) {
		free(ig->initiators[i - 1]);
		spdk_iscsi_init_grp_delete_initiator(ig, inames[i - 1]);
	}
	free(ig->initiators);

	return -ENOMEM;
	return rc;
}

static void
spdk_iscsi_init_grp_delete_all_initiators(struct spdk_iscsi_init_grp *ig)
{
	int i;
	struct spdk_iscsi_initiator_name *iname, *tmp;

	for (i = 0; i < ig->ninitiators; i++) {
		free(ig->initiators[i]);
	TAILQ_FOREACH_SAFE(iname, &ig->initiator_head, tailq, tmp) {
		TAILQ_REMOVE(&ig->initiator_head, iname, tailq);
		ig->ninitiators--;
		free(iname->name);
		free(iname);
	}
	free(ig->initiators);
}

static struct spdk_iscsi_initiator_netmask *
spdk_iscsi_init_grp_find_netmask(struct spdk_iscsi_init_grp *ig, const char *mask)
{
	struct spdk_iscsi_initiator_netmask *netmask;

	TAILQ_FOREACH(netmask, &ig->netmask_head, tailq) {
		if (!strcmp(netmask->mask, mask)) {
			return netmask;
		}
	}
	return NULL;
}

static int
spdk_iscsi_init_grp_add_netmasks(struct spdk_iscsi_init_grp *ig, int num_imasks, char **imasks)
spdk_iscsi_init_grp_add_netmask(struct spdk_iscsi_init_grp *ig, char *mask)
{
	int i;
	struct spdk_iscsi_initiator_netmask *imask;

	if (num_imasks > MAX_NETMASK) {
		SPDK_ERRLOG("%d > MAX_NETMASK\n", num_imasks);
	if (ig->nnetmasks >= MAX_NETMASK) {
		SPDK_ERRLOG("> MAX_NETMASK(=%d) is not allowed\n", MAX_NETMASK);
		return -EPERM;
	}

	ig->netmasks = calloc(num_imasks, sizeof(char *));
	if (ig->netmasks == NULL) {
	imask = spdk_iscsi_init_grp_find_netmask(ig, mask);
	if (imask != NULL) {
		return -EEXIST;
	}

	imask = malloc(sizeof(*imask));
	if (imask == NULL) {
		return -ENOMEM;
	}
	ig->nnetmasks = num_imasks;

	for (i = 0; i < ig->nnetmasks; i++) {
		SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "Netmask %s\n", imasks[i]);
		ig->netmasks[i] = strdup(imasks[i]);
		if (ig->netmasks[i] == NULL) {
			goto cleanup;
	imask->mask = strdup(mask);
	if (imask->mask == NULL) {
		free(imask);
		return -ENOMEM;
	}

	TAILQ_INSERT_TAIL(&ig->netmask_head, imask, tailq);
	ig->nnetmasks++;

	SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "Netmask %s\n", mask);
	return 0;
}

static int
spdk_iscsi_init_grp_delete_netmask(struct spdk_iscsi_init_grp *ig, char *mask)
{
	struct spdk_iscsi_initiator_netmask *imask;

	imask = spdk_iscsi_init_grp_find_netmask(ig, mask);
	if (imask == NULL) {
		return -ENOENT;
	}

	TAILQ_REMOVE(&ig->netmask_head, imask, tailq);
	ig->nnetmasks--;
	free(imask->mask);
	free(imask);
	return 0;
}

static int
spdk_iscsi_init_grp_add_netmasks(struct spdk_iscsi_init_grp *ig, int num_imasks, char **imasks)
{
	int i;
	int rc;

	for (i = 0; i < num_imasks; i++) {
		rc = spdk_iscsi_init_grp_add_netmask(ig, imasks[i]);
		if (rc != 0) {
			goto cleanup;
		}
	}
	return 0;

cleanup:
	for (; i > 0; --i) {
		free(ig->netmasks[i - 1]);
		spdk_iscsi_init_grp_delete_netmask(ig, imasks[i - 1]);
	}
	free(ig->netmasks);

	return -ENOMEM;
	return rc;
}

static void
spdk_iscsi_init_grp_delete_all_netmasks(struct spdk_iscsi_init_grp *ig)
{
	int i;
	struct spdk_iscsi_initiator_netmask *imask, *tmp;

	for (i = 0; i < ig->nnetmasks; i++) {
		free(ig->netmasks[i]);
	TAILQ_FOREACH_SAFE(imask, &ig->netmask_head, tailq, tmp) {
		TAILQ_REMOVE(&ig->netmask_head, imask, tailq);
		ig->nnetmasks--;
		free(imask->mask);
		free(imask);
	}
	free(ig->netmasks);
}


@@ -312,7 +416,6 @@ spdk_iscsi_init_grp_create_from_initiator_list(int tag,
	}

	spdk_iscsi_init_grp_register(ig);

	return 0;

cleanup:
+12 −2
Original line number Diff line number Diff line
@@ -43,11 +43,21 @@ enum group_state {
	GROUP_DESTROY = 0x2,
};

struct spdk_iscsi_initiator_name {
	char *name;
	TAILQ_ENTRY(spdk_iscsi_initiator_name) tailq;
};

struct spdk_iscsi_initiator_netmask {
	char *mask;
	TAILQ_ENTRY(spdk_iscsi_initiator_netmask) tailq;
};

struct spdk_iscsi_init_grp {
	int ninitiators;
	char **initiators;
	TAILQ_HEAD(, spdk_iscsi_initiator_name) initiator_head;
	int nnetmasks;
	char **netmasks;
	TAILQ_HEAD(, spdk_iscsi_initiator_netmask) netmask_head;
	int ref;
	int tag;
	enum group_state state;
+6 −5
Original line number Diff line number Diff line
@@ -49,7 +49,8 @@ spdk_rpc_get_initiator_groups(struct spdk_jsonrpc_request *request,
{
	struct spdk_json_write_ctx *w;
	struct spdk_iscsi_init_grp *ig;
	int i;
	struct spdk_iscsi_initiator_name *iname;
	struct spdk_iscsi_initiator_netmask *imask;

	if (params != NULL) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
@@ -69,8 +70,8 @@ spdk_rpc_get_initiator_groups(struct spdk_jsonrpc_request *request,

		spdk_json_write_name(w, "initiators");
		spdk_json_write_array_begin(w);
		for (i = 0; i < ig->ninitiators; i++) {
			spdk_json_write_string(w, ig->initiators[i]);
		TAILQ_FOREACH(iname, &ig->initiator_head, tailq) {
			spdk_json_write_string(w, iname->name);
		}
		spdk_json_write_array_end(w);

@@ -79,8 +80,8 @@ spdk_rpc_get_initiator_groups(struct spdk_jsonrpc_request *request,

		spdk_json_write_name(w, "netmasks");
		spdk_json_write_array_begin(w);
		for (i = 0; i < ig->nnetmasks; i++) {
			spdk_json_write_string(w, ig->netmasks[i]);
		TAILQ_FOREACH(imask, &ig->netmask_head, tailq) {
			spdk_json_write_string(w, imask->mask);
		}
		spdk_json_write_array_end(w);

+8 −5
Original line number Diff line number Diff line
@@ -170,8 +170,9 @@ static const char *initiator_group_section = \
static void
spdk_iscsi_config_dump_initiator_groups(FILE *fp)
{
	int i;
	struct spdk_iscsi_init_grp *ig;
	struct spdk_iscsi_initiator_name *iname;
	struct spdk_iscsi_initiator_netmask *imask;

	/* Create initiator group section */
	fprintf(fp, "%s", initiator_group_section);
@@ -183,14 +184,16 @@ spdk_iscsi_config_dump_initiator_groups(FILE *fp)

		/* Dump initiators */
		fprintf(fp, INITIATOR_TMPL);
		for (i = 0; i < ig->ninitiators; i++)
			fprintf(fp, "%s ", ig->initiators[i]);
		TAILQ_FOREACH(iname, &ig->initiator_head, tailq) {
			fprintf(fp, "%s ", iname->name);
		}
		fprintf(fp, "\n");

		/* Dump netmasks */
		fprintf(fp, NETMASK_TMPL);
		for (i = 0; i < ig->nnetmasks; i++)
			fprintf(fp, "%s ", ig->netmasks[i]);
		TAILQ_FOREACH(imask, &ig->netmask_head, tailq) {
			fprintf(fp, "%s ", imask->mask);
		}
		fprintf(fp, "\n");
	}
}
+20 −17
Original line number Diff line number Diff line
@@ -180,7 +180,9 @@ spdk_iscsi_tgt_node_access(struct spdk_iscsi_conn *conn,
{
	struct spdk_iscsi_portal_grp *pg;
	struct spdk_iscsi_init_grp *igp;
	int i, j, k;
	struct spdk_iscsi_initiator_name *iname;
	struct spdk_iscsi_initiator_netmask *imask;
	int i;

	if (conn == NULL || target == NULL || iqn == NULL || addr == NULL)
		return false;
@@ -194,11 +196,11 @@ spdk_iscsi_tgt_node_access(struct spdk_iscsi_conn *conn,
			continue;
		/* iqn is initiator group? */
		igp = target->map[i].ig;
		for (j = 0; j < igp->ninitiators; j++) {
		TAILQ_FOREACH(iname, &igp->initiator_head, tailq) {
			/* deny initiators */
			if (igp->initiators[j][0] == '!'
			    && (strcasecmp(&igp->initiators[j][1], "ALL") == 0
				|| strcasecmp(&igp->initiators[j][1], iqn) == 0)) {
			if ((iname->name[0] == '!')
			    && (strcasecmp(&iname->name[1], "ALL") == 0
				|| strcasecmp(&iname->name[1], iqn) == 0)) {
				/* NG */
				SPDK_DEBUGLOG(SPDK_TRACE_ISCSI,
					      "access denied from %s (%s) to %s (%s:%s,%d)\n",
@@ -207,14 +209,14 @@ spdk_iscsi_tgt_node_access(struct spdk_iscsi_conn *conn,
				return false;
			}
			/* allow initiators */
			if (strcasecmp(igp->initiators[j], "ALL") == 0
			    || strcasecmp(igp->initiators[j], iqn) == 0) {
			if (strcasecmp(iname->name, "ALL") == 0
			    || strcasecmp(iname->name, iqn) == 0) {
				/* OK iqn, check netmask */
				for (k = 0; k < igp->nnetmasks; k++) {
				TAILQ_FOREACH(imask, &igp->netmask_head, tailq) {
					SPDK_DEBUGLOG(SPDK_TRACE_ISCSI,
						      "netmask=%s, addr=%s\n",
						      igp->netmasks[k], addr);
					if (spdk_iscsi_tgt_node_allow_netmask(igp->netmasks[k], addr)) {
						      imask->mask, addr);
					if (spdk_iscsi_tgt_node_allow_netmask(imask->mask, addr)) {
						/* OK netmask */
						return true;
					}
@@ -235,7 +237,8 @@ static bool
spdk_iscsi_tgt_node_visible(struct spdk_iscsi_tgt_node *target, const char *iqn)
{
	struct spdk_iscsi_init_grp *igp;
	int i, j;
	struct spdk_iscsi_initiator_name *iname;
	int i;

	if (target == NULL || iqn == NULL)
		return false;
@@ -243,15 +246,15 @@ spdk_iscsi_tgt_node_visible(struct spdk_iscsi_tgt_node *target, const char *iqn)
	for (i = 0; i < target->maxmap; i++) {
		/* iqn is initiator group? */
		igp = target->map[i].ig;
		for (j = 0; j < igp->ninitiators; j++) {
			if (igp->initiators[j][0] == '!'
			    && (strcasecmp(&igp->initiators[j][1], "ALL") == 0
				|| strcasecmp(&igp->initiators[j][1], iqn) == 0)) {
		TAILQ_FOREACH(iname, &igp->initiator_head, tailq) {
			if ((iname->name[0] == '!')
			    && (strcasecmp(&iname->name[1], "ALL") == 0
				|| strcasecmp(&iname->name[1], iqn) == 0)) {
				/* NG */
				return false;
			}
			if (strcasecmp(igp->initiators[j], "ALL") == 0
			    || strcasecmp(igp->initiators[j], iqn) == 0) {
			if (strcasecmp(iname->name, "ALL") == 0
			    || strcasecmp(iname->name, iqn) == 0) {
				/* OK iqn, no check addr */
				return true;
			}
Loading