xref: /spdk/lib/iscsi/init_grp.c (revision a6dbe3721eb3b5990707fc3e378c95e505dd8ab5)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2d29384bfSBen Walker  *   Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
3*a6dbe372Spaul luse  *   Copyright (C) 2016 Intel Corporation.
4d29384bfSBen Walker  *   All rights reserved.
5d29384bfSBen Walker  */
6d29384bfSBen Walker 
7b961d9ccSBen Walker #include "spdk/stdinc.h"
8d29384bfSBen Walker 
981673d0cSShuhei Matsumoto #include "spdk/string.h"
10d27b24c9SDaniel Verkamp 
114e8e97c8STomasz Zawadzki #include "spdk/log.h"
12d27b24c9SDaniel Verkamp 
13d29384bfSBen Walker #include "iscsi/iscsi.h"
14d29384bfSBen Walker #include "iscsi/init_grp.h"
15d29384bfSBen Walker 
16f678097dSShuhei Matsumoto static struct spdk_iscsi_init_grp *
iscsi_init_grp_create(int tag)17893e02a5SShuhei Matsumoto iscsi_init_grp_create(int tag)
18f678097dSShuhei Matsumoto {
19f678097dSShuhei Matsumoto 	struct spdk_iscsi_init_grp *ig;
20f678097dSShuhei Matsumoto 
21f678097dSShuhei Matsumoto 	ig = calloc(1, sizeof(*ig));
22f678097dSShuhei Matsumoto 	if (ig == NULL) {
23026dd8c6SDaniel Verkamp 		SPDK_ERRLOG("calloc() failed for initiator group\n");
24f678097dSShuhei Matsumoto 		return NULL;
25f678097dSShuhei Matsumoto 	}
26f678097dSShuhei Matsumoto 
27f678097dSShuhei Matsumoto 	ig->tag = tag;
28b8705bf4SShuhei Matsumoto 	TAILQ_INIT(&ig->initiator_head);
29b8705bf4SShuhei Matsumoto 	TAILQ_INIT(&ig->netmask_head);
30f678097dSShuhei Matsumoto 	return ig;
31f678097dSShuhei Matsumoto }
32d29384bfSBen Walker 
33b8705bf4SShuhei Matsumoto static struct spdk_iscsi_initiator_name *
iscsi_init_grp_find_initiator(struct spdk_iscsi_init_grp * ig,char * name)34893e02a5SShuhei Matsumoto iscsi_init_grp_find_initiator(struct spdk_iscsi_init_grp *ig, char *name)
35b8705bf4SShuhei Matsumoto {
36b8705bf4SShuhei Matsumoto 	struct spdk_iscsi_initiator_name *iname;
37b8705bf4SShuhei Matsumoto 
38b8705bf4SShuhei Matsumoto 	TAILQ_FOREACH(iname, &ig->initiator_head, tailq) {
39b8705bf4SShuhei Matsumoto 		if (!strcmp(iname->name, name)) {
40b8705bf4SShuhei Matsumoto 			return iname;
41b8705bf4SShuhei Matsumoto 		}
42b8705bf4SShuhei Matsumoto 	}
43b8705bf4SShuhei Matsumoto 	return NULL;
44b8705bf4SShuhei Matsumoto }
45b8705bf4SShuhei Matsumoto 
46b8705bf4SShuhei Matsumoto static int
iscsi_init_grp_add_initiator(struct spdk_iscsi_init_grp * ig,char * name)47893e02a5SShuhei Matsumoto iscsi_init_grp_add_initiator(struct spdk_iscsi_init_grp *ig, char *name)
48b8705bf4SShuhei Matsumoto {
49b8705bf4SShuhei Matsumoto 	struct spdk_iscsi_initiator_name *iname;
50eee268feSShuhei Matsumoto 	char *p;
514a3ad837SShuhei Matsumoto 	size_t len;
52b8705bf4SShuhei Matsumoto 
53b8705bf4SShuhei Matsumoto 	if (ig->ninitiators >= MAX_INITIATOR) {
54b8705bf4SShuhei Matsumoto 		SPDK_ERRLOG("> MAX_INITIATOR(=%d) is not allowed\n", MAX_INITIATOR);
55b8705bf4SShuhei Matsumoto 		return -EPERM;
56b8705bf4SShuhei Matsumoto 	}
57b8705bf4SShuhei Matsumoto 
584a3ad837SShuhei Matsumoto 	len = strlen(name);
594a3ad837SShuhei Matsumoto 	if (len > MAX_INITIATOR_NAME) {
60e8b65232SChangpeng Liu 		SPDK_ERRLOG("Initiator Name is larger than 223 bytes\n");
61e8b65232SChangpeng Liu 		return -EINVAL;
62e8b65232SChangpeng Liu 	}
63e8b65232SChangpeng Liu 
64893e02a5SShuhei Matsumoto 	iname = iscsi_init_grp_find_initiator(ig, name);
65b8705bf4SShuhei Matsumoto 	if (iname != NULL) {
66b8705bf4SShuhei Matsumoto 		return -EEXIST;
67b8705bf4SShuhei Matsumoto 	}
68b8705bf4SShuhei Matsumoto 
694a3ad837SShuhei Matsumoto 	iname = calloc(1, sizeof(*iname));
70b8705bf4SShuhei Matsumoto 	if (iname == NULL) {
71026dd8c6SDaniel Verkamp 		SPDK_ERRLOG("malloc() failed for initiator name str\n");
72b8705bf4SShuhei Matsumoto 		return -ENOMEM;
73b8705bf4SShuhei Matsumoto 	}
74b8705bf4SShuhei Matsumoto 
754a3ad837SShuhei Matsumoto 	memcpy(iname->name, name, len);
76b8705bf4SShuhei Matsumoto 
77eee268feSShuhei Matsumoto 	/* Replace "ALL" by "ANY" if set */
78eee268feSShuhei Matsumoto 	p = strstr(iname->name, "ALL");
79eee268feSShuhei Matsumoto 	if (p != NULL) {
80eee268feSShuhei Matsumoto 		SPDK_WARNLOG("Please use \"%s\" instead of \"%s\"\n", "ANY", "ALL");
81eee268feSShuhei Matsumoto 		SPDK_WARNLOG("Converting \"%s\" to \"%s\" automatically\n", "ALL", "ANY");
82c0d6eb9dSBen Walker 		memcpy(p, "ANY", 3);
83eee268feSShuhei Matsumoto 	}
84eee268feSShuhei Matsumoto 
85b8705bf4SShuhei Matsumoto 	TAILQ_INSERT_TAIL(&ig->initiator_head, iname, tailq);
86b8705bf4SShuhei Matsumoto 	ig->ninitiators++;
87b8705bf4SShuhei Matsumoto 
882172c432STomasz Zawadzki 	SPDK_DEBUGLOG(iscsi, "InitiatorName %s\n", name);
89b8705bf4SShuhei Matsumoto 	return 0;
90b8705bf4SShuhei Matsumoto }
91b8705bf4SShuhei Matsumoto 
92b8705bf4SShuhei Matsumoto static int
iscsi_init_grp_delete_initiator(struct spdk_iscsi_init_grp * ig,char * name)93893e02a5SShuhei Matsumoto iscsi_init_grp_delete_initiator(struct spdk_iscsi_init_grp *ig, char *name)
94b8705bf4SShuhei Matsumoto {
95b8705bf4SShuhei Matsumoto 	struct spdk_iscsi_initiator_name *iname;
96b8705bf4SShuhei Matsumoto 
97893e02a5SShuhei Matsumoto 	iname = iscsi_init_grp_find_initiator(ig, name);
98b8705bf4SShuhei Matsumoto 	if (iname == NULL) {
99b8705bf4SShuhei Matsumoto 		return -ENOENT;
100b8705bf4SShuhei Matsumoto 	}
101b8705bf4SShuhei Matsumoto 
102b8705bf4SShuhei Matsumoto 	TAILQ_REMOVE(&ig->initiator_head, iname, tailq);
103b8705bf4SShuhei Matsumoto 	ig->ninitiators--;
104b8705bf4SShuhei Matsumoto 	free(iname);
105b8705bf4SShuhei Matsumoto 	return 0;
106b8705bf4SShuhei Matsumoto }
107b8705bf4SShuhei Matsumoto 
108e5c6b9c7SShuhei Matsumoto static int
iscsi_init_grp_add_initiators(struct spdk_iscsi_init_grp * ig,int num_inames,char ** inames)109893e02a5SShuhei Matsumoto iscsi_init_grp_add_initiators(struct spdk_iscsi_init_grp *ig, int num_inames,
110893e02a5SShuhei Matsumoto 			      char **inames)
111e5c6b9c7SShuhei Matsumoto {
112e5c6b9c7SShuhei Matsumoto 	int i;
113b8705bf4SShuhei Matsumoto 	int rc;
114e5c6b9c7SShuhei Matsumoto 
115b8705bf4SShuhei Matsumoto 	for (i = 0; i < num_inames; i++) {
116893e02a5SShuhei Matsumoto 		rc = iscsi_init_grp_add_initiator(ig, inames[i]);
117b8705bf4SShuhei Matsumoto 		if (rc < 0) {
118e5c6b9c7SShuhei Matsumoto 			goto cleanup;
119e5c6b9c7SShuhei Matsumoto 		}
120e5c6b9c7SShuhei Matsumoto 	}
121e5c6b9c7SShuhei Matsumoto 	return 0;
122e5c6b9c7SShuhei Matsumoto 
123e5c6b9c7SShuhei Matsumoto cleanup:
124e5c6b9c7SShuhei Matsumoto 	for (; i > 0; --i) {
125893e02a5SShuhei Matsumoto 		iscsi_init_grp_delete_initiator(ig, inames[i - 1]);
126e5c6b9c7SShuhei Matsumoto 	}
127b8705bf4SShuhei Matsumoto 	return rc;
128e5c6b9c7SShuhei Matsumoto }
129e5c6b9c7SShuhei Matsumoto 
130e5c6b9c7SShuhei Matsumoto static void
iscsi_init_grp_delete_all_initiators(struct spdk_iscsi_init_grp * ig)131893e02a5SShuhei Matsumoto iscsi_init_grp_delete_all_initiators(struct spdk_iscsi_init_grp *ig)
132e5c6b9c7SShuhei Matsumoto {
133b8705bf4SShuhei Matsumoto 	struct spdk_iscsi_initiator_name *iname, *tmp;
134e5c6b9c7SShuhei Matsumoto 
135b8705bf4SShuhei Matsumoto 	TAILQ_FOREACH_SAFE(iname, &ig->initiator_head, tailq, tmp) {
136b8705bf4SShuhei Matsumoto 		TAILQ_REMOVE(&ig->initiator_head, iname, tailq);
137b8705bf4SShuhei Matsumoto 		ig->ninitiators--;
138b8705bf4SShuhei Matsumoto 		free(iname);
139e5c6b9c7SShuhei Matsumoto 	}
140b8705bf4SShuhei Matsumoto }
141b8705bf4SShuhei Matsumoto 
1422982a74dSShuhei Matsumoto static int
iscsi_init_grp_delete_initiators(struct spdk_iscsi_init_grp * ig,int num_inames,char ** inames)143893e02a5SShuhei Matsumoto iscsi_init_grp_delete_initiators(struct spdk_iscsi_init_grp *ig, int num_inames, char **inames)
1442982a74dSShuhei Matsumoto {
1452982a74dSShuhei Matsumoto 	int i;
1462982a74dSShuhei Matsumoto 	int rc;
1472982a74dSShuhei Matsumoto 
1482982a74dSShuhei Matsumoto 	for (i = 0; i < num_inames; i++) {
149893e02a5SShuhei Matsumoto 		rc = iscsi_init_grp_delete_initiator(ig, inames[i]);
1502982a74dSShuhei Matsumoto 		if (rc < 0) {
1512982a74dSShuhei Matsumoto 			goto cleanup;
1522982a74dSShuhei Matsumoto 		}
1532982a74dSShuhei Matsumoto 	}
1542982a74dSShuhei Matsumoto 	return 0;
1552982a74dSShuhei Matsumoto 
1562982a74dSShuhei Matsumoto cleanup:
1572982a74dSShuhei Matsumoto 	for (; i > 0; --i) {
158893e02a5SShuhei Matsumoto 		rc = iscsi_init_grp_add_initiator(ig, inames[i - 1]);
1592982a74dSShuhei Matsumoto 		if (rc != 0) {
160893e02a5SShuhei Matsumoto 			iscsi_init_grp_delete_all_initiators(ig);
1612982a74dSShuhei Matsumoto 			break;
1622982a74dSShuhei Matsumoto 		}
1632982a74dSShuhei Matsumoto 	}
1642982a74dSShuhei Matsumoto 	return -1;
1652982a74dSShuhei Matsumoto }
1662982a74dSShuhei Matsumoto 
167b8705bf4SShuhei Matsumoto static struct spdk_iscsi_initiator_netmask *
iscsi_init_grp_find_netmask(struct spdk_iscsi_init_grp * ig,const char * mask)168893e02a5SShuhei Matsumoto iscsi_init_grp_find_netmask(struct spdk_iscsi_init_grp *ig, const char *mask)
169b8705bf4SShuhei Matsumoto {
170b8705bf4SShuhei Matsumoto 	struct spdk_iscsi_initiator_netmask *netmask;
171b8705bf4SShuhei Matsumoto 
172b8705bf4SShuhei Matsumoto 	TAILQ_FOREACH(netmask, &ig->netmask_head, tailq) {
173b8705bf4SShuhei Matsumoto 		if (!strcmp(netmask->mask, mask)) {
174b8705bf4SShuhei Matsumoto 			return netmask;
175b8705bf4SShuhei Matsumoto 		}
176b8705bf4SShuhei Matsumoto 	}
177b8705bf4SShuhei Matsumoto 	return NULL;
178b8705bf4SShuhei Matsumoto }
179b8705bf4SShuhei Matsumoto 
180b8705bf4SShuhei Matsumoto static int
iscsi_init_grp_add_netmask(struct spdk_iscsi_init_grp * ig,char * mask)181893e02a5SShuhei Matsumoto iscsi_init_grp_add_netmask(struct spdk_iscsi_init_grp *ig, char *mask)
182b8705bf4SShuhei Matsumoto {
183b8705bf4SShuhei Matsumoto 	struct spdk_iscsi_initiator_netmask *imask;
184eee268feSShuhei Matsumoto 	char *p;
185975e48aeSShuhei Matsumoto 	size_t len;
186b8705bf4SShuhei Matsumoto 
187b8705bf4SShuhei Matsumoto 	if (ig->nnetmasks >= MAX_NETMASK) {
188b8705bf4SShuhei Matsumoto 		SPDK_ERRLOG("> MAX_NETMASK(=%d) is not allowed\n", MAX_NETMASK);
189b8705bf4SShuhei Matsumoto 		return -EPERM;
190b8705bf4SShuhei Matsumoto 	}
191b8705bf4SShuhei Matsumoto 
192975e48aeSShuhei Matsumoto 	len = strlen(mask);
193975e48aeSShuhei Matsumoto 	if (len > MAX_INITIATOR_ADDR) {
194975e48aeSShuhei Matsumoto 		SPDK_ERRLOG("Initiator Name is larger than %d bytes\n", MAX_INITIATOR_ADDR);
195975e48aeSShuhei Matsumoto 		return -EINVAL;
196975e48aeSShuhei Matsumoto 	}
197975e48aeSShuhei Matsumoto 
198893e02a5SShuhei Matsumoto 	imask = iscsi_init_grp_find_netmask(ig, mask);
199b8705bf4SShuhei Matsumoto 	if (imask != NULL) {
200b8705bf4SShuhei Matsumoto 		return -EEXIST;
201b8705bf4SShuhei Matsumoto 	}
202b8705bf4SShuhei Matsumoto 
203975e48aeSShuhei Matsumoto 	imask = calloc(1, sizeof(*imask));
204b8705bf4SShuhei Matsumoto 	if (imask == NULL) {
205cc6920a4SJosh Soref 		SPDK_ERRLOG("malloc() failed for initiator mask str\n");
206b8705bf4SShuhei Matsumoto 		return -ENOMEM;
207b8705bf4SShuhei Matsumoto 	}
208b8705bf4SShuhei Matsumoto 
209975e48aeSShuhei Matsumoto 	memcpy(imask->mask, mask, len);
210b8705bf4SShuhei Matsumoto 
211eee268feSShuhei Matsumoto 	/* Replace "ALL" by "ANY" if set */
212eee268feSShuhei Matsumoto 	p = strstr(imask->mask, "ALL");
213eee268feSShuhei Matsumoto 	if (p != NULL) {
214eee268feSShuhei Matsumoto 		SPDK_WARNLOG("Please use \"%s\" instead of \"%s\"\n", "ANY", "ALL");
215eee268feSShuhei Matsumoto 		SPDK_WARNLOG("Converting \"%s\" to \"%s\" automatically\n", "ALL", "ANY");
216c0d6eb9dSBen Walker 		memcpy(p, "ANY", 3);
217eee268feSShuhei Matsumoto 	}
218eee268feSShuhei Matsumoto 
219b8705bf4SShuhei Matsumoto 	TAILQ_INSERT_TAIL(&ig->netmask_head, imask, tailq);
220b8705bf4SShuhei Matsumoto 	ig->nnetmasks++;
221b8705bf4SShuhei Matsumoto 
2222172c432STomasz Zawadzki 	SPDK_DEBUGLOG(iscsi, "Netmask %s\n", mask);
223b8705bf4SShuhei Matsumoto 	return 0;
224b8705bf4SShuhei Matsumoto }
225b8705bf4SShuhei Matsumoto 
226b8705bf4SShuhei Matsumoto static int
iscsi_init_grp_delete_netmask(struct spdk_iscsi_init_grp * ig,char * mask)227893e02a5SShuhei Matsumoto iscsi_init_grp_delete_netmask(struct spdk_iscsi_init_grp *ig, char *mask)
228b8705bf4SShuhei Matsumoto {
229b8705bf4SShuhei Matsumoto 	struct spdk_iscsi_initiator_netmask *imask;
230b8705bf4SShuhei Matsumoto 
231893e02a5SShuhei Matsumoto 	imask = iscsi_init_grp_find_netmask(ig, mask);
232b8705bf4SShuhei Matsumoto 	if (imask == NULL) {
233b8705bf4SShuhei Matsumoto 		return -ENOENT;
234b8705bf4SShuhei Matsumoto 	}
235b8705bf4SShuhei Matsumoto 
236b8705bf4SShuhei Matsumoto 	TAILQ_REMOVE(&ig->netmask_head, imask, tailq);
237b8705bf4SShuhei Matsumoto 	ig->nnetmasks--;
238b8705bf4SShuhei Matsumoto 	free(imask);
239b8705bf4SShuhei Matsumoto 	return 0;
240e5c6b9c7SShuhei Matsumoto }
241e5c6b9c7SShuhei Matsumoto 
242e5c6b9c7SShuhei Matsumoto static int
iscsi_init_grp_add_netmasks(struct spdk_iscsi_init_grp * ig,int num_imasks,char ** imasks)243893e02a5SShuhei Matsumoto iscsi_init_grp_add_netmasks(struct spdk_iscsi_init_grp *ig, int num_imasks, char **imasks)
244e5c6b9c7SShuhei Matsumoto {
245e5c6b9c7SShuhei Matsumoto 	int i;
246b8705bf4SShuhei Matsumoto 	int rc;
247e5c6b9c7SShuhei Matsumoto 
248b8705bf4SShuhei Matsumoto 	for (i = 0; i < num_imasks; i++) {
249893e02a5SShuhei Matsumoto 		rc = iscsi_init_grp_add_netmask(ig, imasks[i]);
250b8705bf4SShuhei Matsumoto 		if (rc != 0) {
251e5c6b9c7SShuhei Matsumoto 			goto cleanup;
252e5c6b9c7SShuhei Matsumoto 		}
253e5c6b9c7SShuhei Matsumoto 	}
254e5c6b9c7SShuhei Matsumoto 	return 0;
255e5c6b9c7SShuhei Matsumoto 
256e5c6b9c7SShuhei Matsumoto cleanup:
257e5c6b9c7SShuhei Matsumoto 	for (; i > 0; --i) {
258893e02a5SShuhei Matsumoto 		iscsi_init_grp_delete_netmask(ig, imasks[i - 1]);
259e5c6b9c7SShuhei Matsumoto 	}
260b8705bf4SShuhei Matsumoto 	return rc;
261e5c6b9c7SShuhei Matsumoto }
262e5c6b9c7SShuhei Matsumoto 
263e5c6b9c7SShuhei Matsumoto static void
iscsi_init_grp_delete_all_netmasks(struct spdk_iscsi_init_grp * ig)264893e02a5SShuhei Matsumoto iscsi_init_grp_delete_all_netmasks(struct spdk_iscsi_init_grp *ig)
265e5c6b9c7SShuhei Matsumoto {
266b8705bf4SShuhei Matsumoto 	struct spdk_iscsi_initiator_netmask *imask, *tmp;
267e5c6b9c7SShuhei Matsumoto 
268b8705bf4SShuhei Matsumoto 	TAILQ_FOREACH_SAFE(imask, &ig->netmask_head, tailq, tmp) {
269b8705bf4SShuhei Matsumoto 		TAILQ_REMOVE(&ig->netmask_head, imask, tailq);
270b8705bf4SShuhei Matsumoto 		ig->nnetmasks--;
271b8705bf4SShuhei Matsumoto 		free(imask);
272e5c6b9c7SShuhei Matsumoto 	}
273e5c6b9c7SShuhei Matsumoto }
274e5c6b9c7SShuhei Matsumoto 
2752982a74dSShuhei Matsumoto static int
iscsi_init_grp_delete_netmasks(struct spdk_iscsi_init_grp * ig,int num_imasks,char ** imasks)276893e02a5SShuhei Matsumoto iscsi_init_grp_delete_netmasks(struct spdk_iscsi_init_grp *ig, int num_imasks, char **imasks)
2772982a74dSShuhei Matsumoto {
2782982a74dSShuhei Matsumoto 	int i;
2792982a74dSShuhei Matsumoto 	int rc;
2802982a74dSShuhei Matsumoto 
2812982a74dSShuhei Matsumoto 	for (i = 0; i < num_imasks; i++) {
282893e02a5SShuhei Matsumoto 		rc = iscsi_init_grp_delete_netmask(ig, imasks[i]);
2832982a74dSShuhei Matsumoto 		if (rc != 0) {
2842982a74dSShuhei Matsumoto 			goto cleanup;
2852982a74dSShuhei Matsumoto 		}
2862982a74dSShuhei Matsumoto 	}
2872982a74dSShuhei Matsumoto 	return 0;
2882982a74dSShuhei Matsumoto 
2892982a74dSShuhei Matsumoto cleanup:
2902982a74dSShuhei Matsumoto 	for (; i > 0; --i) {
291893e02a5SShuhei Matsumoto 		rc = iscsi_init_grp_add_netmask(ig, imasks[i - 1]);
2922982a74dSShuhei Matsumoto 		if (rc != 0) {
293893e02a5SShuhei Matsumoto 			iscsi_init_grp_delete_all_netmasks(ig);
2942982a74dSShuhei Matsumoto 			break;
2952982a74dSShuhei Matsumoto 		}
2962982a74dSShuhei Matsumoto 	}
2972982a74dSShuhei Matsumoto 	return -1;
2982982a74dSShuhei Matsumoto }
299e5c6b9c7SShuhei Matsumoto 
30013cffa4aSShuhei Matsumoto int
iscsi_init_grp_register(struct spdk_iscsi_init_grp * ig)301df53885bSShuhei Matsumoto iscsi_init_grp_register(struct spdk_iscsi_init_grp *ig)
3024547ce65SZiye Yang {
30313cffa4aSShuhei Matsumoto 	struct spdk_iscsi_init_grp *tmp;
30413cffa4aSShuhei Matsumoto 	int rc = -1;
30513cffa4aSShuhei Matsumoto 
3064547ce65SZiye Yang 	assert(ig != NULL);
3074547ce65SZiye Yang 
308be1489b9SShuhei Matsumoto 	pthread_mutex_lock(&g_iscsi.mutex);
309df53885bSShuhei Matsumoto 	tmp = iscsi_init_grp_find_by_tag(ig->tag);
31013cffa4aSShuhei Matsumoto 	if (tmp == NULL) {
311be1489b9SShuhei Matsumoto 		TAILQ_INSERT_TAIL(&g_iscsi.ig_head, ig, tailq);
31213cffa4aSShuhei Matsumoto 		rc = 0;
31313cffa4aSShuhei Matsumoto 	}
314be1489b9SShuhei Matsumoto 	pthread_mutex_unlock(&g_iscsi.mutex);
31513cffa4aSShuhei Matsumoto 
31613cffa4aSShuhei Matsumoto 	return rc;
3174547ce65SZiye Yang }
3184547ce65SZiye Yang 
319d29384bfSBen Walker /*
320d29384bfSBen Walker  * Create initiator group from list of initiator ip/hostnames and netmasks
321d29384bfSBen Walker  * The initiator hostname/netmask lists are allocated by the caller on the
322d29384bfSBen Walker  * heap.  Freed later by common initiator_group_destroy() code
323d29384bfSBen Walker  */
324d29384bfSBen Walker int
iscsi_init_grp_create_from_initiator_list(int tag,int num_initiator_names,char ** initiator_names,int num_initiator_masks,char ** initiator_masks)325df53885bSShuhei Matsumoto iscsi_init_grp_create_from_initiator_list(int tag,
326d29384bfSBen Walker 		int num_initiator_names,
327d29384bfSBen Walker 		char **initiator_names,
328d29384bfSBen Walker 		int num_initiator_masks,
329d29384bfSBen Walker 		char **initiator_masks)
330d29384bfSBen Walker {
331e5c6b9c7SShuhei Matsumoto 	int rc = -1;
332d29384bfSBen Walker 	struct spdk_iscsi_init_grp *ig = NULL;
333d29384bfSBen Walker 
3342172c432STomasz Zawadzki 	SPDK_DEBUGLOG(iscsi,
335d29384bfSBen Walker 		      "add initiator group (from initiator list) tag=%d, #initiators=%d, #masks=%d\n",
336d29384bfSBen Walker 		      tag, num_initiator_names, num_initiator_masks);
337d29384bfSBen Walker 
338893e02a5SShuhei Matsumoto 	ig = iscsi_init_grp_create(tag);
339d29384bfSBen Walker 	if (!ig) {
340f678097dSShuhei Matsumoto 		SPDK_ERRLOG("initiator group create error (%d)\n", tag);
341e5c6b9c7SShuhei Matsumoto 		return rc;
342e5c6b9c7SShuhei Matsumoto 	}
343e5c6b9c7SShuhei Matsumoto 
344893e02a5SShuhei Matsumoto 	rc = iscsi_init_grp_add_initiators(ig, num_initiator_names,
345e5c6b9c7SShuhei Matsumoto 					   initiator_names);
346e5c6b9c7SShuhei Matsumoto 	if (rc < 0) {
347e5c6b9c7SShuhei Matsumoto 		SPDK_ERRLOG("add initiator name error\n");
348d29384bfSBen Walker 		goto cleanup;
349d29384bfSBen Walker 	}
350d29384bfSBen Walker 
351893e02a5SShuhei Matsumoto 	rc = iscsi_init_grp_add_netmasks(ig, num_initiator_masks,
352e5c6b9c7SShuhei Matsumoto 					 initiator_masks);
353e5c6b9c7SShuhei Matsumoto 	if (rc < 0) {
354e5c6b9c7SShuhei Matsumoto 		SPDK_ERRLOG("add initiator netmask error\n");
355e5c6b9c7SShuhei Matsumoto 		goto cleanup;
356e5c6b9c7SShuhei Matsumoto 	}
357d29384bfSBen Walker 
358df53885bSShuhei Matsumoto 	rc = iscsi_init_grp_register(ig);
35913cffa4aSShuhei Matsumoto 	if (rc < 0) {
36013cffa4aSShuhei Matsumoto 		SPDK_ERRLOG("initiator group register error (%d)\n", tag);
36113cffa4aSShuhei Matsumoto 		goto cleanup;
36213cffa4aSShuhei Matsumoto 	}
363d29384bfSBen Walker 	return 0;
364d29384bfSBen Walker 
365d29384bfSBen Walker cleanup:
366df53885bSShuhei Matsumoto 	iscsi_init_grp_destroy(ig);
367d29384bfSBen Walker 	return rc;
368d29384bfSBen Walker }
369d29384bfSBen Walker 
3702982a74dSShuhei Matsumoto int
iscsi_init_grp_add_initiators_from_initiator_list(int tag,int num_initiator_names,char ** initiator_names,int num_initiator_masks,char ** initiator_masks)371df53885bSShuhei Matsumoto iscsi_init_grp_add_initiators_from_initiator_list(int tag,
3722982a74dSShuhei Matsumoto 		int num_initiator_names,
3732982a74dSShuhei Matsumoto 		char **initiator_names,
3742982a74dSShuhei Matsumoto 		int num_initiator_masks,
3752982a74dSShuhei Matsumoto 		char **initiator_masks)
3762982a74dSShuhei Matsumoto {
3772982a74dSShuhei Matsumoto 	int rc = -1;
3782982a74dSShuhei Matsumoto 	struct spdk_iscsi_init_grp *ig;
3792982a74dSShuhei Matsumoto 
3802172c432STomasz Zawadzki 	SPDK_DEBUGLOG(iscsi,
3812982a74dSShuhei Matsumoto 		      "add initiator to initiator group: tag=%d, #initiators=%d, #masks=%d\n",
3822982a74dSShuhei Matsumoto 		      tag, num_initiator_names, num_initiator_masks);
3832982a74dSShuhei Matsumoto 
384be1489b9SShuhei Matsumoto 	pthread_mutex_lock(&g_iscsi.mutex);
385df53885bSShuhei Matsumoto 	ig = iscsi_init_grp_find_by_tag(tag);
3862982a74dSShuhei Matsumoto 	if (!ig) {
387be1489b9SShuhei Matsumoto 		pthread_mutex_unlock(&g_iscsi.mutex);
3882982a74dSShuhei Matsumoto 		SPDK_ERRLOG("initiator group (%d) is not found\n", tag);
3892982a74dSShuhei Matsumoto 		return rc;
3902982a74dSShuhei Matsumoto 	}
3912982a74dSShuhei Matsumoto 
392893e02a5SShuhei Matsumoto 	rc = iscsi_init_grp_add_initiators(ig, num_initiator_names,
3932982a74dSShuhei Matsumoto 					   initiator_names);
3942982a74dSShuhei Matsumoto 	if (rc < 0) {
3952982a74dSShuhei Matsumoto 		SPDK_ERRLOG("add initiator name error\n");
3962982a74dSShuhei Matsumoto 		goto error;
3972982a74dSShuhei Matsumoto 	}
3982982a74dSShuhei Matsumoto 
399893e02a5SShuhei Matsumoto 	rc = iscsi_init_grp_add_netmasks(ig, num_initiator_masks,
4002982a74dSShuhei Matsumoto 					 initiator_masks);
4012982a74dSShuhei Matsumoto 	if (rc < 0) {
4022982a74dSShuhei Matsumoto 		SPDK_ERRLOG("add initiator netmask error\n");
403893e02a5SShuhei Matsumoto 		iscsi_init_grp_delete_initiators(ig, num_initiator_names,
4042982a74dSShuhei Matsumoto 						 initiator_names);
4052982a74dSShuhei Matsumoto 	}
4062982a74dSShuhei Matsumoto 
4072982a74dSShuhei Matsumoto error:
408be1489b9SShuhei Matsumoto 	pthread_mutex_unlock(&g_iscsi.mutex);
4092982a74dSShuhei Matsumoto 	return rc;
4102982a74dSShuhei Matsumoto }
4112982a74dSShuhei Matsumoto 
4122982a74dSShuhei Matsumoto int
iscsi_init_grp_delete_initiators_from_initiator_list(int tag,int num_initiator_names,char ** initiator_names,int num_initiator_masks,char ** initiator_masks)413df53885bSShuhei Matsumoto iscsi_init_grp_delete_initiators_from_initiator_list(int tag,
4142982a74dSShuhei Matsumoto 		int num_initiator_names,
4152982a74dSShuhei Matsumoto 		char **initiator_names,
4162982a74dSShuhei Matsumoto 		int num_initiator_masks,
4172982a74dSShuhei Matsumoto 		char **initiator_masks)
4182982a74dSShuhei Matsumoto {
4192982a74dSShuhei Matsumoto 	int rc = -1;
4202982a74dSShuhei Matsumoto 	struct spdk_iscsi_init_grp *ig;
4212982a74dSShuhei Matsumoto 
4222172c432STomasz Zawadzki 	SPDK_DEBUGLOG(iscsi,
4232982a74dSShuhei Matsumoto 		      "delete initiator from initiator group: tag=%d, #initiators=%d, #masks=%d\n",
4242982a74dSShuhei Matsumoto 		      tag, num_initiator_names, num_initiator_masks);
4252982a74dSShuhei Matsumoto 
426be1489b9SShuhei Matsumoto 	pthread_mutex_lock(&g_iscsi.mutex);
427df53885bSShuhei Matsumoto 	ig = iscsi_init_grp_find_by_tag(tag);
4282982a74dSShuhei Matsumoto 	if (!ig) {
429be1489b9SShuhei Matsumoto 		pthread_mutex_unlock(&g_iscsi.mutex);
4302982a74dSShuhei Matsumoto 		SPDK_ERRLOG("initiator group (%d) is not found\n", tag);
4312982a74dSShuhei Matsumoto 		return rc;
4322982a74dSShuhei Matsumoto 	}
4332982a74dSShuhei Matsumoto 
434893e02a5SShuhei Matsumoto 	rc = iscsi_init_grp_delete_initiators(ig, num_initiator_names,
4352982a74dSShuhei Matsumoto 					      initiator_names);
4362982a74dSShuhei Matsumoto 	if (rc < 0) {
4372982a74dSShuhei Matsumoto 		SPDK_ERRLOG("delete initiator name error\n");
4382982a74dSShuhei Matsumoto 		goto error;
4392982a74dSShuhei Matsumoto 	}
4402982a74dSShuhei Matsumoto 
441893e02a5SShuhei Matsumoto 	rc = iscsi_init_grp_delete_netmasks(ig, num_initiator_masks,
4422982a74dSShuhei Matsumoto 					    initiator_masks);
4432982a74dSShuhei Matsumoto 	if (rc < 0) {
4442982a74dSShuhei Matsumoto 		SPDK_ERRLOG("delete initiator netmask error\n");
445893e02a5SShuhei Matsumoto 		iscsi_init_grp_add_initiators(ig, num_initiator_names,
4462982a74dSShuhei Matsumoto 					      initiator_names);
4472982a74dSShuhei Matsumoto 		goto error;
4482982a74dSShuhei Matsumoto 	}
4492982a74dSShuhei Matsumoto 
4502982a74dSShuhei Matsumoto error:
451be1489b9SShuhei Matsumoto 	pthread_mutex_unlock(&g_iscsi.mutex);
4522982a74dSShuhei Matsumoto 	return rc;
4532982a74dSShuhei Matsumoto }
4542982a74dSShuhei Matsumoto 
45513cffa4aSShuhei Matsumoto void
iscsi_init_grp_destroy(struct spdk_iscsi_init_grp * ig)456df53885bSShuhei Matsumoto iscsi_init_grp_destroy(struct spdk_iscsi_init_grp *ig)
457d29384bfSBen Walker {
458d29384bfSBen Walker 	if (!ig) {
459d29384bfSBen Walker 		return;
460d29384bfSBen Walker 	}
461d29384bfSBen Walker 
462893e02a5SShuhei Matsumoto 	iscsi_init_grp_delete_all_initiators(ig);
463893e02a5SShuhei Matsumoto 	iscsi_init_grp_delete_all_netmasks(ig);
464d29384bfSBen Walker 	free(ig);
465d29384bfSBen Walker };
466d29384bfSBen Walker 
467d29384bfSBen Walker struct spdk_iscsi_init_grp *
iscsi_init_grp_find_by_tag(int tag)468df53885bSShuhei Matsumoto iscsi_init_grp_find_by_tag(int tag)
469d29384bfSBen Walker {
470d29384bfSBen Walker 	struct spdk_iscsi_init_grp *ig;
471d29384bfSBen Walker 
472be1489b9SShuhei Matsumoto 	TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
473d29384bfSBen Walker 		if (ig->tag == tag) {
474d29384bfSBen Walker 			return ig;
475d29384bfSBen Walker 		}
476d29384bfSBen Walker 	}
477d29384bfSBen Walker 
478d29384bfSBen Walker 	return NULL;
479d29384bfSBen Walker }
480d29384bfSBen Walker 
481d29384bfSBen Walker void
iscsi_init_grps_destroy(void)482df53885bSShuhei Matsumoto iscsi_init_grps_destroy(void)
483d29384bfSBen Walker {
484d29384bfSBen Walker 	struct spdk_iscsi_init_grp *ig, *tmp;
485d29384bfSBen Walker 
4862172c432STomasz Zawadzki 	SPDK_DEBUGLOG(iscsi, "iscsi_init_grp_array_destroy\n");
487be1489b9SShuhei Matsumoto 	pthread_mutex_lock(&g_iscsi.mutex);
488be1489b9SShuhei Matsumoto 	TAILQ_FOREACH_SAFE(ig, &g_iscsi.ig_head, tailq, tmp) {
489be1489b9SShuhei Matsumoto 		TAILQ_REMOVE(&g_iscsi.ig_head, ig, tailq);
490df53885bSShuhei Matsumoto 		iscsi_init_grp_destroy(ig);
491d29384bfSBen Walker 	}
492be1489b9SShuhei Matsumoto 	pthread_mutex_unlock(&g_iscsi.mutex);
493d29384bfSBen Walker }
494d29384bfSBen Walker 
49513cffa4aSShuhei Matsumoto struct spdk_iscsi_init_grp *
iscsi_init_grp_unregister(int tag)496df53885bSShuhei Matsumoto iscsi_init_grp_unregister(int tag)
49713cffa4aSShuhei Matsumoto {
49813cffa4aSShuhei Matsumoto 	struct spdk_iscsi_init_grp *ig;
499d29384bfSBen Walker 
500be1489b9SShuhei Matsumoto 	pthread_mutex_lock(&g_iscsi.mutex);
501be1489b9SShuhei Matsumoto 	TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
50213cffa4aSShuhei Matsumoto 		if (ig->tag == tag) {
503be1489b9SShuhei Matsumoto 			TAILQ_REMOVE(&g_iscsi.ig_head, ig, tailq);
504be1489b9SShuhei Matsumoto 			pthread_mutex_unlock(&g_iscsi.mutex);
50513cffa4aSShuhei Matsumoto 			return ig;
506d29384bfSBen Walker 		}
50759970a89SDaniel Verkamp 	}
508be1489b9SShuhei Matsumoto 	pthread_mutex_unlock(&g_iscsi.mutex);
50913cffa4aSShuhei Matsumoto 	return NULL;
510d29384bfSBen Walker }
5118107d04bSShuhei Matsumoto 
5128107d04bSShuhei Matsumoto static void
iscsi_init_grp_info_json(struct spdk_iscsi_init_grp * ig,struct spdk_json_write_ctx * w)513893e02a5SShuhei Matsumoto iscsi_init_grp_info_json(struct spdk_iscsi_init_grp *ig,
5148107d04bSShuhei Matsumoto 			 struct spdk_json_write_ctx *w)
5158107d04bSShuhei Matsumoto {
5168107d04bSShuhei Matsumoto 	struct spdk_iscsi_initiator_name *iname;
5178107d04bSShuhei Matsumoto 	struct spdk_iscsi_initiator_netmask *imask;
5188107d04bSShuhei Matsumoto 
5198107d04bSShuhei Matsumoto 	spdk_json_write_object_begin(w);
5208107d04bSShuhei Matsumoto 
5218107d04bSShuhei Matsumoto 	spdk_json_write_named_int32(w, "tag", ig->tag);
5228107d04bSShuhei Matsumoto 
5238107d04bSShuhei Matsumoto 	spdk_json_write_named_array_begin(w, "initiators");
5248107d04bSShuhei Matsumoto 	TAILQ_FOREACH(iname, &ig->initiator_head, tailq) {
5258107d04bSShuhei Matsumoto 		spdk_json_write_string(w, iname->name);
5268107d04bSShuhei Matsumoto 	}
5278107d04bSShuhei Matsumoto 	spdk_json_write_array_end(w);
5288107d04bSShuhei Matsumoto 
5298107d04bSShuhei Matsumoto 	spdk_json_write_named_array_begin(w, "netmasks");
5308107d04bSShuhei Matsumoto 	TAILQ_FOREACH(imask, &ig->netmask_head, tailq) {
5318107d04bSShuhei Matsumoto 		spdk_json_write_string(w, imask->mask);
5328107d04bSShuhei Matsumoto 	}
5338107d04bSShuhei Matsumoto 	spdk_json_write_array_end(w);
5348107d04bSShuhei Matsumoto 
5358107d04bSShuhei Matsumoto 	spdk_json_write_object_end(w);
5368107d04bSShuhei Matsumoto }
5378107d04bSShuhei Matsumoto 
5388107d04bSShuhei Matsumoto static void
iscsi_init_grp_config_json(struct spdk_iscsi_init_grp * ig,struct spdk_json_write_ctx * w)539893e02a5SShuhei Matsumoto iscsi_init_grp_config_json(struct spdk_iscsi_init_grp *ig,
5408107d04bSShuhei Matsumoto 			   struct spdk_json_write_ctx *w)
5418107d04bSShuhei Matsumoto {
5428107d04bSShuhei Matsumoto 	spdk_json_write_object_begin(w);
5438107d04bSShuhei Matsumoto 
54494dd4b9aSPawel Kaminski 	spdk_json_write_named_string(w, "method", "iscsi_create_initiator_group");
5458107d04bSShuhei Matsumoto 
5468107d04bSShuhei Matsumoto 	spdk_json_write_name(w, "params");
547893e02a5SShuhei Matsumoto 	iscsi_init_grp_info_json(ig, w);
5488107d04bSShuhei Matsumoto 
5498107d04bSShuhei Matsumoto 	spdk_json_write_object_end(w);
5508107d04bSShuhei Matsumoto }
5518107d04bSShuhei Matsumoto 
5528107d04bSShuhei Matsumoto void
iscsi_init_grps_info_json(struct spdk_json_write_ctx * w)553df53885bSShuhei Matsumoto iscsi_init_grps_info_json(struct spdk_json_write_ctx *w)
5548107d04bSShuhei Matsumoto {
5558107d04bSShuhei Matsumoto 	struct spdk_iscsi_init_grp *ig;
5568107d04bSShuhei Matsumoto 
557be1489b9SShuhei Matsumoto 	TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
558893e02a5SShuhei Matsumoto 		iscsi_init_grp_info_json(ig, w);
5598107d04bSShuhei Matsumoto 	}
5608107d04bSShuhei Matsumoto }
5618107d04bSShuhei Matsumoto 
5628107d04bSShuhei Matsumoto void
iscsi_init_grps_config_json(struct spdk_json_write_ctx * w)563df53885bSShuhei Matsumoto iscsi_init_grps_config_json(struct spdk_json_write_ctx *w)
5648107d04bSShuhei Matsumoto {
5658107d04bSShuhei Matsumoto 	struct spdk_iscsi_init_grp *ig;
5668107d04bSShuhei Matsumoto 
567be1489b9SShuhei Matsumoto 	TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
568893e02a5SShuhei Matsumoto 		iscsi_init_grp_config_json(ig, w);
5698107d04bSShuhei Matsumoto 	}
5708107d04bSShuhei Matsumoto }
571