Commit 2c8309e0 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Tomasz Zawadzki
Browse files

lib/iscsi: Update redirect portal of public portal group



iscsi_tgt_node_redirect() updates redirect portal of the initial
portal iin a primary portal group for the target node.

Check if the specified portal group is a public portal group and is
mapped to the target node first.

Then if the passed IP address-port pair is NULL, clear the current
redirect setting. Public portal group and private portal group are
clearly separated and redirect portal must be chosen from a private
portal group. Hence this clear method is intuitive and simple.

If the passed IP address-port pair is not NULL, check if they are
valid, and are not in the specified portal group. Then update a
redirect portal of the portal group map.

Finally, send asynchronous logout request to all corresponding
initiators.

Besides, change allocating pg_map from malloc to calloc to initialize
redirect portal.

Signed-off-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I79d826663f4c3d5a117add286f133adeb1ce07f5
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3222


Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 651f6d6a
Loading
Loading
Loading
Loading
+58 −1
Original line number Diff line number Diff line
@@ -553,7 +553,7 @@ iscsi_tgt_node_add_pg_map(struct spdk_iscsi_tgt_node *target,
		return NULL;
	}

	pg_map = malloc(sizeof(*pg_map));
	pg_map = calloc(1, sizeof(*pg_map));
	if (pg_map == NULL) {
		return NULL;
	}
@@ -857,6 +857,63 @@ invalid:
	return -1;
}

int
iscsi_tgt_node_redirect(struct spdk_iscsi_tgt_node *target, int pg_tag,
			const char *host, const char *port)
{
	struct spdk_iscsi_portal_grp *pg;
	struct spdk_iscsi_pg_map *pg_map;
	struct sockaddr_storage sa;

	if (target == NULL) {
		return -EINVAL;
	}

	pg = iscsi_portal_grp_find_by_tag(pg_tag);
	if (pg == NULL) {
		SPDK_ERRLOG("Portal group %d is not found.\n", pg_tag);
		return -EINVAL;
	}

	if (pg->is_private) {
		SPDK_ERRLOG("Portal group %d is not public portal group.\n", pg_tag);
		return -EINVAL;
	}

	pg_map = iscsi_tgt_node_find_pg_map(target, pg);
	if (pg_map == NULL) {
		SPDK_ERRLOG("Portal group %d is not mapped.\n", pg_tag);
		return -EINVAL;
	}

	if (host == NULL && port == NULL) {
		/* Clear redirect setting. */
		memset(pg_map->redirect_host, 0, MAX_PORTAL_ADDR + 1);
		memset(pg_map->redirect_port, 0, MAX_PORTAL_PORT + 1);
	} else {
		if (iscsi_parse_redirect_addr(&sa, host, port) != 0) {
			SPDK_ERRLOG("IP address-port pair is not valid.\n");
			return -EINVAL;
		}

		if (iscsi_portal_grp_find_portal_by_addr(pg, port, host) != NULL) {
			SPDK_ERRLOG("IP address-port pair must be chosen from a "
				    "different private portal group\n");
			return -EINVAL;
		}

		snprintf(pg_map->redirect_host, MAX_PORTAL_ADDR + 1, "%s", host);
		snprintf(pg_map->redirect_port, MAX_PORTAL_PORT + 1, "%s", port);
	}

	/* Terminate connections to this public portal group by asynchronous
	 * logout message.
	 */
	iscsi_conns_request_logout(target, pg_tag);

	return 0;
}

static int
check_iscsi_name(const char *name)
{
+4 −0
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ struct spdk_iscsi_pg_map {
	struct spdk_iscsi_portal_grp *pg;
	int num_ig_maps;
	TAILQ_HEAD(, spdk_iscsi_ig_map) ig_map_head;
	char redirect_host[MAX_PORTAL_ADDR + 1];
	char redirect_port[MAX_PORTAL_PORT + 1];
	TAILQ_ENTRY(spdk_iscsi_pg_map) tailq ;
};

@@ -126,6 +128,8 @@ int iscsi_target_node_add_pg_ig_maps(struct spdk_iscsi_tgt_node *target,
int iscsi_target_node_remove_pg_ig_maps(struct spdk_iscsi_tgt_node *target,
					int *pg_tag_list, int *ig_tag_list,
					uint16_t num_maps);
int iscsi_tgt_node_redirect(struct spdk_iscsi_tgt_node *target, int pg_tag,
			    const char *host, const char *port);

bool iscsi_tgt_node_access(struct spdk_iscsi_conn *conn,
			   struct spdk_iscsi_tgt_node *target, const char *iqn,