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

iscsi&iscsi/ut: Unify cpumask decode between iSCSI.conf and JSON-RPC



Currently cpumask cannot be specified for each portal when it is
created by JSON-RPC and portal group creation is not unified
between iSCSI.conf and JSON-RPC.

This patch does the following:
 - cpumask string is decoded in spdk_iscsi_portal_create() which
   is common between iSCSI.conf and JSON-RPC.
 - parsing configline of portal is difficult to understand and
   hence it is refactored.
 - UT code is added.

 JSON-RPC will be added by the next patch.

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


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 52bd4453
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -825,7 +825,6 @@ 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;
	uint64_t cpumask;
	size_t i = 0;
	int rc = -1;

@@ -836,11 +835,10 @@ spdk_rpc_add_portal_group(struct spdk_jsonrpc_request *request,
		goto out;
	}

	cpumask = spdk_app_get_core_mask();

	for (i = 0; i < req.portal_list.num_portals; i++) {
		portal_list[i] = spdk_iscsi_portal_create(req.portal_list.portals[i].host,
				 req.portal_list.portals[i].port, cpumask);
				 req.portal_list.portals[i].port, NULL);
		if (portal_list[i] == NULL) {
			SPDK_ERRLOG("portal_list allocation failed\n");
			goto out;
+97 −102
Original line number Diff line number Diff line
@@ -67,9 +67,11 @@ spdk_iscsi_portal_find_by_addr(const char *host, const char *port)

/* 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)
spdk_iscsi_portal_create(const char *host, const char *port, const char *cpumask)
{
	struct spdk_iscsi_portal *p = NULL;
	uint64_t core_mask;
	int rc;

	assert(host != NULL);
	assert(port != NULL);
@@ -80,9 +82,9 @@ spdk_iscsi_portal_create(const char *host, const char *port, uint64_t cpumask)
		return NULL;
	}

	p = malloc(sizeof(*p));
	p = calloc(1, sizeof(*p));
	if (!p) {
		SPDK_ERRLOG("malloc() failed for portal\n");
		SPDK_ERRLOG("calloc() failed for portal\n");
		return NULL;
	}

@@ -100,9 +102,34 @@ spdk_iscsi_portal_create(const char *host, const char *port, uint64_t cpumask)
	} else {
		p->host = strdup(host);
	}
	if (!p->host) {
		SPDK_ERRLOG("strdup() failed for host\n");
		goto error_out;
	}

	p->port = strdup(port);
	p->cpumask = cpumask;
	if (!p->port) {
		SPDK_ERRLOG("strdup() failed for host\n");
		goto error_out;
	}

	core_mask = spdk_app_get_core_mask();

	if (cpumask != NULL) {
		rc = spdk_app_parse_core_mask(cpumask, &p->cpumask);
		if (rc < 0) {
			SPDK_ERRLOG("cpumask (%s) is invalid\n", cpumask);
			goto error_out;
		}
		if (p->cpumask == 0) {
			SPDK_ERRLOG("cpumask (%s) does not contain core mask (0x%" PRIx64 ")\n",
				    cpumask, core_mask);
			goto error_out;
		}
	} else {
		p->cpumask = core_mask;
	}

	p->sock = -1;
	p->group = NULL; /* set at a later time by caller */
	p->acceptor_poller = NULL;
@@ -110,6 +137,13 @@ spdk_iscsi_portal_create(const char *host, const char *port, uint64_t cpumask)
	TAILQ_INSERT_TAIL(&g_spdk_iscsi.portal_head, p, g_tailq);

	return p;

error_out:
	free(p->port);
	free(p->host);
	free(p);

	return NULL;
}

void
@@ -166,10 +200,8 @@ spdk_iscsi_portal_create_from_configline(const char *portalstring,
		struct spdk_iscsi_portal **ip,
		int dry_run)
{
	char *host = NULL, *port = NULL;
	const char *cpumask_str;
	uint64_t cpumask = 0;
	int n, len, rc = -1;
	char *host = NULL, *port = NULL, *cpumask = NULL;
	int len, rc = -1;
	const char *p, *q;

	if (portalstring == NULL) {
@@ -177,6 +209,7 @@ spdk_iscsi_portal_create_from_configline(const char *portalstring,
		goto error_out;
	}

	/* IP address */
	if (portalstring[0] == '[') {
		/* IPv6 */
		p = strchr(portalstring + 1, ']');
@@ -185,62 +218,26 @@ spdk_iscsi_portal_create_from_configline(const char *portalstring,
			goto error_out;
		}
		p++;
		n = p - portalstring;
		if (!dry_run) {
			host = malloc(n + 1);
			if (!host) {
				SPDK_ERRLOG("malloc() failed for host\n");
				goto error_out;
			}
			memcpy(host, portalstring, n);
			host[n] = '\0';
		}
		if (p[0] == '\0') {
			if (!dry_run) {
				port = malloc(PORTNUMSTRLEN);
				if (!port) {
					SPDK_ERRLOG("malloc() failed for port\n");
					goto error_out;
				}
				snprintf(port, PORTNUMSTRLEN, "%d", DEFAULT_PORT);
			}
		} else {
			if (p[0] != ':') {
				SPDK_ERRLOG("portal error\n");
				goto error_out;
			}
			if (!dry_run) {
				q = strchr(portalstring, '@');
				if (q == NULL) {
					q = portalstring + strlen(portalstring);
				}
				len = q - p - 1;

				port = malloc(len + 1);
				if (!port) {
					SPDK_ERRLOG("malloc() failed for port\n");
					goto error_out;
				}
				memset(port, 0, len + 1);
				memcpy(port, p + 1, len);
			}
		}
	} else {
		/* IPv4 */
		p = strchr(portalstring, ':');
		if (p == NULL) {
			p = portalstring + strlen(portalstring);
		}
		n = p - portalstring;
	}

	if (!dry_run) {
			host = malloc(n + 1);
			if (!host) {
		len = p - portalstring;
		host = malloc(len + 1);
		if (host == NULL) {
			SPDK_ERRLOG("malloc() failed for host\n");
			goto error_out;
		}
			memcpy(host, portalstring, n);
			host[n] = '\0';
		strncpy(host, portalstring, len);
		host[len] = '\0';
	}

	/* Port number (IPv4 and IPv6 are the same) */
	if (p[0] == '\0') {
		if (!dry_run) {
			port = malloc(PORTNUMSTRLEN);
@@ -255,44 +252,45 @@ spdk_iscsi_portal_create_from_configline(const char *portalstring,
			SPDK_ERRLOG("portal error\n");
			goto error_out;
		}
			if (!dry_run) {
		q = strchr(portalstring, '@');
		if (q == NULL) {
			q = portalstring + strlen(portalstring);
		}

		if (q == p) {
			SPDK_ERRLOG("no port specified\n");
			goto error_out;
		}

		if (!dry_run) {
			len = q - p - 1;
			port = malloc(len + 1);
				if (!port) {
			if (port == NULL) {
				SPDK_ERRLOG("malloc() failed for port\n");
				goto error_out;
			}
				memset(port, 0, len + 1);
				memcpy(port, p + 1, len);
			}

			strncpy(port, p + 1, len);
			port[len] = '\0';
		}
	}

	/* Cpumask (IPv4 and IPv6 are the same) */
	p = strchr(portalstring, '@');
	if (p != NULL) {
		cpumask_str = p + 1;
		if (spdk_app_parse_core_mask(cpumask_str, &cpumask)) {
			SPDK_ERRLOG("invalid portal cpumask %s\n", cpumask_str);
		q = portalstring + strlen(portalstring);
		if (q == p) {
			SPDK_ERRLOG("no cpumask specified\n");
			goto error_out;
		}
		if (cpumask == 0) {
			SPDK_ERRLOG("no cpu is selected among reactor mask(=%jx)\n",
				    spdk_app_get_core_mask());
		if (!dry_run) {
			len = q - p - 1;
			cpumask = malloc(len + 1);
			if (cpumask == NULL) {
				SPDK_ERRLOG("malloc() failed for cpumask\n");
				goto error_out;
			}
	} else {
		cpumask = spdk_app_get_core_mask();
			strncpy(cpumask, p + 1, len);
			cpumask[len] = '\0';
		}
	}

	if (!dry_run) {
@@ -304,12 +302,9 @@ spdk_iscsi_portal_create_from_configline(const char *portalstring,

	rc = 0;
error_out:
	if (host) {
	free(host);
	}
	if (port) {
	free(port);
	}
	free(cpumask);

	return rc;
}
+1 −1
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ struct spdk_iscsi_portal_grp {
/* SPDK iSCSI Portal Group management API */

struct spdk_iscsi_portal *spdk_iscsi_portal_create(const char *host, const char *port,
		uint64_t cpumask);
		const char *cpumask);
void spdk_iscsi_portal_destroy(struct spdk_iscsi_portal *p);

int spdk_iscsi_portal_grp_create_from_portal_list(int tag,
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk

DIRS-y = conn.c init_grp.c iscsi.c param.c tgt_node.c
DIRS-y = conn.c init_grp.c iscsi.c param.c portal_grp.c tgt_node.c

.PHONY: all clean $(DIRS-y)

+47 −0
Original line number Diff line number Diff line
#include "iscsi/task.h"
#include "iscsi/iscsi.h"
#include "iscsi/conn.h"
#include "iscsi/acceptor.h"

#include "spdk/env.h"
#include "spdk/event.h"
#include "spdk/net.h"

#include "spdk_internal/log.h"

@@ -100,6 +102,51 @@ spdk_scsi_dev_get_name(const struct spdk_scsi_dev *dev)
	return NULL;
}

void
spdk_iscsi_acceptor_start(struct spdk_iscsi_portal *p)
{
}

void
spdk_iscsi_acceptor_stop(struct spdk_iscsi_portal *p)
{
}

int
spdk_sock_listen(const char *ip, int port)
{
	return 0;
}

int
spdk_sock_close(int sock)
{
	return 0;
}

uint64_t
spdk_app_get_core_mask(void)
{
	return 0xFFFFFFFFFFFFFFFF;
}

int
spdk_app_parse_core_mask(const char *mask, uint64_t *cpumask)
{
	char *end;

	if (mask == NULL || cpumask == NULL) {
		return -1;
	}

	*cpumask = strtoull(mask, &end, 16);
	if (*end != '\0' || errno) {
		return -1;
	}

	return 0;
}

uint32_t
spdk_env_get_current_core(void)
{
Loading