]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/lib/iscsi/init_grp.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / lib / iscsi / init_grp.c
1 /*-
2 * BSD LICENSE
3 *
4 * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
5 * Copyright (c) Intel Corporation.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 * * Neither the name of Intel Corporation nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #include "spdk/stdinc.h"
36
37 #include "spdk/conf.h"
38 #include "spdk/string.h"
39
40 #include "spdk_internal/log.h"
41
42 #include "iscsi/iscsi.h"
43 #include "iscsi/init_grp.h"
44
45 static struct spdk_iscsi_init_grp *
46 iscsi_init_grp_create(int tag)
47 {
48 struct spdk_iscsi_init_grp *ig;
49
50 ig = calloc(1, sizeof(*ig));
51 if (ig == NULL) {
52 SPDK_ERRLOG("calloc() failed for initiator group\n");
53 return NULL;
54 }
55
56 ig->tag = tag;
57 TAILQ_INIT(&ig->initiator_head);
58 TAILQ_INIT(&ig->netmask_head);
59 return ig;
60 }
61
62 static struct spdk_iscsi_initiator_name *
63 iscsi_init_grp_find_initiator(struct spdk_iscsi_init_grp *ig, char *name)
64 {
65 struct spdk_iscsi_initiator_name *iname;
66
67 TAILQ_FOREACH(iname, &ig->initiator_head, tailq) {
68 if (!strcmp(iname->name, name)) {
69 return iname;
70 }
71 }
72 return NULL;
73 }
74
75 static int
76 iscsi_init_grp_add_initiator(struct spdk_iscsi_init_grp *ig, char *name)
77 {
78 struct spdk_iscsi_initiator_name *iname;
79 char *p;
80 size_t len;
81
82 if (ig->ninitiators >= MAX_INITIATOR) {
83 SPDK_ERRLOG("> MAX_INITIATOR(=%d) is not allowed\n", MAX_INITIATOR);
84 return -EPERM;
85 }
86
87 len = strlen(name);
88 if (len > MAX_INITIATOR_NAME) {
89 SPDK_ERRLOG("Initiator Name is larger than 223 bytes\n");
90 return -EINVAL;
91 }
92
93 iname = iscsi_init_grp_find_initiator(ig, name);
94 if (iname != NULL) {
95 return -EEXIST;
96 }
97
98 iname = calloc(1, sizeof(*iname));
99 if (iname == NULL) {
100 SPDK_ERRLOG("malloc() failed for initiator name str\n");
101 return -ENOMEM;
102 }
103
104 memcpy(iname->name, name, len);
105
106 /* Replace "ALL" by "ANY" if set */
107 p = strstr(iname->name, "ALL");
108 if (p != NULL) {
109 SPDK_WARNLOG("Please use \"%s\" instead of \"%s\"\n", "ANY", "ALL");
110 SPDK_WARNLOG("Converting \"%s\" to \"%s\" automatically\n", "ALL", "ANY");
111 memcpy(p, "ANY", 3);
112 }
113
114 TAILQ_INSERT_TAIL(&ig->initiator_head, iname, tailq);
115 ig->ninitiators++;
116
117 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "InitiatorName %s\n", name);
118 return 0;
119 }
120
121 static int
122 iscsi_init_grp_delete_initiator(struct spdk_iscsi_init_grp *ig, char *name)
123 {
124 struct spdk_iscsi_initiator_name *iname;
125
126 iname = iscsi_init_grp_find_initiator(ig, name);
127 if (iname == NULL) {
128 return -ENOENT;
129 }
130
131 TAILQ_REMOVE(&ig->initiator_head, iname, tailq);
132 ig->ninitiators--;
133 free(iname);
134 return 0;
135 }
136
137 static int
138 iscsi_init_grp_add_initiators(struct spdk_iscsi_init_grp *ig, int num_inames,
139 char **inames)
140 {
141 int i;
142 int rc;
143
144 for (i = 0; i < num_inames; i++) {
145 rc = iscsi_init_grp_add_initiator(ig, inames[i]);
146 if (rc < 0) {
147 goto cleanup;
148 }
149 }
150 return 0;
151
152 cleanup:
153 for (; i > 0; --i) {
154 iscsi_init_grp_delete_initiator(ig, inames[i - 1]);
155 }
156 return rc;
157 }
158
159 static void
160 iscsi_init_grp_delete_all_initiators(struct spdk_iscsi_init_grp *ig)
161 {
162 struct spdk_iscsi_initiator_name *iname, *tmp;
163
164 TAILQ_FOREACH_SAFE(iname, &ig->initiator_head, tailq, tmp) {
165 TAILQ_REMOVE(&ig->initiator_head, iname, tailq);
166 ig->ninitiators--;
167 free(iname);
168 }
169 }
170
171 static int
172 iscsi_init_grp_delete_initiators(struct spdk_iscsi_init_grp *ig, int num_inames, char **inames)
173 {
174 int i;
175 int rc;
176
177 for (i = 0; i < num_inames; i++) {
178 rc = iscsi_init_grp_delete_initiator(ig, inames[i]);
179 if (rc < 0) {
180 goto cleanup;
181 }
182 }
183 return 0;
184
185 cleanup:
186 for (; i > 0; --i) {
187 rc = iscsi_init_grp_add_initiator(ig, inames[i - 1]);
188 if (rc != 0) {
189 iscsi_init_grp_delete_all_initiators(ig);
190 break;
191 }
192 }
193 return -1;
194 }
195
196 static struct spdk_iscsi_initiator_netmask *
197 iscsi_init_grp_find_netmask(struct spdk_iscsi_init_grp *ig, const char *mask)
198 {
199 struct spdk_iscsi_initiator_netmask *netmask;
200
201 TAILQ_FOREACH(netmask, &ig->netmask_head, tailq) {
202 if (!strcmp(netmask->mask, mask)) {
203 return netmask;
204 }
205 }
206 return NULL;
207 }
208
209 static int
210 iscsi_init_grp_add_netmask(struct spdk_iscsi_init_grp *ig, char *mask)
211 {
212 struct spdk_iscsi_initiator_netmask *imask;
213 char *p;
214 size_t len;
215
216 if (ig->nnetmasks >= MAX_NETMASK) {
217 SPDK_ERRLOG("> MAX_NETMASK(=%d) is not allowed\n", MAX_NETMASK);
218 return -EPERM;
219 }
220
221 len = strlen(mask);
222 if (len > MAX_INITIATOR_ADDR) {
223 SPDK_ERRLOG("Initiator Name is larger than %d bytes\n", MAX_INITIATOR_ADDR);
224 return -EINVAL;
225 }
226
227 imask = iscsi_init_grp_find_netmask(ig, mask);
228 if (imask != NULL) {
229 return -EEXIST;
230 }
231
232 imask = calloc(1, sizeof(*imask));
233 if (imask == NULL) {
234 SPDK_ERRLOG("malloc() failed for inititator mask str\n");
235 return -ENOMEM;
236 }
237
238 memcpy(imask->mask, mask, len);
239
240 /* Replace "ALL" by "ANY" if set */
241 p = strstr(imask->mask, "ALL");
242 if (p != NULL) {
243 SPDK_WARNLOG("Please use \"%s\" instead of \"%s\"\n", "ANY", "ALL");
244 SPDK_WARNLOG("Converting \"%s\" to \"%s\" automatically\n", "ALL", "ANY");
245 memcpy(p, "ANY", 3);
246 }
247
248 TAILQ_INSERT_TAIL(&ig->netmask_head, imask, tailq);
249 ig->nnetmasks++;
250
251 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Netmask %s\n", mask);
252 return 0;
253 }
254
255 static int
256 iscsi_init_grp_delete_netmask(struct spdk_iscsi_init_grp *ig, char *mask)
257 {
258 struct spdk_iscsi_initiator_netmask *imask;
259
260 imask = iscsi_init_grp_find_netmask(ig, mask);
261 if (imask == NULL) {
262 return -ENOENT;
263 }
264
265 TAILQ_REMOVE(&ig->netmask_head, imask, tailq);
266 ig->nnetmasks--;
267 free(imask);
268 return 0;
269 }
270
271 static int
272 iscsi_init_grp_add_netmasks(struct spdk_iscsi_init_grp *ig, int num_imasks, char **imasks)
273 {
274 int i;
275 int rc;
276
277 for (i = 0; i < num_imasks; i++) {
278 rc = iscsi_init_grp_add_netmask(ig, imasks[i]);
279 if (rc != 0) {
280 goto cleanup;
281 }
282 }
283 return 0;
284
285 cleanup:
286 for (; i > 0; --i) {
287 iscsi_init_grp_delete_netmask(ig, imasks[i - 1]);
288 }
289 return rc;
290 }
291
292 static void
293 iscsi_init_grp_delete_all_netmasks(struct spdk_iscsi_init_grp *ig)
294 {
295 struct spdk_iscsi_initiator_netmask *imask, *tmp;
296
297 TAILQ_FOREACH_SAFE(imask, &ig->netmask_head, tailq, tmp) {
298 TAILQ_REMOVE(&ig->netmask_head, imask, tailq);
299 ig->nnetmasks--;
300 free(imask);
301 }
302 }
303
304 static int
305 iscsi_init_grp_delete_netmasks(struct spdk_iscsi_init_grp *ig, int num_imasks, char **imasks)
306 {
307 int i;
308 int rc;
309
310 for (i = 0; i < num_imasks; i++) {
311 rc = iscsi_init_grp_delete_netmask(ig, imasks[i]);
312 if (rc != 0) {
313 goto cleanup;
314 }
315 }
316 return 0;
317
318 cleanup:
319 for (; i > 0; --i) {
320 rc = iscsi_init_grp_add_netmask(ig, imasks[i - 1]);
321 if (rc != 0) {
322 iscsi_init_grp_delete_all_netmasks(ig);
323 break;
324 }
325 }
326 return -1;
327 }
328
329 /* Read spdk iscsi target's config file and create initiator group */
330 static int
331 iscsi_parse_init_grp(struct spdk_conf_section *sp)
332 {
333 int i, rc = 0;
334 const char *val = NULL;
335 int num_initiator_names;
336 int num_initiator_masks;
337 char **initiators = NULL, **netmasks = NULL;
338 int tag = spdk_conf_section_get_num(sp);
339
340 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "add initiator group %d\n", tag);
341
342 val = spdk_conf_section_get_val(sp, "Comment");
343 if (val != NULL) {
344 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Comment %s\n", val);
345 }
346
347 /* counts number of definitions */
348 for (i = 0; ; i++) {
349 val = spdk_conf_section_get_nval(sp, "InitiatorName", i);
350 if (val == NULL) {
351 break;
352 }
353 }
354 if (i == 0) {
355 SPDK_ERRLOG("num_initiator_names = 0\n");
356 return -EINVAL;
357 }
358 num_initiator_names = i;
359 if (num_initiator_names > MAX_INITIATOR) {
360 SPDK_ERRLOG("%d > MAX_INITIATOR\n", num_initiator_names);
361 return -E2BIG;
362 }
363 for (i = 0; ; i++) {
364 val = spdk_conf_section_get_nval(sp, "Netmask", i);
365 if (val == NULL) {
366 break;
367 }
368 }
369 if (i == 0) {
370 SPDK_ERRLOG("num_initiator_mask = 0\n");
371 return -EINVAL;
372 }
373 num_initiator_masks = i;
374 if (num_initiator_masks > MAX_NETMASK) {
375 SPDK_ERRLOG("%d > MAX_NETMASK\n", num_initiator_masks);
376 return -E2BIG;
377 }
378
379 initiators = calloc(num_initiator_names, sizeof(char *));
380 if (!initiators) {
381 SPDK_ERRLOG("calloc() failed for temp initiator name array\n");
382 return -ENOMEM;
383 }
384 for (i = 0; i < num_initiator_names; i++) {
385 val = spdk_conf_section_get_nval(sp, "InitiatorName", i);
386 if (!val) {
387 SPDK_ERRLOG("InitiatorName %d not found\n", i);
388 rc = -EINVAL;
389 goto cleanup;
390 }
391 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "InitiatorName %s\n", val);
392 initiators[i] = strdup(val);
393 if (!initiators[i]) {
394 SPDK_ERRLOG("strdup() failed for temp initiator name\n");
395 rc = -ENOMEM;
396 goto cleanup;
397 }
398 }
399 netmasks = calloc(num_initiator_masks, sizeof(char *));
400 if (!netmasks) {
401 SPDK_ERRLOG("malloc() failed for portal group\n");
402 rc = -ENOMEM;
403 goto cleanup;
404 }
405 for (i = 0; i < num_initiator_masks; i++) {
406 val = spdk_conf_section_get_nval(sp, "Netmask", i);
407 if (!val) {
408 SPDK_ERRLOG("Netmask %d not found\n", i);
409 rc = -EINVAL;
410 goto cleanup;
411 }
412 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Netmask %s\n", val);
413 netmasks[i] = strdup(val);
414 if (!netmasks[i]) {
415 SPDK_ERRLOG("strdup() failed for temp initiator mask\n");
416 rc = -ENOMEM;
417 goto cleanup;
418 }
419 }
420
421 rc = iscsi_init_grp_create_from_initiator_list(tag,
422 num_initiator_names, initiators, num_initiator_masks, netmasks);
423
424 cleanup:
425 if (initiators) {
426 for (i = 0; i < num_initiator_names; i++) {
427 if (initiators[i]) {
428 free(initiators[i]);
429 }
430 }
431 free(initiators);
432 }
433 if (netmasks) {
434 for (i = 0; i < num_initiator_masks; i++) {
435 if (netmasks[i]) {
436 free(netmasks[i]);
437 }
438 }
439 free(netmasks);
440 }
441 return rc;
442 }
443
444 int
445 iscsi_init_grp_register(struct spdk_iscsi_init_grp *ig)
446 {
447 struct spdk_iscsi_init_grp *tmp;
448 int rc = -1;
449
450 assert(ig != NULL);
451
452 pthread_mutex_lock(&g_iscsi.mutex);
453 tmp = iscsi_init_grp_find_by_tag(ig->tag);
454 if (tmp == NULL) {
455 TAILQ_INSERT_TAIL(&g_iscsi.ig_head, ig, tailq);
456 rc = 0;
457 }
458 pthread_mutex_unlock(&g_iscsi.mutex);
459
460 return rc;
461 }
462
463 /*
464 * Create initiator group from list of initiator ip/hostnames and netmasks
465 * The initiator hostname/netmask lists are allocated by the caller on the
466 * heap. Freed later by common initiator_group_destroy() code
467 */
468 int
469 iscsi_init_grp_create_from_initiator_list(int tag,
470 int num_initiator_names,
471 char **initiator_names,
472 int num_initiator_masks,
473 char **initiator_masks)
474 {
475 int rc = -1;
476 struct spdk_iscsi_init_grp *ig = NULL;
477
478 SPDK_DEBUGLOG(SPDK_LOG_ISCSI,
479 "add initiator group (from initiator list) tag=%d, #initiators=%d, #masks=%d\n",
480 tag, num_initiator_names, num_initiator_masks);
481
482 ig = iscsi_init_grp_create(tag);
483 if (!ig) {
484 SPDK_ERRLOG("initiator group create error (%d)\n", tag);
485 return rc;
486 }
487
488 rc = iscsi_init_grp_add_initiators(ig, num_initiator_names,
489 initiator_names);
490 if (rc < 0) {
491 SPDK_ERRLOG("add initiator name error\n");
492 goto cleanup;
493 }
494
495 rc = iscsi_init_grp_add_netmasks(ig, num_initiator_masks,
496 initiator_masks);
497 if (rc < 0) {
498 SPDK_ERRLOG("add initiator netmask error\n");
499 goto cleanup;
500 }
501
502 rc = iscsi_init_grp_register(ig);
503 if (rc < 0) {
504 SPDK_ERRLOG("initiator group register error (%d)\n", tag);
505 goto cleanup;
506 }
507 return 0;
508
509 cleanup:
510 iscsi_init_grp_destroy(ig);
511 return rc;
512 }
513
514 int
515 iscsi_init_grp_add_initiators_from_initiator_list(int tag,
516 int num_initiator_names,
517 char **initiator_names,
518 int num_initiator_masks,
519 char **initiator_masks)
520 {
521 int rc = -1;
522 struct spdk_iscsi_init_grp *ig;
523
524 SPDK_DEBUGLOG(SPDK_LOG_ISCSI,
525 "add initiator to initiator group: tag=%d, #initiators=%d, #masks=%d\n",
526 tag, num_initiator_names, num_initiator_masks);
527
528 pthread_mutex_lock(&g_iscsi.mutex);
529 ig = iscsi_init_grp_find_by_tag(tag);
530 if (!ig) {
531 pthread_mutex_unlock(&g_iscsi.mutex);
532 SPDK_ERRLOG("initiator group (%d) is not found\n", tag);
533 return rc;
534 }
535
536 rc = iscsi_init_grp_add_initiators(ig, num_initiator_names,
537 initiator_names);
538 if (rc < 0) {
539 SPDK_ERRLOG("add initiator name error\n");
540 goto error;
541 }
542
543 rc = iscsi_init_grp_add_netmasks(ig, num_initiator_masks,
544 initiator_masks);
545 if (rc < 0) {
546 SPDK_ERRLOG("add initiator netmask error\n");
547 iscsi_init_grp_delete_initiators(ig, num_initiator_names,
548 initiator_names);
549 }
550
551 error:
552 pthread_mutex_unlock(&g_iscsi.mutex);
553 return rc;
554 }
555
556 int
557 iscsi_init_grp_delete_initiators_from_initiator_list(int tag,
558 int num_initiator_names,
559 char **initiator_names,
560 int num_initiator_masks,
561 char **initiator_masks)
562 {
563 int rc = -1;
564 struct spdk_iscsi_init_grp *ig;
565
566 SPDK_DEBUGLOG(SPDK_LOG_ISCSI,
567 "delete initiator from initiator group: tag=%d, #initiators=%d, #masks=%d\n",
568 tag, num_initiator_names, num_initiator_masks);
569
570 pthread_mutex_lock(&g_iscsi.mutex);
571 ig = iscsi_init_grp_find_by_tag(tag);
572 if (!ig) {
573 pthread_mutex_unlock(&g_iscsi.mutex);
574 SPDK_ERRLOG("initiator group (%d) is not found\n", tag);
575 return rc;
576 }
577
578 rc = iscsi_init_grp_delete_initiators(ig, num_initiator_names,
579 initiator_names);
580 if (rc < 0) {
581 SPDK_ERRLOG("delete initiator name error\n");
582 goto error;
583 }
584
585 rc = iscsi_init_grp_delete_netmasks(ig, num_initiator_masks,
586 initiator_masks);
587 if (rc < 0) {
588 SPDK_ERRLOG("delete initiator netmask error\n");
589 iscsi_init_grp_add_initiators(ig, num_initiator_names,
590 initiator_names);
591 goto error;
592 }
593
594 error:
595 pthread_mutex_unlock(&g_iscsi.mutex);
596 return rc;
597 }
598
599 void
600 iscsi_init_grp_destroy(struct spdk_iscsi_init_grp *ig)
601 {
602 if (!ig) {
603 return;
604 }
605
606 iscsi_init_grp_delete_all_initiators(ig);
607 iscsi_init_grp_delete_all_netmasks(ig);
608 free(ig);
609 };
610
611 struct spdk_iscsi_init_grp *
612 iscsi_init_grp_find_by_tag(int tag)
613 {
614 struct spdk_iscsi_init_grp *ig;
615
616 TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
617 if (ig->tag == tag) {
618 return ig;
619 }
620 }
621
622 return NULL;
623 }
624
625 int
626 iscsi_parse_init_grps(void)
627 {
628 struct spdk_conf_section *sp;
629 int rc;
630
631 sp = spdk_conf_first_section(NULL);
632 while (sp != NULL) {
633 if (spdk_conf_section_match_prefix(sp, "InitiatorGroup")) {
634 if (spdk_conf_section_get_num(sp) == 0) {
635 SPDK_ERRLOG("Group 0 is invalid\n");
636 return -1;
637 }
638 rc = iscsi_parse_init_grp(sp);
639 if (rc < 0) {
640 SPDK_ERRLOG("parse_init_group() failed\n");
641 return -1;
642 }
643 }
644 sp = spdk_conf_next_section(sp);
645 }
646 return 0;
647 }
648
649 void
650 iscsi_init_grps_destroy(void)
651 {
652 struct spdk_iscsi_init_grp *ig, *tmp;
653
654 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "iscsi_init_grp_array_destroy\n");
655 pthread_mutex_lock(&g_iscsi.mutex);
656 TAILQ_FOREACH_SAFE(ig, &g_iscsi.ig_head, tailq, tmp) {
657 TAILQ_REMOVE(&g_iscsi.ig_head, ig, tailq);
658 iscsi_init_grp_destroy(ig);
659 }
660 pthread_mutex_unlock(&g_iscsi.mutex);
661 }
662
663 struct spdk_iscsi_init_grp *
664 iscsi_init_grp_unregister(int tag)
665 {
666 struct spdk_iscsi_init_grp *ig;
667
668 pthread_mutex_lock(&g_iscsi.mutex);
669 TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
670 if (ig->tag == tag) {
671 TAILQ_REMOVE(&g_iscsi.ig_head, ig, tailq);
672 pthread_mutex_unlock(&g_iscsi.mutex);
673 return ig;
674 }
675 }
676 pthread_mutex_unlock(&g_iscsi.mutex);
677 return NULL;
678 }
679
680 static const char *initiator_group_section = \
681 "\n"
682 "# Users must change the InitiatorGroup section(s) to match the IP\n"
683 "# addresses and initiator configuration in their environment.\n"
684 "# Netmask can be used to specify a single IP address or a range of IP addresses\n"
685 "# Netmask 192.168.1.20 <== single IP address\n"
686 "# Netmask 192.168.1.0/24 <== IP range 192.168.1.*\n";
687
688 #define INITIATOR_GROUP_TMPL \
689 "[InitiatorGroup%d]\n" \
690 " Comment \"Initiator Group%d\"\n"
691
692 #define INITIATOR_TMPL \
693 " InitiatorName "
694
695 #define NETMASK_TMPL \
696 " Netmask "
697
698 void
699 iscsi_init_grps_config_text(FILE *fp)
700 {
701 struct spdk_iscsi_init_grp *ig;
702 struct spdk_iscsi_initiator_name *iname;
703 struct spdk_iscsi_initiator_netmask *imask;
704
705 /* Create initiator group section */
706 fprintf(fp, "%s", initiator_group_section);
707
708 /* Dump initiator groups */
709 TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
710 if (NULL == ig) { continue; }
711 fprintf(fp, INITIATOR_GROUP_TMPL, ig->tag, ig->tag);
712
713 /* Dump initiators */
714 fprintf(fp, INITIATOR_TMPL);
715 TAILQ_FOREACH(iname, &ig->initiator_head, tailq) {
716 fprintf(fp, "%s ", iname->name);
717 }
718 fprintf(fp, "\n");
719
720 /* Dump netmasks */
721 fprintf(fp, NETMASK_TMPL);
722 TAILQ_FOREACH(imask, &ig->netmask_head, tailq) {
723 fprintf(fp, "%s ", imask->mask);
724 }
725 fprintf(fp, "\n");
726 }
727 }
728
729 static void
730 iscsi_init_grp_info_json(struct spdk_iscsi_init_grp *ig,
731 struct spdk_json_write_ctx *w)
732 {
733 struct spdk_iscsi_initiator_name *iname;
734 struct spdk_iscsi_initiator_netmask *imask;
735
736 spdk_json_write_object_begin(w);
737
738 spdk_json_write_named_int32(w, "tag", ig->tag);
739
740 spdk_json_write_named_array_begin(w, "initiators");
741 TAILQ_FOREACH(iname, &ig->initiator_head, tailq) {
742 spdk_json_write_string(w, iname->name);
743 }
744 spdk_json_write_array_end(w);
745
746 spdk_json_write_named_array_begin(w, "netmasks");
747 TAILQ_FOREACH(imask, &ig->netmask_head, tailq) {
748 spdk_json_write_string(w, imask->mask);
749 }
750 spdk_json_write_array_end(w);
751
752 spdk_json_write_object_end(w);
753 }
754
755 static void
756 iscsi_init_grp_config_json(struct spdk_iscsi_init_grp *ig,
757 struct spdk_json_write_ctx *w)
758 {
759 spdk_json_write_object_begin(w);
760
761 spdk_json_write_named_string(w, "method", "iscsi_create_initiator_group");
762
763 spdk_json_write_name(w, "params");
764 iscsi_init_grp_info_json(ig, w);
765
766 spdk_json_write_object_end(w);
767 }
768
769 void
770 iscsi_init_grps_info_json(struct spdk_json_write_ctx *w)
771 {
772 struct spdk_iscsi_init_grp *ig;
773
774 TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
775 iscsi_init_grp_info_json(ig, w);
776 }
777 }
778
779 void
780 iscsi_init_grps_config_json(struct spdk_json_write_ctx *w)
781 {
782 struct spdk_iscsi_init_grp *ig;
783
784 TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
785 iscsi_init_grp_config_json(ig, w);
786 }
787 }