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

iscsi&rpc: Add new initiator information to an existing initiator group



Adding new initiator to an existing initiator group to allow login
will be usual. This patch support the following JSON-RPC commands:
- add_initiators_to_initiator_group
- delete_initiators_from_initiator_group

Both initiator's name and netmask are optional but already added
name or netmask cannot be added.

Test code is added too.

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


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent c0021d08
Loading
Loading
Loading
Loading
+134 −0
Original line number Diff line number Diff line
@@ -167,6 +167,31 @@ spdk_iscsi_init_grp_delete_all_initiators(struct spdk_iscsi_init_grp *ig)
	}
}

static int
spdk_iscsi_init_grp_delete_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_delete_initiator(ig, inames[i]);
		if (rc < 0) {
			goto cleanup;
		}
	}
	return 0;

cleanup:
	for (; i > 0; --i) {
		rc = spdk_iscsi_init_grp_add_initiator(ig, inames[i - 1]);
		if (rc != 0) {
			spdk_iscsi_init_grp_delete_all_initiators(ig);
			break;
		}
	}
	return -1;
}

static struct spdk_iscsi_initiator_netmask *
spdk_iscsi_init_grp_find_netmask(struct spdk_iscsi_init_grp *ig, const char *mask)
{
@@ -275,6 +300,30 @@ spdk_iscsi_init_grp_delete_all_netmasks(struct spdk_iscsi_init_grp *ig)
	}
}

static int
spdk_iscsi_init_grp_delete_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_delete_netmask(ig, imasks[i]);
		if (rc != 0) {
			goto cleanup;
		}
	}
	return 0;

cleanup:
	for (; i > 0; --i) {
		rc = spdk_iscsi_init_grp_add_netmask(ig, imasks[i - 1]);
		if (rc != 0) {
			spdk_iscsi_init_grp_delete_all_netmasks(ig);
			break;
		}
	}
	return -1;
}

/* Read spdk iscsi target's config file and create initiator group */
static int
@@ -461,6 +510,91 @@ cleanup:
	return rc;
}

int
spdk_iscsi_init_grp_add_initiators_from_initiator_list(int tag,
		int num_initiator_names,
		char **initiator_names,
		int num_initiator_masks,
		char **initiator_masks)
{
	int rc = -1;
	struct spdk_iscsi_init_grp *ig;

	SPDK_DEBUGLOG(SPDK_LOG_ISCSI,
		      "add initiator to initiator group: tag=%d, #initiators=%d, #masks=%d\n",
		      tag, num_initiator_names, num_initiator_masks);

	pthread_mutex_lock(&g_spdk_iscsi.mutex);
	ig = spdk_iscsi_init_grp_find_by_tag(tag);
	if (!ig) {
		pthread_mutex_unlock(&g_spdk_iscsi.mutex);
		SPDK_ERRLOG("initiator group (%d) is not found\n", tag);
		return rc;
	}

	rc = spdk_iscsi_init_grp_add_initiators(ig, num_initiator_names,
						initiator_names);
	if (rc < 0) {
		SPDK_ERRLOG("add initiator name error\n");
		goto error;
	}

	rc = spdk_iscsi_init_grp_add_netmasks(ig, num_initiator_masks,
					      initiator_masks);
	if (rc < 0) {
		SPDK_ERRLOG("add initiator netmask error\n");
		spdk_iscsi_init_grp_delete_initiators(ig, num_initiator_names,
						      initiator_names);
	}

error:
	pthread_mutex_unlock(&g_spdk_iscsi.mutex);
	return rc;
}

int
spdk_iscsi_init_grp_delete_initiators_from_initiator_list(int tag,
		int num_initiator_names,
		char **initiator_names,
		int num_initiator_masks,
		char **initiator_masks)
{
	int rc = -1;
	struct spdk_iscsi_init_grp *ig;

	SPDK_DEBUGLOG(SPDK_LOG_ISCSI,
		      "delete initiator from initiator group: tag=%d, #initiators=%d, #masks=%d\n",
		      tag, num_initiator_names, num_initiator_masks);

	pthread_mutex_lock(&g_spdk_iscsi.mutex);
	ig = spdk_iscsi_init_grp_find_by_tag(tag);
	if (!ig) {
		pthread_mutex_unlock(&g_spdk_iscsi.mutex);
		SPDK_ERRLOG("initiator group (%d) is not found\n", tag);
		return rc;
	}

	rc = spdk_iscsi_init_grp_delete_initiators(ig, num_initiator_names,
			initiator_names);
	if (rc < 0) {
		SPDK_ERRLOG("delete initiator name error\n");
		goto error;
	}

	rc = spdk_iscsi_init_grp_delete_netmasks(ig, num_initiator_masks,
			initiator_masks);
	if (rc < 0) {
		SPDK_ERRLOG("delete initiator netmask error\n");
		spdk_iscsi_init_grp_add_initiators(ig, num_initiator_names,
						   initiator_names);
		goto error;
	}

error:
	pthread_mutex_unlock(&g_spdk_iscsi.mutex);
	return rc;
}

void
spdk_iscsi_init_grp_destroy(struct spdk_iscsi_init_grp *ig)
{
+6 −0
Original line number Diff line number Diff line
@@ -61,6 +61,12 @@ struct spdk_iscsi_init_grp {
int spdk_iscsi_init_grp_create_from_initiator_list(int tag,
		int num_initiator_names, char **initiator_names,
		int num_initiator_masks, char **initiator_masks);
int spdk_iscsi_init_grp_add_initiators_from_initiator_list(int tag,
		int num_initiator_names, char **initiator_names,
		int num_initiator_masks, char **initiator_masks);
int spdk_iscsi_init_grp_delete_initiators_from_initiator_list(int tag,
		int num_initiator_names, char **initiator_names,
		int num_initiator_masks, char **initiator_masks);
int spdk_iscsi_init_grp_register(struct spdk_iscsi_init_grp *ig);
struct spdk_iscsi_init_grp *spdk_iscsi_init_grp_unregister(int tag);
struct spdk_iscsi_init_grp *spdk_iscsi_init_grp_find_by_tag(int tag);
+85 −0
Original line number Diff line number Diff line
@@ -206,6 +206,91 @@ invalid:
}
SPDK_RPC_REGISTER("add_initiator_group", spdk_rpc_add_initiator_group)

static const struct spdk_json_object_decoder rpc_add_or_delete_initiators_decoders[] = {
	{"tag", offsetof(struct rpc_initiator_group, tag), spdk_json_decode_int32},
	{"initiators", offsetof(struct rpc_initiator_group, initiator_list), decode_rpc_initiator_list, true},
	{"netmasks", offsetof(struct rpc_initiator_group, netmask_list), decode_rpc_netmask_list, true},
};

static void
spdk_rpc_add_initiators_to_initiator_group(struct spdk_jsonrpc_request *request,
		const struct spdk_json_val *params)
{
	struct rpc_initiator_group req = {};
	struct spdk_json_write_ctx *w;

	if (spdk_json_decode_object(params, rpc_add_or_delete_initiators_decoders,
				    SPDK_COUNTOF(rpc_add_or_delete_initiators_decoders), &req)) {
		SPDK_ERRLOG("spdk_json_decode_object failed\n");
		goto invalid;
	}

	if (spdk_iscsi_init_grp_add_initiators_from_initiator_list(req.tag,
			req.initiator_list.num_initiators,
			req.initiator_list.initiators,
			req.netmask_list.num_netmasks,
			req.netmask_list.netmasks)) {
		SPDK_ERRLOG("add_initiators_from_initiator_list failed\n");
		goto invalid;
	}

	free_rpc_initiator_group(&req);

	w = spdk_jsonrpc_begin_result(request);
	if (w == NULL) {
		return;
	}

	spdk_json_write_bool(w, true);
	spdk_jsonrpc_end_result(request, w);
	return;

invalid:
	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
	free_rpc_initiator_group(&req);
}
SPDK_RPC_REGISTER("add_initiators_to_initiator_group", spdk_rpc_add_initiators_to_initiator_group)

static void
spdk_rpc_delete_initiators_from_initiator_group(struct spdk_jsonrpc_request *request,
		const struct spdk_json_val *params)
{
	struct rpc_initiator_group req = {};
	struct spdk_json_write_ctx *w;

	if (spdk_json_decode_object(params, rpc_add_or_delete_initiators_decoders,
				    SPDK_COUNTOF(rpc_add_or_delete_initiators_decoders), &req)) {
		SPDK_ERRLOG("spdk_json_decode_object failed\n");
		goto invalid;
	}

	if (spdk_iscsi_init_grp_delete_initiators_from_initiator_list(req.tag,
			req.initiator_list.num_initiators,
			req.initiator_list.initiators,
			req.netmask_list.num_netmasks,
			req.netmask_list.netmasks)) {
		SPDK_ERRLOG("delete_initiators_from_initiator_list failed\n");
		goto invalid;
	}

	free_rpc_initiator_group(&req);

	w = spdk_jsonrpc_begin_result(request);
	if (w == NULL) {
		return;
	}

	spdk_json_write_bool(w, true);
	spdk_jsonrpc_end_result(request, w);
	return;

invalid:
	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
	free_rpc_initiator_group(&req);
}
SPDK_RPC_REGISTER("delete_initiators_from_initiator_group",
		  spdk_rpc_delete_initiators_from_initiator_group)

struct rpc_delete_initiator_group {
	int32_t tag;
};
+20 −0
Original line number Diff line number Diff line
@@ -192,6 +192,26 @@ if __name__ == "__main__":
    Example: '255.255.0.0 255.248.0.0' etc""")
    p.set_defaults(func=rpc.iscsi.add_initiator_group)

    p = subparsers.add_parser('add_initiators_to_initiator_group',
                              help='Add initiators to an existing initiator group')
    p.add_argument(
        'tag', help='Initiator group tag (unique, integer > 0)', type=int)
    p.add_argument('-n', dest='initiator_list', help="""Whitespace-separated list of initiator hostnames or IP addresses,
    enclosed in quotes.  This parameter can be omitted.  Example: 'ANY' or '127.0.0.1 192.168.200.100'""", required=False)
    p.add_argument('-m', dest='netmask_list', help="""Whitespace-separated list of initiator netmasks enclosed in quotes.
    This parameter can be omitted.  Example: '255.255.0.0 255.248.0.0' etc""", required=False)
    p.set_defaults(func=rpc.iscsi.add_initiators_to_initiator_group)

    p = subparsers.add_parser('delete_initiators_from_initiator_group',
                              help='Delete initiators from an existing initiator group')
    p.add_argument(
        'tag', help='Initiator group tag (unique, integer > 0)', type=int)
    p.add_argument('-n', dest='initiator_list', help="""Whitespace-separated list of initiator hostnames or IP addresses,
    enclosed in quotes.  This parameter can be omitted.  Example: 'ANY' or '127.0.0.1 192.168.200.100'""", required=False)
    p.add_argument('-m', dest='netmask_list', help="""Whitespace-separated list of initiator netmasks enclosed in quotes.
    This parameter can be omitted.  Example: '255.255.0.0 255.248.0.0' etc""", required=False)
    p.set_defaults(func=rpc.iscsi.delete_initiators_from_initiator_group)

    p = subparsers.add_parser('delete_target_node',
                              help='Delete a target node')
    p.add_argument('target_node_name',
+28 −0
Original line number Diff line number Diff line
@@ -120,6 +120,34 @@ def add_initiator_group(args):
    args.client.call('add_initiator_group', params)


def add_initiators_to_initiator_group(args):
    initiators = []
    netmasks = []
    if args.initiator_list:
        for i in args.initiator_list.strip().split(' '):
            initiators.append(i)
    if args.netmask_list:
        for n in args.netmask_list.strip().split(' '):
            netmasks.append(n)

    params = {'tag': args.tag, 'initiators': initiators, 'netmasks': netmasks}
    args.client.call('add_initiators_to_initiator_group', params)


def delete_initiators_from_initiator_group(args):
    initiators = []
    netmasks = []
    if args.initiator_list:
        for i in args.initiator_list.strip().split(' '):
            initiators.append(i)
    if args.netmask_list:
        for n in args.netmask_list.strip().split(' '):
            netmasks.append(n)

    params = {'tag': args.tag, 'initiators': initiators, 'netmasks': netmasks}
    args.client.call('delete_initiators_from_initiator_group', params)


def delete_target_node(args):
    params = {'name': args.target_node_name}
    args.client.call('delete_target_node', params)
Loading