LCOV - code coverage report
Current view: top level - spdk/lib/iscsi - portal_grp.c (source / functions) Hit Total Coverage
Test: Combined Lines: 202 250 80.8 %
Date: 2024-07-14 00:44:13 Functions: 23 27 85.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 130 222 58.6 %

           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/sock.h"
      10                 :            : #include "spdk/string.h"
      11                 :            : 
      12                 :            : #include "spdk/log.h"
      13                 :            : 
      14                 :            : #include "iscsi/iscsi.h"
      15                 :            : #include "iscsi/conn.h"
      16                 :            : #include "iscsi/portal_grp.h"
      17                 :            : #include "iscsi/tgt_node.h"
      18                 :            : 
      19                 :            : #define PORTNUMSTRLEN 32
      20                 :            : #define ACCEPT_TIMEOUT_US 1000 /* 1ms */
      21                 :            : 
      22                 :            : static int
      23                 :    2221068 : iscsi_portal_accept(void *arg)
      24                 :            : {
      25                 :    2221068 :         struct spdk_iscsi_portal        *portal = arg;
      26                 :          0 :         struct spdk_sock                *sock;
      27                 :            :         int                             rc;
      28                 :    2221068 :         int                             count = 0;
      29                 :            : 
      30         [ -  + ]:    2221068 :         if (portal->sock == NULL) {
      31                 :          0 :                 return -1;
      32                 :            :         }
      33                 :            : 
      34                 :            :         while (1) {
      35                 :    2221643 :                 sock = spdk_sock_accept(portal->sock);
      36         [ +  + ]:    2221643 :                 if (sock != NULL) {
      37                 :        575 :                         rc = iscsi_conn_construct(portal, sock);
      38         [ -  + ]:        575 :                         if (rc < 0) {
      39                 :          0 :                                 spdk_sock_close(&sock);
      40                 :          0 :                                 SPDK_ERRLOG("spdk_iscsi_connection_construct() failed\n");
      41                 :          0 :                                 break;
      42                 :            :                         }
      43                 :        575 :                         count++;
      44                 :            :                 } else {
      45   [ -  +  -  - ]:    2221068 :                         if (errno != EAGAIN && errno != EWOULDBLOCK) {
      46                 :          0 :                                 SPDK_ERRLOG("accept error(%d): %s\n", errno, spdk_strerror(errno));
      47                 :            :                         }
      48                 :    2221068 :                         break;
      49                 :            :                 }
      50                 :            :         }
      51                 :            : 
      52                 :    2221068 :         return count;
      53                 :            : }
      54                 :            : 
      55                 :            : static struct spdk_iscsi_portal *
      56                 :        124 : iscsi_portal_find_by_addr(const char *host, const char *port)
      57                 :            : {
      58                 :            :         struct spdk_iscsi_portal *p;
      59                 :            : 
      60         [ +  + ]:        138 :         TAILQ_FOREACH(p, &g_iscsi.portal_head, g_tailq) {
      61   [ +  +  +  +  :         20 :                 if (!strcmp(p->host, host) && !strcmp(p->port, port)) {
          +  +  -  +  -  
                +  +  + ]
      62                 :          6 :                         return p;
      63                 :            :                 }
      64                 :            :         }
      65                 :            : 
      66                 :        118 :         return NULL;
      67                 :            : }
      68                 :            : 
      69                 :            : /* Assumes caller allocated host and port strings on the heap */
      70                 :            : struct spdk_iscsi_portal *
      71                 :        124 : iscsi_portal_create(const char *host, const char *port)
      72                 :            : {
      73                 :        124 :         struct spdk_iscsi_portal *p = NULL, *tmp;
      74                 :            : 
      75         [ -  + ]:        124 :         assert(host != NULL);
      76         [ -  + ]:        124 :         assert(port != NULL);
      77                 :            : 
      78   [ +  +  +  +  :        124 :         if (strlen(host) > MAX_PORTAL_ADDR || strlen(port) > MAX_PORTAL_PORT) {
             -  +  -  + ]
      79                 :          0 :                 return NULL;
      80                 :            :         }
      81                 :            : 
      82                 :        124 :         p = calloc(1, sizeof(*p));
      83         [ -  + ]:        124 :         if (!p) {
      84                 :          0 :                 SPDK_ERRLOG("calloc() failed for portal\n");
      85                 :          0 :                 return NULL;
      86                 :            :         }
      87                 :            : 
      88                 :            :         /* check and overwrite abbreviation of wildcard */
      89   [ +  +  +  + ]:        124 :         if (strcasecmp(host, "[*]") == 0) {
      90                 :          6 :                 SPDK_WARNLOG("Please use \"[::]\" as IPv6 wildcard\n");
      91                 :          6 :                 SPDK_WARNLOG("Convert \"[*]\" to \"[::]\" automatically\n");
      92                 :          6 :                 SPDK_WARNLOG("(Use of \"[*]\" will be deprecated in a future release)");
      93                 :          6 :                 snprintf(p->host, sizeof(p->host), "[::]");
      94   [ +  +  +  + ]:        118 :         } else if (strcasecmp(host, "*") == 0) {
      95                 :          6 :                 SPDK_WARNLOG("Please use \"0.0.0.0\" as IPv4 wildcard\n");
      96                 :          6 :                 SPDK_WARNLOG("Convert \"*\" to \"0.0.0.0\" automatically\n");
      97                 :          6 :                 SPDK_WARNLOG("(Use of \"[*]\" will be deprecated in a future release)");
      98                 :          6 :                 snprintf(p->host, sizeof(p->host), "0.0.0.0");
      99                 :            :         } else {
     100   [ -  +  -  +  :        112 :                 memcpy(p->host, host, strlen(host));
                   -  + ]
     101                 :            :         }
     102                 :            : 
     103   [ -  +  -  +  :        124 :         memcpy(p->port, port, strlen(port));
                   -  + ]
     104                 :            : 
     105                 :        124 :         p->sock = NULL;
     106                 :        124 :         p->group = NULL; /* set at a later time by caller */
     107                 :        124 :         p->acceptor_poller = NULL;
     108                 :            : 
     109         [ -  + ]:        124 :         pthread_mutex_lock(&g_iscsi.mutex);
     110                 :        124 :         tmp = iscsi_portal_find_by_addr(host, port);
     111         [ +  + ]:        124 :         if (tmp != NULL) {
     112         [ #  # ]:          6 :                 pthread_mutex_unlock(&g_iscsi.mutex);
     113                 :          6 :                 SPDK_ERRLOG("portal (%s, %s) already exists\n", host, port);
     114                 :          6 :                 goto error_out;
     115                 :            :         }
     116                 :            : 
     117                 :        118 :         TAILQ_INSERT_TAIL(&g_iscsi.portal_head, p, g_tailq);
     118         [ -  + ]:        118 :         pthread_mutex_unlock(&g_iscsi.mutex);
     119                 :            : 
     120                 :        118 :         return p;
     121                 :            : 
     122                 :          6 : error_out:
     123                 :          6 :         free(p);
     124                 :            : 
     125                 :          6 :         return NULL;
     126                 :            : }
     127                 :            : 
     128                 :            : void
     129                 :        118 : iscsi_portal_destroy(struct spdk_iscsi_portal *p)
     130                 :            : {
     131         [ -  + ]:        118 :         assert(p != NULL);
     132                 :            : 
     133   [ -  +  -  + ]:        118 :         SPDK_DEBUGLOG(iscsi, "iscsi_portal_destroy\n");
     134                 :            : 
     135         [ -  + ]:        118 :         pthread_mutex_lock(&g_iscsi.mutex);
     136         [ +  + ]:        118 :         TAILQ_REMOVE(&g_iscsi.portal_head, p, g_tailq);
     137         [ -  + ]:        118 :         pthread_mutex_unlock(&g_iscsi.mutex);
     138                 :            : 
     139                 :        118 :         free(p);
     140                 :            : 
     141                 :        118 : }
     142                 :            : 
     143                 :            : static int
     144                 :         76 : iscsi_portal_open(struct spdk_iscsi_portal *p)
     145                 :            : {
     146                 :            :         struct spdk_sock *sock;
     147                 :            :         int port;
     148                 :            : 
     149         [ -  + ]:         76 :         if (p->sock != NULL) {
     150                 :          0 :                 SPDK_ERRLOG("portal (%s, %s) is already opened\n",
     151                 :            :                             p->host, p->port);
     152                 :          0 :                 return -1;
     153                 :            :         }
     154                 :            : 
     155         [ -  + ]:         76 :         port = (int)strtol(p->port, NULL, 0);
     156   [ +  -  -  + ]:         76 :         if (port <= 0 || port > 65535) {
     157                 :          0 :                 SPDK_ERRLOG("invalid port %s\n", p->port);
     158                 :          0 :                 return -1;
     159                 :            :         }
     160                 :            : 
     161                 :         76 :         sock = spdk_sock_listen(p->host, port, NULL);
     162         [ -  + ]:         76 :         if (sock == NULL) {
     163                 :          0 :                 SPDK_ERRLOG("listen error %.64s.%d\n", p->host, port);
     164                 :          0 :                 return -1;
     165                 :            :         }
     166                 :            : 
     167                 :         76 :         p->sock = sock;
     168                 :            : 
     169                 :            :         /*
     170                 :            :          * When the portal is created by config file, incoming connection
     171                 :            :          * requests for the socket are pended to accept until reactors start.
     172                 :            :          * However the gap between listen() and accept() will be slight and
     173                 :            :          * the requests will be queued by the nonzero backlog of the socket
     174                 :            :          * or resend by TCP.
     175                 :            :          */
     176                 :         76 :         p->acceptor_poller = SPDK_POLLER_REGISTER(iscsi_portal_accept, p, ACCEPT_TIMEOUT_US);
     177                 :            : 
     178                 :         76 :         return 0;
     179                 :            : }
     180                 :            : 
     181                 :            : static void
     182                 :         76 : iscsi_portal_close(struct spdk_iscsi_portal *p)
     183                 :            : {
     184         [ +  - ]:         76 :         if (p->sock) {
     185   [ -  +  -  + ]:         76 :                 SPDK_DEBUGLOG(iscsi, "close portal (%s, %s)\n",
     186                 :            :                               p->host, p->port);
     187                 :         76 :                 spdk_poller_unregister(&p->acceptor_poller);
     188                 :         76 :                 spdk_sock_close(&p->sock);
     189                 :            :         }
     190                 :         76 : }
     191                 :            : 
     192                 :            : static void
     193                 :          0 : iscsi_portal_pause(struct spdk_iscsi_portal *p)
     194                 :            : {
     195         [ #  # ]:          0 :         assert(p->acceptor_poller != NULL);
     196                 :            : 
     197                 :          0 :         spdk_poller_pause(p->acceptor_poller);
     198                 :          0 : }
     199                 :            : 
     200                 :            : static void
     201                 :          0 : iscsi_portal_resume(struct spdk_iscsi_portal *p)
     202                 :            : {
     203         [ #  # ]:          0 :         assert(p->acceptor_poller != NULL);
     204                 :            : 
     205                 :          0 :         spdk_poller_resume(p->acceptor_poller);
     206                 :          0 : }
     207                 :            : 
     208                 :            : int
     209                 :          2 : iscsi_parse_redirect_addr(struct sockaddr_storage *sa,
     210                 :            :                           const char *host, const char *port)
     211                 :            : {
     212                 :          0 :         struct addrinfo hints, *res;
     213                 :            :         int rc;
     214                 :            : 
     215   [ +  -  -  + ]:          2 :         if (host == NULL || port == NULL) {
     216                 :          0 :                 return -EINVAL;
     217                 :            :         }
     218                 :            : 
     219         [ -  + ]:          2 :         memset(&hints, 0, sizeof(hints));
     220                 :          2 :         hints.ai_family = PF_UNSPEC;
     221                 :          2 :         hints.ai_socktype = SOCK_STREAM;
     222                 :          2 :         hints.ai_flags = AI_NUMERICSERV;
     223                 :          2 :         hints.ai_flags |= AI_NUMERICHOST;
     224                 :          2 :         rc = getaddrinfo(host, port, &hints, &res);
     225         [ -  + ]:          2 :         if (rc != 0) {
     226                 :          0 :                 SPDK_ERRLOG("getaddinrfo failed: %s (%d)\n", gai_strerror(rc), rc);
     227                 :          0 :                 return -(abs(rc));
     228                 :            :         }
     229                 :            : 
     230         [ -  + ]:          2 :         if (res->ai_addrlen > sizeof(*sa)) {
     231                 :          0 :                 SPDK_ERRLOG("getaddrinfo() ai_addrlen %zu too large\n",
     232                 :            :                             (size_t)res->ai_addrlen);
     233                 :          0 :                 rc = -EINVAL;
     234                 :            :         } else {
     235   [ -  +  -  + ]:          2 :                 memcpy(sa, res->ai_addr, res->ai_addrlen);
     236                 :            :         }
     237                 :            : 
     238                 :          2 :         freeaddrinfo(res);
     239                 :          2 :         return rc;
     240                 :            : }
     241                 :            : 
     242                 :            : struct spdk_iscsi_portal_grp *
     243                 :         86 : iscsi_portal_grp_create(int tag, bool is_private)
     244                 :            : {
     245                 :         86 :         struct spdk_iscsi_portal_grp *pg = malloc(sizeof(*pg));
     246                 :            : 
     247         [ -  + ]:         86 :         if (!pg) {
     248                 :          0 :                 SPDK_ERRLOG("malloc() failed for portal group\n");
     249                 :          0 :                 return NULL;
     250                 :            :         }
     251                 :            : 
     252                 :         86 :         pg->ref = 0;
     253                 :         86 :         pg->tag = tag;
     254                 :         86 :         pg->is_private = is_private;
     255                 :            : 
     256         [ -  + ]:         86 :         pthread_mutex_lock(&g_iscsi.mutex);
     257         [ -  + ]:         86 :         pg->disable_chap = g_iscsi.disable_chap;
     258         [ -  + ]:         86 :         pg->require_chap = g_iscsi.require_chap;
     259         [ -  + ]:         86 :         pg->mutual_chap = g_iscsi.mutual_chap;
     260                 :         86 :         pg->chap_group = g_iscsi.chap_group;
     261         [ -  + ]:         86 :         pthread_mutex_unlock(&g_iscsi.mutex);
     262                 :            : 
     263                 :         86 :         TAILQ_INIT(&pg->head);
     264                 :            : 
     265                 :         86 :         return pg;
     266                 :            : }
     267                 :            : 
     268                 :            : void
     269                 :         86 : iscsi_portal_grp_destroy(struct spdk_iscsi_portal_grp *pg)
     270                 :            : {
     271                 :            :         struct spdk_iscsi_portal        *p;
     272                 :            : 
     273         [ -  + ]:         86 :         assert(pg != NULL);
     274                 :            : 
     275   [ -  +  -  + ]:         86 :         SPDK_DEBUGLOG(iscsi, "iscsi_portal_grp_destroy\n");
     276         [ +  + ]:        174 :         while (!TAILQ_EMPTY(&pg->head)) {
     277                 :         88 :                 p = TAILQ_FIRST(&pg->head);
     278         [ +  + ]:         88 :                 TAILQ_REMOVE(&pg->head, p, per_pg_tailq);
     279                 :         88 :                 iscsi_portal_destroy(p);
     280                 :            :         }
     281                 :         86 :         free(pg);
     282                 :         86 : }
     283                 :            : 
     284                 :            : int
     285                 :         92 : iscsi_portal_grp_register(struct spdk_iscsi_portal_grp *pg)
     286                 :            : {
     287                 :         92 :         int rc = -1;
     288                 :            :         struct spdk_iscsi_portal_grp *tmp;
     289                 :            : 
     290         [ -  + ]:         92 :         assert(pg != NULL);
     291                 :            : 
     292         [ -  + ]:         92 :         pthread_mutex_lock(&g_iscsi.mutex);
     293                 :         92 :         tmp = iscsi_portal_grp_find_by_tag(pg->tag);
     294         [ +  + ]:         92 :         if (tmp == NULL) {
     295                 :         86 :                 TAILQ_INSERT_TAIL(&g_iscsi.pg_head, pg, tailq);
     296                 :         86 :                 rc = 0;
     297                 :            :         }
     298         [ -  + ]:         92 :         pthread_mutex_unlock(&g_iscsi.mutex);
     299                 :         92 :         return rc;
     300                 :            : }
     301                 :            : 
     302                 :            : void
     303                 :         88 : iscsi_portal_grp_add_portal(struct spdk_iscsi_portal_grp *pg,
     304                 :            :                             struct spdk_iscsi_portal *p)
     305                 :            : {
     306         [ -  + ]:         88 :         assert(pg != NULL);
     307         [ -  + ]:         88 :         assert(p != NULL);
     308                 :            : 
     309                 :         88 :         p->group = pg;
     310                 :         88 :         TAILQ_INSERT_TAIL(&pg->head, p, per_pg_tailq);
     311                 :         88 : }
     312                 :            : 
     313                 :            : struct spdk_iscsi_portal *
     314                 :          2 : iscsi_portal_grp_find_portal_by_addr(struct spdk_iscsi_portal_grp *pg,
     315                 :            :                                      const char *host, const char *port)
     316                 :            : {
     317                 :            :         struct spdk_iscsi_portal *p;
     318                 :            : 
     319         [ +  + ]:          4 :         TAILQ_FOREACH(p, &pg->head, per_pg_tailq) {
     320   [ -  +  -  +  :          2 :                 if (!strcmp(p->host, host) && !strcmp(p->port, port)) {
          -  +  -  -  -  
                -  -  - ]
     321                 :          0 :                         return p;
     322                 :            :                 }
     323                 :            :         }
     324                 :            : 
     325                 :          2 :         return NULL;
     326                 :            : }
     327                 :            : 
     328                 :            : int
     329                 :          0 : iscsi_portal_grp_set_chap_params(struct spdk_iscsi_portal_grp *pg,
     330                 :            :                                  bool disable_chap, bool require_chap,
     331                 :            :                                  bool mutual_chap, int32_t chap_group)
     332                 :            : {
     333         [ #  # ]:          0 :         if (!iscsi_check_chap_params(disable_chap, require_chap,
     334                 :            :                                      mutual_chap, chap_group)) {
     335                 :          0 :                 return -EINVAL;
     336                 :            :         }
     337                 :            : 
     338                 :          0 :         pg->disable_chap = disable_chap;
     339                 :          0 :         pg->require_chap = require_chap;
     340                 :          0 :         pg->mutual_chap = mutual_chap;
     341                 :          0 :         pg->chap_group = chap_group;
     342                 :            : 
     343                 :          0 :         return 0;
     344                 :            : }
     345                 :            : 
     346                 :            : struct spdk_iscsi_portal_grp *
     347                 :        266 : iscsi_portal_grp_find_by_tag(int tag)
     348                 :            : {
     349                 :            :         struct spdk_iscsi_portal_grp *pg;
     350                 :            : 
     351         [ +  + ]:        280 :         TAILQ_FOREACH(pg, &g_iscsi.pg_head, tailq) {
     352         [ +  + ]:        194 :                 if (pg->tag == tag) {
     353                 :        180 :                         return pg;
     354                 :            :                 }
     355                 :            :         }
     356                 :            : 
     357                 :         86 :         return NULL;
     358                 :            : }
     359                 :            : 
     360                 :            : void
     361                 :        658 : iscsi_portal_grps_destroy(void)
     362                 :            : {
     363                 :            :         struct spdk_iscsi_portal_grp *pg;
     364                 :            : 
     365   [ -  +  -  + ]:        658 :         SPDK_DEBUGLOG(iscsi, "iscsi_portal_grps_destroy\n");
     366         [ -  + ]:        658 :         pthread_mutex_lock(&g_iscsi.mutex);
     367         [ +  + ]:        710 :         while (!TAILQ_EMPTY(&g_iscsi.pg_head)) {
     368                 :         52 :                 pg = TAILQ_FIRST(&g_iscsi.pg_head);
     369         [ +  + ]:         52 :                 TAILQ_REMOVE(&g_iscsi.pg_head, pg, tailq);
     370         [ -  + ]:         52 :                 pthread_mutex_unlock(&g_iscsi.mutex);
     371                 :         52 :                 iscsi_portal_grp_destroy(pg);
     372         [ -  + ]:         52 :                 pthread_mutex_lock(&g_iscsi.mutex);
     373                 :            :         }
     374         [ -  + ]:        658 :         pthread_mutex_unlock(&g_iscsi.mutex);
     375                 :        658 : }
     376                 :            : 
     377                 :            : int
     378                 :         74 : iscsi_portal_grp_open(struct spdk_iscsi_portal_grp *pg, bool pause)
     379                 :            : {
     380                 :            :         struct spdk_iscsi_portal *p;
     381                 :            :         int rc;
     382                 :            : 
     383         [ +  + ]:        150 :         TAILQ_FOREACH(p, &pg->head, per_pg_tailq) {
     384                 :         76 :                 rc = iscsi_portal_open(p);
     385         [ -  + ]:         76 :                 if (rc < 0) {
     386                 :          0 :                         return rc;
     387                 :            :                 }
     388                 :            : 
     389         [ -  + ]:         76 :                 if (pause) {
     390                 :          0 :                         iscsi_portal_pause(p);
     391                 :            :                 }
     392                 :            :         }
     393                 :         74 :         return 0;
     394                 :            : }
     395                 :            : 
     396                 :            : static void
     397                 :         74 : iscsi_portal_grp_close(struct spdk_iscsi_portal_grp *pg)
     398                 :            : {
     399                 :            :         struct spdk_iscsi_portal *p;
     400                 :            : 
     401         [ +  + ]:        150 :         TAILQ_FOREACH(p, &pg->head, per_pg_tailq) {
     402                 :         76 :                 iscsi_portal_close(p);
     403                 :            :         }
     404                 :         74 : }
     405                 :            : 
     406                 :            : void
     407                 :          0 : iscsi_portal_grp_resume(struct spdk_iscsi_portal_grp *pg)
     408                 :            : {
     409                 :            :         struct spdk_iscsi_portal *p;
     410                 :            : 
     411         [ #  # ]:          0 :         TAILQ_FOREACH(p, &pg->head, per_pg_tailq) {
     412                 :          0 :                 iscsi_portal_resume(p);
     413                 :            :         }
     414                 :          0 : }
     415                 :            : 
     416                 :            : void
     417                 :        652 : iscsi_portal_grp_close_all(void)
     418                 :            : {
     419                 :            :         struct spdk_iscsi_portal_grp *pg;
     420                 :            : 
     421   [ -  +  -  + ]:        652 :         SPDK_DEBUGLOG(iscsi, "iscsi_portal_grp_close_all\n");
     422         [ -  + ]:        652 :         pthread_mutex_lock(&g_iscsi.mutex);
     423         [ +  + ]:        692 :         TAILQ_FOREACH(pg, &g_iscsi.pg_head, tailq) {
     424                 :         40 :                 iscsi_portal_grp_close(pg);
     425                 :            :         }
     426         [ -  + ]:        652 :         pthread_mutex_unlock(&g_iscsi.mutex);
     427                 :        652 : }
     428                 :            : 
     429                 :            : struct spdk_iscsi_portal_grp *
     430                 :         34 : iscsi_portal_grp_unregister(int tag)
     431                 :            : {
     432                 :            :         struct spdk_iscsi_portal_grp *pg;
     433                 :            : 
     434         [ -  + ]:         34 :         pthread_mutex_lock(&g_iscsi.mutex);
     435         [ +  - ]:         34 :         TAILQ_FOREACH(pg, &g_iscsi.pg_head, tailq) {
     436         [ +  - ]:         34 :                 if (pg->tag == tag) {
     437         [ +  + ]:         34 :                         TAILQ_REMOVE(&g_iscsi.pg_head, pg, tailq);
     438         [ -  + ]:         34 :                         pthread_mutex_unlock(&g_iscsi.mutex);
     439                 :         34 :                         return pg;
     440                 :            :                 }
     441                 :            :         }
     442         [ #  # ]:          0 :         pthread_mutex_unlock(&g_iscsi.mutex);
     443                 :          0 :         return NULL;
     444                 :            : }
     445                 :            : 
     446                 :            : void
     447                 :         22 : iscsi_portal_grp_release(struct spdk_iscsi_portal_grp *pg)
     448                 :            : {
     449                 :         22 :         iscsi_portal_grp_close(pg);
     450                 :         22 :         iscsi_portal_grp_destroy(pg);
     451                 :         22 : }
     452                 :            : 
     453                 :            : static void
     454                 :        128 : iscsi_portal_grp_info_json(struct spdk_iscsi_portal_grp *pg,
     455                 :            :                            struct spdk_json_write_ctx *w)
     456                 :            : {
     457                 :            :         struct spdk_iscsi_portal *portal;
     458                 :            : 
     459                 :        128 :         spdk_json_write_object_begin(w);
     460                 :            : 
     461                 :        128 :         spdk_json_write_named_int32(w, "tag", pg->tag);
     462                 :            : 
     463                 :        128 :         spdk_json_write_named_array_begin(w, "portals");
     464         [ +  + ]:        312 :         TAILQ_FOREACH(portal, &pg->head, per_pg_tailq) {
     465                 :        184 :                 spdk_json_write_object_begin(w);
     466                 :            : 
     467                 :        184 :                 spdk_json_write_named_string(w, "host", portal->host);
     468                 :        184 :                 spdk_json_write_named_string(w, "port", portal->port);
     469                 :            : 
     470                 :        184 :                 spdk_json_write_object_end(w);
     471                 :            :         }
     472                 :        128 :         spdk_json_write_array_end(w);
     473                 :            : 
     474         [ -  + ]:        128 :         spdk_json_write_named_bool(w, "private", pg->is_private);
     475                 :            : 
     476                 :        128 :         spdk_json_write_object_end(w);
     477                 :        128 : }
     478                 :            : 
     479                 :            : static void
     480                 :          8 : iscsi_portal_grp_config_json(struct spdk_iscsi_portal_grp *pg,
     481                 :            :                              struct spdk_json_write_ctx *w)
     482                 :            : {
     483                 :          8 :         spdk_json_write_object_begin(w);
     484                 :            : 
     485                 :          8 :         spdk_json_write_named_string(w, "method", "iscsi_create_portal_group");
     486                 :            : 
     487                 :          8 :         spdk_json_write_name(w, "params");
     488                 :          8 :         iscsi_portal_grp_info_json(pg, w);
     489                 :            : 
     490                 :          8 :         spdk_json_write_object_end(w);
     491                 :          8 : }
     492                 :            : 
     493                 :            : void
     494                 :        136 : iscsi_portal_grps_info_json(struct spdk_json_write_ctx *w)
     495                 :            : {
     496                 :            :         struct spdk_iscsi_portal_grp *pg;
     497                 :            : 
     498         [ +  + ]:        256 :         TAILQ_FOREACH(pg, &g_iscsi.pg_head, tailq) {
     499                 :        120 :                 iscsi_portal_grp_info_json(pg, w);
     500                 :            :         }
     501                 :        136 : }
     502                 :            : 
     503                 :            : void
     504                 :        106 : iscsi_portal_grps_config_json(struct spdk_json_write_ctx *w)
     505                 :            : {
     506                 :            :         struct spdk_iscsi_portal_grp *pg;
     507                 :            : 
     508         [ +  + ]:        114 :         TAILQ_FOREACH(pg, &g_iscsi.pg_head, tailq) {
     509                 :          8 :                 iscsi_portal_grp_config_json(pg, w);
     510                 :            :         }
     511                 :        106 : }

Generated by: LCOV version 1.14