Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
3 : : * Copyright (C) 2016 Intel Corporation.
4 : : * All rights reserved.
5 : : */
6 : :
7 : : #include "spdk/stdinc.h"
8 : :
9 : : #include "spdk/string.h"
10 : :
11 : : #include "spdk/log.h"
12 : :
13 : : #include "iscsi/iscsi.h"
14 : : #include "iscsi/init_grp.h"
15 : :
16 : : static struct spdk_iscsi_init_grp *
17 : 177 : iscsi_init_grp_create(int tag)
18 : : {
19 : : struct spdk_iscsi_init_grp *ig;
20 : :
21 : 177 : ig = calloc(1, sizeof(*ig));
22 [ - + ]: 177 : if (ig == NULL) {
23 : 0 : SPDK_ERRLOG("calloc() failed for initiator group\n");
24 : 0 : return NULL;
25 : : }
26 : :
27 : 177 : ig->tag = tag;
28 : 177 : TAILQ_INIT(&ig->initiator_head);
29 : 177 : TAILQ_INIT(&ig->netmask_head);
30 : 177 : return ig;
31 : : }
32 : :
33 : : static struct spdk_iscsi_initiator_name *
34 : 415 : iscsi_init_grp_find_initiator(struct spdk_iscsi_init_grp *ig, char *name)
35 : : {
36 : : struct spdk_iscsi_initiator_name *iname;
37 : :
38 [ + + ]: 569 : TAILQ_FOREACH(iname, &ig->initiator_head, tailq) {
39 [ + + - + : 328 : if (!strcmp(iname->name, name)) {
+ + ]
40 : 174 : return iname;
41 : : }
42 : : }
43 : 241 : return NULL;
44 : : }
45 : :
46 : : static int
47 : 216 : iscsi_init_grp_add_initiator(struct spdk_iscsi_init_grp *ig, char *name)
48 : : {
49 : : struct spdk_iscsi_initiator_name *iname;
50 : : char *p;
51 : : size_t len;
52 : :
53 [ + + ]: 216 : if (ig->ninitiators >= MAX_INITIATOR) {
54 : 5 : SPDK_ERRLOG("> MAX_INITIATOR(=%d) is not allowed\n", MAX_INITIATOR);
55 : 5 : return -EPERM;
56 : : }
57 : :
58 [ - + ]: 211 : len = strlen(name);
59 [ - + ]: 211 : if (len > MAX_INITIATOR_NAME) {
60 : 0 : SPDK_ERRLOG("Initiator Name is larger than 223 bytes\n");
61 : 0 : return -EINVAL;
62 : : }
63 : :
64 : 211 : iname = iscsi_init_grp_find_initiator(ig, name);
65 [ + + ]: 211 : if (iname != NULL) {
66 : 10 : return -EEXIST;
67 : : }
68 : :
69 : 201 : iname = calloc(1, sizeof(*iname));
70 [ - + ]: 201 : if (iname == NULL) {
71 : 0 : SPDK_ERRLOG("malloc() failed for initiator name str\n");
72 : 0 : return -ENOMEM;
73 : : }
74 : :
75 [ - + - + ]: 201 : memcpy(iname->name, name, len);
76 : :
77 : : /* Replace "ALL" by "ANY" if set */
78 [ - + ]: 201 : p = strstr(iname->name, "ALL");
79 [ + + ]: 201 : if (p != NULL) {
80 : 10 : SPDK_WARNLOG("Please use \"%s\" instead of \"%s\"\n", "ANY", "ALL");
81 : 10 : SPDK_WARNLOG("Converting \"%s\" to \"%s\" automatically\n", "ALL", "ANY");
82 [ - + ]: 10 : memcpy(p, "ANY", 3);
83 : : }
84 : :
85 : 201 : TAILQ_INSERT_TAIL(&ig->initiator_head, iname, tailq);
86 : 201 : ig->ninitiators++;
87 : :
88 [ - + - + ]: 201 : SPDK_DEBUGLOG(iscsi, "InitiatorName %s\n", name);
89 : 201 : return 0;
90 : : }
91 : :
92 : : static int
93 : 104 : iscsi_init_grp_delete_initiator(struct spdk_iscsi_init_grp *ig, char *name)
94 : : {
95 : : struct spdk_iscsi_initiator_name *iname;
96 : :
97 : 104 : iname = iscsi_init_grp_find_initiator(ig, name);
98 [ + + ]: 104 : if (iname == NULL) {
99 : 5 : return -ENOENT;
100 : : }
101 : :
102 [ + + ]: 99 : TAILQ_REMOVE(&ig->initiator_head, iname, tailq);
103 : 99 : ig->ninitiators--;
104 : 99 : free(iname);
105 : 99 : return 0;
106 : : }
107 : :
108 : : static int
109 : 131 : iscsi_init_grp_add_initiators(struct spdk_iscsi_init_grp *ig, int num_inames,
110 : : char **inames)
111 : : {
112 : : int i;
113 : : int rc;
114 : :
115 [ + + ]: 287 : for (i = 0; i < num_inames; i++) {
116 : 161 : rc = iscsi_init_grp_add_initiator(ig, inames[i]);
117 [ + + ]: 161 : if (rc < 0) {
118 : 5 : goto cleanup;
119 : : }
120 : : }
121 : 126 : return 0;
122 : :
123 : 5 : cleanup:
124 [ + + ]: 15 : for (; i > 0; --i) {
125 : 10 : iscsi_init_grp_delete_initiator(ig, inames[i - 1]);
126 : : }
127 : 5 : return rc;
128 : : }
129 : :
130 : : static void
131 : 182 : iscsi_init_grp_delete_all_initiators(struct spdk_iscsi_init_grp *ig)
132 : : {
133 : : struct spdk_iscsi_initiator_name *iname, *tmp;
134 : :
135 [ + + ]: 284 : TAILQ_FOREACH_SAFE(iname, &ig->initiator_head, tailq, tmp) {
136 [ + + ]: 102 : TAILQ_REMOVE(&ig->initiator_head, iname, tailq);
137 : 102 : ig->ninitiators--;
138 : 102 : free(iname);
139 : : }
140 : 182 : }
141 : :
142 : : static int
143 : 39 : iscsi_init_grp_delete_initiators(struct spdk_iscsi_init_grp *ig, int num_inames, char **inames)
144 : : {
145 : : int i;
146 : : int rc;
147 : :
148 [ + + ]: 103 : for (i = 0; i < num_inames; i++) {
149 : 69 : rc = iscsi_init_grp_delete_initiator(ig, inames[i]);
150 [ + + ]: 69 : if (rc < 0) {
151 : 5 : goto cleanup;
152 : : }
153 : : }
154 : 34 : return 0;
155 : :
156 : 5 : cleanup:
157 [ + + ]: 15 : for (; i > 0; --i) {
158 : 10 : rc = iscsi_init_grp_add_initiator(ig, inames[i - 1]);
159 [ - + ]: 10 : if (rc != 0) {
160 : 0 : iscsi_init_grp_delete_all_initiators(ig);
161 : 0 : break;
162 : : }
163 : : }
164 : 5 : return -1;
165 : : }
166 : :
167 : : static struct spdk_iscsi_initiator_netmask *
168 : 395 : iscsi_init_grp_find_netmask(struct spdk_iscsi_init_grp *ig, const char *mask)
169 : : {
170 : : struct spdk_iscsi_initiator_netmask *netmask;
171 : :
172 [ + + ]: 544 : TAILQ_FOREACH(netmask, &ig->netmask_head, tailq) {
173 [ + + - + : 313 : if (!strcmp(netmask->mask, mask)) {
+ + ]
174 : 164 : return netmask;
175 : : }
176 : : }
177 : 231 : return NULL;
178 : : }
179 : :
180 : : static int
181 : 211 : iscsi_init_grp_add_netmask(struct spdk_iscsi_init_grp *ig, char *mask)
182 : : {
183 : : struct spdk_iscsi_initiator_netmask *imask;
184 : : char *p;
185 : : size_t len;
186 : :
187 [ + + ]: 211 : if (ig->nnetmasks >= MAX_NETMASK) {
188 : 5 : SPDK_ERRLOG("> MAX_NETMASK(=%d) is not allowed\n", MAX_NETMASK);
189 : 5 : return -EPERM;
190 : : }
191 : :
192 [ - + ]: 206 : len = strlen(mask);
193 [ - + ]: 206 : if (len > MAX_INITIATOR_ADDR) {
194 : 0 : SPDK_ERRLOG("Initiator Name is larger than %d bytes\n", MAX_INITIATOR_ADDR);
195 : 0 : return -EINVAL;
196 : : }
197 : :
198 : 206 : imask = iscsi_init_grp_find_netmask(ig, mask);
199 [ + + ]: 206 : if (imask != NULL) {
200 : 10 : return -EEXIST;
201 : : }
202 : :
203 : 196 : imask = calloc(1, sizeof(*imask));
204 [ - + ]: 196 : if (imask == NULL) {
205 : 0 : SPDK_ERRLOG("malloc() failed for initiator mask str\n");
206 : 0 : return -ENOMEM;
207 : : }
208 : :
209 [ - + - + ]: 196 : memcpy(imask->mask, mask, len);
210 : :
211 : : /* Replace "ALL" by "ANY" if set */
212 [ - + ]: 196 : p = strstr(imask->mask, "ALL");
213 [ + + ]: 196 : if (p != NULL) {
214 : 5 : SPDK_WARNLOG("Please use \"%s\" instead of \"%s\"\n", "ANY", "ALL");
215 : 5 : SPDK_WARNLOG("Converting \"%s\" to \"%s\" automatically\n", "ALL", "ANY");
216 [ - + ]: 5 : memcpy(p, "ANY", 3);
217 : : }
218 : :
219 : 196 : TAILQ_INSERT_TAIL(&ig->netmask_head, imask, tailq);
220 : 196 : ig->nnetmasks++;
221 : :
222 [ - + - + ]: 196 : SPDK_DEBUGLOG(iscsi, "Netmask %s\n", mask);
223 : 196 : return 0;
224 : : }
225 : :
226 : : static int
227 : 99 : iscsi_init_grp_delete_netmask(struct spdk_iscsi_init_grp *ig, char *mask)
228 : : {
229 : : struct spdk_iscsi_initiator_netmask *imask;
230 : :
231 : 99 : imask = iscsi_init_grp_find_netmask(ig, mask);
232 [ + + ]: 99 : if (imask == NULL) {
233 : 5 : return -ENOENT;
234 : : }
235 : :
236 [ + + ]: 94 : TAILQ_REMOVE(&ig->netmask_head, imask, tailq);
237 : 94 : ig->nnetmasks--;
238 : 94 : free(imask);
239 : 94 : return 0;
240 : : }
241 : :
242 : : static int
243 : 131 : iscsi_init_grp_add_netmasks(struct spdk_iscsi_init_grp *ig, int num_imasks, char **imasks)
244 : : {
245 : : int i;
246 : : int rc;
247 : :
248 [ + + ]: 287 : for (i = 0; i < num_imasks; i++) {
249 : 161 : rc = iscsi_init_grp_add_netmask(ig, imasks[i]);
250 [ + + ]: 161 : if (rc != 0) {
251 : 5 : goto cleanup;
252 : : }
253 : : }
254 : 126 : return 0;
255 : :
256 : 5 : cleanup:
257 [ + + ]: 15 : for (; i > 0; --i) {
258 : 10 : iscsi_init_grp_delete_netmask(ig, imasks[i - 1]);
259 : : }
260 : 5 : return rc;
261 : : }
262 : :
263 : : static void
264 : 182 : iscsi_init_grp_delete_all_netmasks(struct spdk_iscsi_init_grp *ig)
265 : : {
266 : : struct spdk_iscsi_initiator_netmask *imask, *tmp;
267 : :
268 [ + + ]: 284 : TAILQ_FOREACH_SAFE(imask, &ig->netmask_head, tailq, tmp) {
269 [ + + ]: 102 : TAILQ_REMOVE(&ig->netmask_head, imask, tailq);
270 : 102 : ig->nnetmasks--;
271 : 102 : free(imask);
272 : : }
273 : 182 : }
274 : :
275 : : static int
276 : 39 : iscsi_init_grp_delete_netmasks(struct spdk_iscsi_init_grp *ig, int num_imasks, char **imasks)
277 : : {
278 : : int i;
279 : : int rc;
280 : :
281 [ + + ]: 103 : for (i = 0; i < num_imasks; i++) {
282 : 69 : rc = iscsi_init_grp_delete_netmask(ig, imasks[i]);
283 [ + + ]: 69 : if (rc != 0) {
284 : 5 : goto cleanup;
285 : : }
286 : : }
287 : 34 : return 0;
288 : :
289 : 5 : cleanup:
290 [ + + ]: 15 : for (; i > 0; --i) {
291 : 10 : rc = iscsi_init_grp_add_netmask(ig, imasks[i - 1]);
292 [ - + ]: 10 : if (rc != 0) {
293 : 0 : iscsi_init_grp_delete_all_netmasks(ig);
294 : 0 : break;
295 : : }
296 : : }
297 : 5 : return -1;
298 : : }
299 : :
300 : : int
301 : 107 : iscsi_init_grp_register(struct spdk_iscsi_init_grp *ig)
302 : : {
303 : : struct spdk_iscsi_init_grp *tmp;
304 : 107 : int rc = -1;
305 : :
306 [ - + ]: 107 : assert(ig != NULL);
307 : :
308 [ - + ]: 107 : pthread_mutex_lock(&g_iscsi.mutex);
309 : 107 : tmp = iscsi_init_grp_find_by_tag(ig->tag);
310 [ + + ]: 107 : if (tmp == NULL) {
311 : 102 : TAILQ_INSERT_TAIL(&g_iscsi.ig_head, ig, tailq);
312 : 102 : rc = 0;
313 : : }
314 [ - + ]: 107 : pthread_mutex_unlock(&g_iscsi.mutex);
315 : :
316 : 107 : return rc;
317 : : }
318 : :
319 : : /*
320 : : * Create initiator group from list of initiator ip/hostnames and netmasks
321 : : * The initiator hostname/netmask lists are allocated by the caller on the
322 : : * heap. Freed later by common initiator_group_destroy() code
323 : : */
324 : : int
325 : 92 : iscsi_init_grp_create_from_initiator_list(int tag,
326 : : int num_initiator_names,
327 : : char **initiator_names,
328 : : int num_initiator_masks,
329 : : char **initiator_masks)
330 : : {
331 : 92 : int rc = -1;
332 : 92 : struct spdk_iscsi_init_grp *ig = NULL;
333 : :
334 [ - + - + ]: 92 : SPDK_DEBUGLOG(iscsi,
335 : : "add initiator group (from initiator list) tag=%d, #initiators=%d, #masks=%d\n",
336 : : tag, num_initiator_names, num_initiator_masks);
337 : :
338 : 92 : ig = iscsi_init_grp_create(tag);
339 [ - + ]: 92 : if (!ig) {
340 : 0 : SPDK_ERRLOG("initiator group create error (%d)\n", tag);
341 : 0 : return rc;
342 : : }
343 : :
344 : 92 : rc = iscsi_init_grp_add_initiators(ig, num_initiator_names,
345 : : initiator_names);
346 [ - + ]: 92 : if (rc < 0) {
347 : 0 : SPDK_ERRLOG("add initiator name error\n");
348 : 0 : goto cleanup;
349 : : }
350 : :
351 : 92 : rc = iscsi_init_grp_add_netmasks(ig, num_initiator_masks,
352 : : initiator_masks);
353 [ - + ]: 92 : if (rc < 0) {
354 : 0 : SPDK_ERRLOG("add initiator netmask error\n");
355 : 0 : goto cleanup;
356 : : }
357 : :
358 : 92 : rc = iscsi_init_grp_register(ig);
359 [ - + ]: 92 : if (rc < 0) {
360 : 0 : SPDK_ERRLOG("initiator group register error (%d)\n", tag);
361 : 0 : goto cleanup;
362 : : }
363 : 92 : return 0;
364 : :
365 : 0 : cleanup:
366 : 0 : iscsi_init_grp_destroy(ig);
367 : 0 : return rc;
368 : : }
369 : :
370 : : int
371 : 24 : iscsi_init_grp_add_initiators_from_initiator_list(int tag,
372 : : int num_initiator_names,
373 : : char **initiator_names,
374 : : int num_initiator_masks,
375 : : char **initiator_masks)
376 : : {
377 : 24 : int rc = -1;
378 : : struct spdk_iscsi_init_grp *ig;
379 : :
380 [ - + - + ]: 24 : SPDK_DEBUGLOG(iscsi,
381 : : "add initiator to initiator group: tag=%d, #initiators=%d, #masks=%d\n",
382 : : tag, num_initiator_names, num_initiator_masks);
383 : :
384 [ - + ]: 24 : pthread_mutex_lock(&g_iscsi.mutex);
385 : 24 : ig = iscsi_init_grp_find_by_tag(tag);
386 [ - + ]: 24 : if (!ig) {
387 [ # # ]: 0 : pthread_mutex_unlock(&g_iscsi.mutex);
388 : 0 : SPDK_ERRLOG("initiator group (%d) is not found\n", tag);
389 : 0 : return rc;
390 : : }
391 : :
392 : 24 : rc = iscsi_init_grp_add_initiators(ig, num_initiator_names,
393 : : initiator_names);
394 [ - + ]: 24 : if (rc < 0) {
395 : 0 : SPDK_ERRLOG("add initiator name error\n");
396 : 0 : goto error;
397 : : }
398 : :
399 : 24 : rc = iscsi_init_grp_add_netmasks(ig, num_initiator_masks,
400 : : initiator_masks);
401 [ + - ]: 24 : if (rc < 0) {
402 : 0 : SPDK_ERRLOG("add initiator netmask error\n");
403 : 0 : iscsi_init_grp_delete_initiators(ig, num_initiator_names,
404 : : initiator_names);
405 : : }
406 : :
407 : 24 : error:
408 [ - + ]: 24 : pthread_mutex_unlock(&g_iscsi.mutex);
409 : 24 : return rc;
410 : : }
411 : :
412 : : int
413 : 24 : iscsi_init_grp_delete_initiators_from_initiator_list(int tag,
414 : : int num_initiator_names,
415 : : char **initiator_names,
416 : : int num_initiator_masks,
417 : : char **initiator_masks)
418 : : {
419 : 24 : int rc = -1;
420 : : struct spdk_iscsi_init_grp *ig;
421 : :
422 [ - + - + ]: 24 : SPDK_DEBUGLOG(iscsi,
423 : : "delete initiator from initiator group: tag=%d, #initiators=%d, #masks=%d\n",
424 : : tag, num_initiator_names, num_initiator_masks);
425 : :
426 [ - + ]: 24 : pthread_mutex_lock(&g_iscsi.mutex);
427 : 24 : ig = iscsi_init_grp_find_by_tag(tag);
428 [ - + ]: 24 : if (!ig) {
429 [ # # ]: 0 : pthread_mutex_unlock(&g_iscsi.mutex);
430 : 0 : SPDK_ERRLOG("initiator group (%d) is not found\n", tag);
431 : 0 : return rc;
432 : : }
433 : :
434 : 24 : rc = iscsi_init_grp_delete_initiators(ig, num_initiator_names,
435 : : initiator_names);
436 [ - + ]: 24 : if (rc < 0) {
437 : 0 : SPDK_ERRLOG("delete initiator name error\n");
438 : 0 : goto error;
439 : : }
440 : :
441 : 24 : rc = iscsi_init_grp_delete_netmasks(ig, num_initiator_masks,
442 : : initiator_masks);
443 [ + - ]: 24 : if (rc < 0) {
444 : 0 : SPDK_ERRLOG("delete initiator netmask error\n");
445 : 0 : iscsi_init_grp_add_initiators(ig, num_initiator_names,
446 : : initiator_names);
447 : 0 : goto error;
448 : : }
449 : :
450 : 24 : error:
451 [ - + ]: 24 : pthread_mutex_unlock(&g_iscsi.mutex);
452 : 24 : return rc;
453 : : }
454 : :
455 : : void
456 : 177 : iscsi_init_grp_destroy(struct spdk_iscsi_init_grp *ig)
457 : : {
458 [ - + ]: 177 : if (!ig) {
459 : 0 : return;
460 : : }
461 : :
462 : 177 : iscsi_init_grp_delete_all_initiators(ig);
463 : 177 : iscsi_init_grp_delete_all_netmasks(ig);
464 : 177 : free(ig);
465 : : };
466 : :
467 : : struct spdk_iscsi_init_grp *
468 : 345 : iscsi_init_grp_find_by_tag(int tag)
469 : : {
470 : : struct spdk_iscsi_init_grp *ig;
471 : :
472 [ + + ]: 861 : TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
473 [ + + ]: 749 : if (ig->tag == tag) {
474 : 233 : return ig;
475 : : }
476 : : }
477 : :
478 : 112 : return NULL;
479 : : }
480 : :
481 : : void
482 : 587 : iscsi_init_grps_destroy(void)
483 : : {
484 : : struct spdk_iscsi_init_grp *ig, *tmp;
485 : :
486 [ - + - + ]: 587 : SPDK_DEBUGLOG(iscsi, "iscsi_init_grp_array_destroy\n");
487 [ - + ]: 587 : pthread_mutex_lock(&g_iscsi.mutex);
488 [ + + ]: 645 : TAILQ_FOREACH_SAFE(ig, &g_iscsi.ig_head, tailq, tmp) {
489 [ + + ]: 58 : TAILQ_REMOVE(&g_iscsi.ig_head, ig, tailq);
490 : 58 : iscsi_init_grp_destroy(ig);
491 : : }
492 [ - + ]: 587 : pthread_mutex_unlock(&g_iscsi.mutex);
493 : 587 : }
494 : :
495 : : struct spdk_iscsi_init_grp *
496 : 44 : iscsi_init_grp_unregister(int tag)
497 : : {
498 : : struct spdk_iscsi_init_grp *ig;
499 : :
500 [ - + ]: 44 : pthread_mutex_lock(&g_iscsi.mutex);
501 [ + - ]: 46 : TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
502 [ + + ]: 46 : if (ig->tag == tag) {
503 [ + + ]: 44 : TAILQ_REMOVE(&g_iscsi.ig_head, ig, tailq);
504 [ - + ]: 44 : pthread_mutex_unlock(&g_iscsi.mutex);
505 : 44 : return ig;
506 : : }
507 : : }
508 [ # # ]: 0 : pthread_mutex_unlock(&g_iscsi.mutex);
509 : 0 : return NULL;
510 : : }
511 : :
512 : : static void
513 : 398 : iscsi_init_grp_info_json(struct spdk_iscsi_init_grp *ig,
514 : : struct spdk_json_write_ctx *w)
515 : : {
516 : : struct spdk_iscsi_initiator_name *iname;
517 : : struct spdk_iscsi_initiator_netmask *imask;
518 : :
519 : 398 : spdk_json_write_object_begin(w);
520 : :
521 : 398 : spdk_json_write_named_int32(w, "tag", ig->tag);
522 : :
523 : 398 : spdk_json_write_named_array_begin(w, "initiators");
524 [ + + ]: 814 : TAILQ_FOREACH(iname, &ig->initiator_head, tailq) {
525 : 416 : spdk_json_write_string(w, iname->name);
526 : : }
527 : 398 : spdk_json_write_array_end(w);
528 : :
529 : 398 : spdk_json_write_named_array_begin(w, "netmasks");
530 [ + + ]: 814 : TAILQ_FOREACH(imask, &ig->netmask_head, tailq) {
531 : 416 : spdk_json_write_string(w, imask->mask);
532 : : }
533 : 398 : spdk_json_write_array_end(w);
534 : :
535 : 398 : spdk_json_write_object_end(w);
536 : 398 : }
537 : :
538 : : static void
539 : 8 : iscsi_init_grp_config_json(struct spdk_iscsi_init_grp *ig,
540 : : struct spdk_json_write_ctx *w)
541 : : {
542 : 8 : spdk_json_write_object_begin(w);
543 : :
544 : 8 : spdk_json_write_named_string(w, "method", "iscsi_create_initiator_group");
545 : :
546 : 8 : spdk_json_write_name(w, "params");
547 : 8 : iscsi_init_grp_info_json(ig, w);
548 : :
549 : 8 : spdk_json_write_object_end(w);
550 : 8 : }
551 : :
552 : : void
553 : 169 : iscsi_init_grps_info_json(struct spdk_json_write_ctx *w)
554 : : {
555 : : struct spdk_iscsi_init_grp *ig;
556 : :
557 [ + + ]: 559 : TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
558 : 390 : iscsi_init_grp_info_json(ig, w);
559 : : }
560 : 169 : }
561 : :
562 : : void
563 : 95 : iscsi_init_grps_config_json(struct spdk_json_write_ctx *w)
564 : : {
565 : : struct spdk_iscsi_init_grp *ig;
566 : :
567 [ + + ]: 103 : TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
568 : 8 : iscsi_init_grp_config_json(ig, w);
569 : : }
570 : 95 : }
|