LCOV - code coverage report
Current view: top level - lib/iscsi - init_grp.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 181 315 57.5 %
Date: 2024-12-05 11:28:15 Functions: 17 25 68.0 %

          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          17 : iscsi_init_grp_create(int tag)
      18             : {
      19             :         struct spdk_iscsi_init_grp *ig;
      20             : 
      21          17 :         ig = calloc(1, sizeof(*ig));
      22          17 :         if (ig == NULL) {
      23           0 :                 SPDK_ERRLOG("calloc() failed for initiator group\n");
      24           0 :                 return NULL;
      25             :         }
      26             : 
      27          17 :         ig->tag = tag;
      28          17 :         TAILQ_INIT(&ig->initiator_head);
      29          17 :         TAILQ_INIT(&ig->netmask_head);
      30          17 :         return ig;
      31          17 : }
      32             : 
      33             : static struct spdk_iscsi_initiator_name *
      34          55 : iscsi_init_grp_find_initiator(struct spdk_iscsi_init_grp *ig, char *name)
      35             : {
      36             :         struct spdk_iscsi_initiator_name *iname;
      37             : 
      38          85 :         TAILQ_FOREACH(iname, &ig->initiator_head, tailq) {
      39          60 :                 if (!strcmp(iname->name, name)) {
      40          30 :                         return iname;
      41             :                 }
      42          30 :         }
      43          25 :         return NULL;
      44          55 : }
      45             : 
      46             : static int
      47          20 : 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          20 :         if (ig->ninitiators >= MAX_INITIATOR) {
      54           1 :                 SPDK_ERRLOG("> MAX_INITIATOR(=%d) is not allowed\n", MAX_INITIATOR);
      55           1 :                 return -EPERM;
      56             :         }
      57             : 
      58          19 :         len = strlen(name);
      59          19 :         if (len > MAX_INITIATOR_NAME) {
      60           0 :                 SPDK_ERRLOG("Initiator Name is larger than 223 bytes\n");
      61           0 :                 return -EINVAL;
      62             :         }
      63             : 
      64          19 :         iname = iscsi_init_grp_find_initiator(ig, name);
      65          19 :         if (iname != NULL) {
      66           2 :                 return -EEXIST;
      67             :         }
      68             : 
      69          17 :         iname = calloc(1, sizeof(*iname));
      70          17 :         if (iname == NULL) {
      71           0 :                 SPDK_ERRLOG("malloc() failed for initiator name str\n");
      72           0 :                 return -ENOMEM;
      73             :         }
      74             : 
      75          17 :         memcpy(iname->name, name, len);
      76             : 
      77             :         /* Replace "ALL" by "ANY" if set */
      78          17 :         p = strstr(iname->name, "ALL");
      79          17 :         if (p != NULL) {
      80           2 :                 SPDK_WARNLOG("Please use \"%s\" instead of \"%s\"\n", "ANY", "ALL");
      81           2 :                 SPDK_WARNLOG("Converting \"%s\" to \"%s\" automatically\n", "ALL", "ANY");
      82           2 :                 memcpy(p, "ANY", 3);
      83           2 :         }
      84             : 
      85          17 :         TAILQ_INSERT_TAIL(&ig->initiator_head, iname, tailq);
      86          17 :         ig->ninitiators++;
      87             : 
      88          17 :         SPDK_DEBUGLOG(iscsi, "InitiatorName %s\n", name);
      89          17 :         return 0;
      90          20 : }
      91             : 
      92             : static int
      93          16 : iscsi_init_grp_delete_initiator(struct spdk_iscsi_init_grp *ig, char *name)
      94             : {
      95             :         struct spdk_iscsi_initiator_name *iname;
      96             : 
      97          16 :         iname = iscsi_init_grp_find_initiator(ig, name);
      98          16 :         if (iname == NULL) {
      99           1 :                 return -ENOENT;
     100             :         }
     101             : 
     102          15 :         TAILQ_REMOVE(&ig->initiator_head, iname, tailq);
     103          15 :         ig->ninitiators--;
     104          15 :         free(iname);
     105          15 :         return 0;
     106          16 : }
     107             : 
     108             : static int
     109           3 : 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          11 :         for (i = 0; i < num_inames; i++) {
     116           9 :                 rc = iscsi_init_grp_add_initiator(ig, inames[i]);
     117           9 :                 if (rc < 0) {
     118           1 :                         goto cleanup;
     119             :                 }
     120           8 :         }
     121           2 :         return 0;
     122             : 
     123             : cleanup:
     124           3 :         for (; i > 0; --i) {
     125           2 :                 iscsi_init_grp_delete_initiator(ig, inames[i - 1]);
     126           2 :         }
     127           1 :         return rc;
     128           3 : }
     129             : 
     130             : static void
     131          18 : iscsi_init_grp_delete_all_initiators(struct spdk_iscsi_init_grp *ig)
     132             : {
     133             :         struct spdk_iscsi_initiator_name *iname, *tmp;
     134             : 
     135          20 :         TAILQ_FOREACH_SAFE(iname, &ig->initiator_head, tailq, tmp) {
     136           2 :                 TAILQ_REMOVE(&ig->initiator_head, iname, tailq);
     137           2 :                 ig->ninitiators--;
     138           2 :                 free(iname);
     139           2 :         }
     140          18 : }
     141             : 
     142             : static int
     143           3 : 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          11 :         for (i = 0; i < num_inames; i++) {
     149           9 :                 rc = iscsi_init_grp_delete_initiator(ig, inames[i]);
     150           9 :                 if (rc < 0) {
     151           1 :                         goto cleanup;
     152             :                 }
     153           8 :         }
     154           2 :         return 0;
     155             : 
     156             : cleanup:
     157           3 :         for (; i > 0; --i) {
     158           2 :                 rc = iscsi_init_grp_add_initiator(ig, inames[i - 1]);
     159           2 :                 if (rc != 0) {
     160           0 :                         iscsi_init_grp_delete_all_initiators(ig);
     161           0 :                         break;
     162             :                 }
     163           2 :         }
     164           1 :         return -1;
     165           3 : }
     166             : 
     167             : static struct spdk_iscsi_initiator_netmask *
     168          51 : iscsi_init_grp_find_netmask(struct spdk_iscsi_init_grp *ig, const char *mask)
     169             : {
     170             :         struct spdk_iscsi_initiator_netmask *netmask;
     171             : 
     172          80 :         TAILQ_FOREACH(netmask, &ig->netmask_head, tailq) {
     173          57 :                 if (!strcmp(netmask->mask, mask)) {
     174          28 :                         return netmask;
     175             :                 }
     176          29 :         }
     177          23 :         return NULL;
     178          51 : }
     179             : 
     180             : static int
     181          19 : 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          19 :         if (ig->nnetmasks >= MAX_NETMASK) {
     188           1 :                 SPDK_ERRLOG("> MAX_NETMASK(=%d) is not allowed\n", MAX_NETMASK);
     189           1 :                 return -EPERM;
     190             :         }
     191             : 
     192          18 :         len = strlen(mask);
     193          18 :         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          18 :         imask = iscsi_init_grp_find_netmask(ig, mask);
     199          18 :         if (imask != NULL) {
     200           2 :                 return -EEXIST;
     201             :         }
     202             : 
     203          16 :         imask = calloc(1, sizeof(*imask));
     204          16 :         if (imask == NULL) {
     205           0 :                 SPDK_ERRLOG("malloc() failed for initiator mask str\n");
     206           0 :                 return -ENOMEM;
     207             :         }
     208             : 
     209          16 :         memcpy(imask->mask, mask, len);
     210             : 
     211             :         /* Replace "ALL" by "ANY" if set */
     212          16 :         p = strstr(imask->mask, "ALL");
     213          16 :         if (p != NULL) {
     214           1 :                 SPDK_WARNLOG("Please use \"%s\" instead of \"%s\"\n", "ANY", "ALL");
     215           1 :                 SPDK_WARNLOG("Converting \"%s\" to \"%s\" automatically\n", "ALL", "ANY");
     216           1 :                 memcpy(p, "ANY", 3);
     217           1 :         }
     218             : 
     219          16 :         TAILQ_INSERT_TAIL(&ig->netmask_head, imask, tailq);
     220          16 :         ig->nnetmasks++;
     221             : 
     222          16 :         SPDK_DEBUGLOG(iscsi, "Netmask %s\n", mask);
     223          16 :         return 0;
     224          19 : }
     225             : 
     226             : static int
     227          15 : iscsi_init_grp_delete_netmask(struct spdk_iscsi_init_grp *ig, char *mask)
     228             : {
     229             :         struct spdk_iscsi_initiator_netmask *imask;
     230             : 
     231          15 :         imask = iscsi_init_grp_find_netmask(ig, mask);
     232          15 :         if (imask == NULL) {
     233           1 :                 return -ENOENT;
     234             :         }
     235             : 
     236          14 :         TAILQ_REMOVE(&ig->netmask_head, imask, tailq);
     237          14 :         ig->nnetmasks--;
     238          14 :         free(imask);
     239          14 :         return 0;
     240          15 : }
     241             : 
     242             : static int
     243           3 : 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          11 :         for (i = 0; i < num_imasks; i++) {
     249           9 :                 rc = iscsi_init_grp_add_netmask(ig, imasks[i]);
     250           9 :                 if (rc != 0) {
     251           1 :                         goto cleanup;
     252             :                 }
     253           8 :         }
     254           2 :         return 0;
     255             : 
     256             : cleanup:
     257           3 :         for (; i > 0; --i) {
     258           2 :                 iscsi_init_grp_delete_netmask(ig, imasks[i - 1]);
     259           2 :         }
     260           1 :         return rc;
     261           3 : }
     262             : 
     263             : static void
     264          18 : iscsi_init_grp_delete_all_netmasks(struct spdk_iscsi_init_grp *ig)
     265             : {
     266             :         struct spdk_iscsi_initiator_netmask *imask, *tmp;
     267             : 
     268          20 :         TAILQ_FOREACH_SAFE(imask, &ig->netmask_head, tailq, tmp) {
     269           2 :                 TAILQ_REMOVE(&ig->netmask_head, imask, tailq);
     270           2 :                 ig->nnetmasks--;
     271           2 :                 free(imask);
     272           2 :         }
     273          18 : }
     274             : 
     275             : static int
     276           3 : 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          11 :         for (i = 0; i < num_imasks; i++) {
     282           9 :                 rc = iscsi_init_grp_delete_netmask(ig, imasks[i]);
     283           9 :                 if (rc != 0) {
     284           1 :                         goto cleanup;
     285             :                 }
     286           8 :         }
     287           2 :         return 0;
     288             : 
     289             : cleanup:
     290           3 :         for (; i > 0; --i) {
     291           2 :                 rc = iscsi_init_grp_add_netmask(ig, imasks[i - 1]);
     292           2 :                 if (rc != 0) {
     293           0 :                         iscsi_init_grp_delete_all_netmasks(ig);
     294           0 :                         break;
     295             :                 }
     296           2 :         }
     297           1 :         return -1;
     298           3 : }
     299             : 
     300             : int
     301           3 : iscsi_init_grp_register(struct spdk_iscsi_init_grp *ig)
     302             : {
     303             :         struct spdk_iscsi_init_grp *tmp;
     304           3 :         int rc = -1;
     305             : 
     306           3 :         assert(ig != NULL);
     307             : 
     308           3 :         pthread_mutex_lock(&g_iscsi.mutex);
     309           3 :         tmp = iscsi_init_grp_find_by_tag(ig->tag);
     310           3 :         if (tmp == NULL) {
     311           2 :                 TAILQ_INSERT_TAIL(&g_iscsi.ig_head, ig, tailq);
     312           2 :                 rc = 0;
     313           2 :         }
     314           3 :         pthread_mutex_unlock(&g_iscsi.mutex);
     315             : 
     316           3 :         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           0 : 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           0 :         int rc = -1;
     332           0 :         struct spdk_iscsi_init_grp *ig = NULL;
     333             : 
     334           0 :         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           0 :         ig = iscsi_init_grp_create(tag);
     339           0 :         if (!ig) {
     340           0 :                 SPDK_ERRLOG("initiator group create error (%d)\n", tag);
     341           0 :                 return rc;
     342             :         }
     343             : 
     344           0 :         rc = iscsi_init_grp_add_initiators(ig, num_initiator_names,
     345           0 :                                            initiator_names);
     346           0 :         if (rc < 0) {
     347           0 :                 SPDK_ERRLOG("add initiator name error\n");
     348           0 :                 goto cleanup;
     349             :         }
     350             : 
     351           0 :         rc = iscsi_init_grp_add_netmasks(ig, num_initiator_masks,
     352           0 :                                          initiator_masks);
     353           0 :         if (rc < 0) {
     354           0 :                 SPDK_ERRLOG("add initiator netmask error\n");
     355           0 :                 goto cleanup;
     356             :         }
     357             : 
     358           0 :         rc = iscsi_init_grp_register(ig);
     359           0 :         if (rc < 0) {
     360           0 :                 SPDK_ERRLOG("initiator group register error (%d)\n", tag);
     361           0 :                 goto cleanup;
     362             :         }
     363           0 :         return 0;
     364             : 
     365             : cleanup:
     366           0 :         iscsi_init_grp_destroy(ig);
     367           0 :         return rc;
     368           0 : }
     369             : 
     370             : int
     371           0 : 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           0 :         int rc = -1;
     378             :         struct spdk_iscsi_init_grp *ig;
     379             : 
     380           0 :         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           0 :         pthread_mutex_lock(&g_iscsi.mutex);
     385           0 :         ig = iscsi_init_grp_find_by_tag(tag);
     386           0 :         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           0 :         rc = iscsi_init_grp_add_initiators(ig, num_initiator_names,
     393           0 :                                            initiator_names);
     394           0 :         if (rc < 0) {
     395           0 :                 SPDK_ERRLOG("add initiator name error\n");
     396           0 :                 goto error;
     397             :         }
     398             : 
     399           0 :         rc = iscsi_init_grp_add_netmasks(ig, num_initiator_masks,
     400           0 :                                          initiator_masks);
     401           0 :         if (rc < 0) {
     402           0 :                 SPDK_ERRLOG("add initiator netmask error\n");
     403           0 :                 iscsi_init_grp_delete_initiators(ig, num_initiator_names,
     404           0 :                                                  initiator_names);
     405           0 :         }
     406             : 
     407             : error:
     408           0 :         pthread_mutex_unlock(&g_iscsi.mutex);
     409           0 :         return rc;
     410           0 : }
     411             : 
     412             : int
     413           0 : 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           0 :         int rc = -1;
     420             :         struct spdk_iscsi_init_grp *ig;
     421             : 
     422           0 :         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           0 :         pthread_mutex_lock(&g_iscsi.mutex);
     427           0 :         ig = iscsi_init_grp_find_by_tag(tag);
     428           0 :         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           0 :         rc = iscsi_init_grp_delete_initiators(ig, num_initiator_names,
     435           0 :                                               initiator_names);
     436           0 :         if (rc < 0) {
     437           0 :                 SPDK_ERRLOG("delete initiator name error\n");
     438           0 :                 goto error;
     439             :         }
     440             : 
     441           0 :         rc = iscsi_init_grp_delete_netmasks(ig, num_initiator_masks,
     442           0 :                                             initiator_masks);
     443           0 :         if (rc < 0) {
     444           0 :                 SPDK_ERRLOG("delete initiator netmask error\n");
     445           0 :                 iscsi_init_grp_add_initiators(ig, num_initiator_names,
     446           0 :                                               initiator_names);
     447           0 :                 goto error;
     448             :         }
     449             : 
     450             : error:
     451           0 :         pthread_mutex_unlock(&g_iscsi.mutex);
     452           0 :         return rc;
     453           0 : }
     454             : 
     455             : void
     456          17 : iscsi_init_grp_destroy(struct spdk_iscsi_init_grp *ig)
     457             : {
     458          17 :         if (!ig) {
     459           0 :                 return;
     460             :         }
     461             : 
     462          17 :         iscsi_init_grp_delete_all_initiators(ig);
     463          17 :         iscsi_init_grp_delete_all_netmasks(ig);
     464          17 :         free(ig);
     465          17 : };
     466             : 
     467             : struct spdk_iscsi_init_grp *
     468           7 : iscsi_init_grp_find_by_tag(int tag)
     469             : {
     470             :         struct spdk_iscsi_init_grp *ig;
     471             : 
     472           7 :         TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
     473           3 :                 if (ig->tag == tag) {
     474           3 :                         return ig;
     475             :                 }
     476           0 :         }
     477             : 
     478           4 :         return NULL;
     479           7 : }
     480             : 
     481             : void
     482           0 : iscsi_init_grps_destroy(void)
     483             : {
     484             :         struct spdk_iscsi_init_grp *ig, *tmp;
     485             : 
     486           0 :         SPDK_DEBUGLOG(iscsi, "iscsi_init_grp_array_destroy\n");
     487           0 :         pthread_mutex_lock(&g_iscsi.mutex);
     488           0 :         TAILQ_FOREACH_SAFE(ig, &g_iscsi.ig_head, tailq, tmp) {
     489           0 :                 TAILQ_REMOVE(&g_iscsi.ig_head, ig, tailq);
     490           0 :                 iscsi_init_grp_destroy(ig);
     491           0 :         }
     492           0 :         pthread_mutex_unlock(&g_iscsi.mutex);
     493           0 : }
     494             : 
     495             : struct spdk_iscsi_init_grp *
     496           2 : iscsi_init_grp_unregister(int tag)
     497             : {
     498             :         struct spdk_iscsi_init_grp *ig;
     499             : 
     500           2 :         pthread_mutex_lock(&g_iscsi.mutex);
     501           2 :         TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
     502           2 :                 if (ig->tag == tag) {
     503           2 :                         TAILQ_REMOVE(&g_iscsi.ig_head, ig, tailq);
     504           2 :                         pthread_mutex_unlock(&g_iscsi.mutex);
     505           2 :                         return ig;
     506             :                 }
     507           0 :         }
     508           0 :         pthread_mutex_unlock(&g_iscsi.mutex);
     509           0 :         return NULL;
     510           2 : }
     511             : 
     512             : static void
     513           0 : 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           0 :         spdk_json_write_object_begin(w);
     520             : 
     521           0 :         spdk_json_write_named_int32(w, "tag", ig->tag);
     522             : 
     523           0 :         spdk_json_write_named_array_begin(w, "initiators");
     524           0 :         TAILQ_FOREACH(iname, &ig->initiator_head, tailq) {
     525           0 :                 spdk_json_write_string(w, iname->name);
     526           0 :         }
     527           0 :         spdk_json_write_array_end(w);
     528             : 
     529           0 :         spdk_json_write_named_array_begin(w, "netmasks");
     530           0 :         TAILQ_FOREACH(imask, &ig->netmask_head, tailq) {
     531           0 :                 spdk_json_write_string(w, imask->mask);
     532           0 :         }
     533           0 :         spdk_json_write_array_end(w);
     534             : 
     535           0 :         spdk_json_write_object_end(w);
     536           0 : }
     537             : 
     538             : static void
     539           0 : iscsi_init_grp_config_json(struct spdk_iscsi_init_grp *ig,
     540             :                            struct spdk_json_write_ctx *w)
     541             : {
     542           0 :         spdk_json_write_object_begin(w);
     543             : 
     544           0 :         spdk_json_write_named_string(w, "method", "iscsi_create_initiator_group");
     545             : 
     546           0 :         spdk_json_write_name(w, "params");
     547           0 :         iscsi_init_grp_info_json(ig, w);
     548             : 
     549           0 :         spdk_json_write_object_end(w);
     550           0 : }
     551             : 
     552             : void
     553           0 : iscsi_init_grps_info_json(struct spdk_json_write_ctx *w)
     554             : {
     555             :         struct spdk_iscsi_init_grp *ig;
     556             : 
     557           0 :         TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
     558           0 :                 iscsi_init_grp_info_json(ig, w);
     559           0 :         }
     560           0 : }
     561             : 
     562             : void
     563           0 : iscsi_init_grps_config_json(struct spdk_json_write_ctx *w)
     564             : {
     565             :         struct spdk_iscsi_init_grp *ig;
     566             : 
     567           0 :         TAILQ_FOREACH(ig, &g_iscsi.ig_head, tailq) {
     568           0 :                 iscsi_init_grp_config_json(ig, w);
     569           0 :         }
     570           0 : }

Generated by: LCOV version 1.15