LCOV - code coverage report
Current view: top level - spdk/lib/iscsi - iscsi_subsystem.c (source / functions) Hit Total Coverage
Test: Combined Lines: 504 706 71.4 %
Date: 2024-07-12 23:21:00 Functions: 51 54 94.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 242 512 47.3 %

           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/string.h"
       8                 :            : #include "spdk/likely.h"
       9                 :            : 
      10                 :            : #include "iscsi/iscsi.h"
      11                 :            : #include "iscsi/init_grp.h"
      12                 :            : #include "iscsi/portal_grp.h"
      13                 :            : #include "iscsi/conn.h"
      14                 :            : #include "iscsi/task.h"
      15                 :            : #include "iscsi/tgt_node.h"
      16                 :            : 
      17                 :            : #include "spdk/log.h"
      18                 :            : 
      19                 :            : struct spdk_iscsi_opts *g_spdk_iscsi_opts = NULL;
      20                 :            : 
      21                 :            : static struct spdk_thread *g_init_thread = NULL;
      22                 :            : static spdk_iscsi_init_cb g_init_cb_fn = NULL;
      23                 :            : static void *g_init_cb_arg = NULL;
      24                 :            : 
      25                 :            : static spdk_iscsi_fini_cb g_fini_cb_fn;
      26                 :            : static void *g_fini_cb_arg;
      27                 :            : 
      28                 :            : #define ISCSI_DATA_BUFFER_ALIGNMENT     (0x1000)
      29                 :            : #define ISCSI_DATA_BUFFER_MASK          (ISCSI_DATA_BUFFER_ALIGNMENT - 1)
      30                 :            : 
      31                 :            : static void
      32                 :   11077632 : mobj_ctor(struct spdk_mempool *mp, __attribute__((unused)) void *arg,
      33                 :            :           void *_m, __attribute__((unused)) unsigned i)
      34                 :            : {
      35                 :   11077632 :         struct spdk_mobj *m = _m;
      36                 :            : 
      37                 :   11077632 :         m->mp = mp;
      38                 :   11077632 :         m->buf = (uint8_t *)m + sizeof(struct spdk_mobj);
      39                 :   11077632 :         m->buf = (void *)((uintptr_t)((uint8_t *)m->buf + ISCSI_DATA_BUFFER_ALIGNMENT) &
      40                 :            :                           ~ISCSI_DATA_BUFFER_MASK);
      41                 :   11077632 : }
      42                 :            : 
      43                 :            : static int
      44                 :        601 : iscsi_initialize_pdu_pool(void)
      45                 :            : {
      46                 :        601 :         struct spdk_iscsi_globals *iscsi = &g_iscsi;
      47                 :        601 :         int imm_mobj_size = SPDK_BDEV_BUF_SIZE_WITH_MD(iscsi_get_max_immediate_data_size()) +
      48                 :        601 :                             sizeof(struct spdk_mobj) + ISCSI_DATA_BUFFER_ALIGNMENT;
      49                 :        601 :         int dout_mobj_size = SPDK_BDEV_BUF_SIZE_WITH_MD(SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH) +
      50                 :            :                              sizeof(struct spdk_mobj) + ISCSI_DATA_BUFFER_ALIGNMENT;
      51                 :            : 
      52                 :            :         /* create PDU pool */
      53                 :        710 :         iscsi->pdu_pool = spdk_mempool_create("PDU_Pool",
      54                 :        601 :                                               iscsi->pdu_pool_size,
      55                 :            :                                               sizeof(struct spdk_iscsi_pdu),
      56                 :            :                                               256, SPDK_ENV_SOCKET_ID_ANY);
      57         [ -  + ]:        601 :         if (!iscsi->pdu_pool) {
      58         [ #  # ]:          0 :                 if (spdk_mempool_lookup("PDU_Pool") != NULL) {
      59                 :          0 :                         SPDK_ERRLOG("Cannot create PDU pool: already exists\n");
      60                 :          0 :                         SPDK_ERRLOG("Probably running in multiprocess environment, which is "
      61                 :            :                                     "unsupported by the iSCSI library\n");
      62                 :            :                 } else {
      63                 :          0 :                         SPDK_ERRLOG("create PDU pool failed\n");
      64                 :            :                 }
      65                 :          0 :                 return -1;
      66                 :            :         }
      67                 :            : 
      68                 :        710 :         iscsi->pdu_immediate_data_pool = spdk_mempool_create_ctor("PDU_immediate_data_Pool",
      69                 :        601 :                                          iscsi->immediate_data_pool_size,
      70                 :            :                                          imm_mobj_size, 256,
      71                 :            :                                          SPDK_ENV_SOCKET_ID_ANY,
      72                 :            :                                          mobj_ctor, NULL);
      73         [ -  + ]:        601 :         if (!iscsi->pdu_immediate_data_pool) {
      74                 :          0 :                 SPDK_ERRLOG("create PDU immediate data pool failed\n");
      75                 :          0 :                 return -1;
      76                 :            :         }
      77                 :            : 
      78                 :        710 :         iscsi->pdu_data_out_pool = spdk_mempool_create_ctor("PDU_data_out_Pool",
      79                 :        601 :                                    iscsi->data_out_pool_size,
      80                 :            :                                    dout_mobj_size, 256,
      81                 :            :                                    SPDK_ENV_SOCKET_ID_ANY,
      82                 :            :                                    mobj_ctor, NULL);
      83         [ -  + ]:        601 :         if (!iscsi->pdu_data_out_pool) {
      84                 :          0 :                 SPDK_ERRLOG("create PDU data out pool failed\n");
      85                 :          0 :                 return -1;
      86                 :            :         }
      87                 :            : 
      88                 :        601 :         return 0;
      89                 :            : }
      90                 :            : 
      91                 :            : static void
      92                 :      73808 : iscsi_sess_ctor(struct spdk_mempool *pool, void *arg, void *session_buf,
      93                 :            :                 unsigned index)
      94                 :            : {
      95                 :      73808 :         struct spdk_iscsi_globals               *iscsi = arg;
      96                 :      73808 :         struct spdk_iscsi_sess  *sess = session_buf;
      97                 :            : 
      98                 :      73808 :         iscsi->session[index] = sess;
      99                 :            : 
     100                 :            :         /* tsih 0 is reserved, so start tsih values at 1. */
     101                 :      73808 :         sess->tsih = index + 1;
     102                 :      73808 : }
     103                 :            : 
     104                 :            : #define DEFAULT_TASK_POOL_SIZE 32768
     105                 :            : 
     106                 :            : static int
     107                 :        601 : iscsi_initialize_task_pool(void)
     108                 :            : {
     109                 :        601 :         struct spdk_iscsi_globals *iscsi = &g_iscsi;
     110                 :            : 
     111                 :            :         /* create scsi_task pool */
     112                 :        601 :         iscsi->task_pool = spdk_mempool_create("SCSI_TASK_Pool",
     113                 :            :                                                DEFAULT_TASK_POOL_SIZE,
     114                 :            :                                                sizeof(struct spdk_iscsi_task),
     115                 :            :                                                128, SPDK_ENV_SOCKET_ID_ANY);
     116         [ -  + ]:        601 :         if (!iscsi->task_pool) {
     117                 :          0 :                 SPDK_ERRLOG("create task pool failed\n");
     118                 :          0 :                 return -1;
     119                 :            :         }
     120                 :            : 
     121                 :        601 :         return 0;
     122                 :            : }
     123                 :            : 
     124                 :            : #define SESSION_POOL_SIZE(iscsi)        (iscsi->MaxSessions)
     125                 :            : static int
     126                 :        601 : iscsi_initialize_session_pool(void)
     127                 :            : {
     128                 :        601 :         struct spdk_iscsi_globals *iscsi = &g_iscsi;
     129                 :            : 
     130                 :        710 :         iscsi->session_pool = spdk_mempool_create_ctor("Session_Pool",
     131                 :        601 :                               SESSION_POOL_SIZE(iscsi),
     132                 :            :                               sizeof(struct spdk_iscsi_sess), 0,
     133                 :            :                               SPDK_ENV_SOCKET_ID_ANY,
     134                 :            :                               iscsi_sess_ctor, iscsi);
     135         [ -  + ]:        601 :         if (!iscsi->session_pool) {
     136                 :          0 :                 SPDK_ERRLOG("create session pool failed\n");
     137                 :          0 :                 return -1;
     138                 :            :         }
     139                 :            : 
     140                 :        601 :         return 0;
     141                 :            : }
     142                 :            : 
     143                 :            : static int
     144                 :        601 : iscsi_initialize_all_pools(void)
     145                 :            : {
     146         [ -  + ]:        601 :         if (iscsi_initialize_pdu_pool() != 0) {
     147                 :          0 :                 return -1;
     148                 :            :         }
     149                 :            : 
     150         [ -  + ]:        601 :         if (iscsi_initialize_session_pool() != 0) {
     151                 :          0 :                 return -1;
     152                 :            :         }
     153                 :            : 
     154         [ -  + ]:        601 :         if (iscsi_initialize_task_pool() != 0) {
     155                 :          0 :                 return -1;
     156                 :            :         }
     157                 :            : 
     158                 :        601 :         return 0;
     159                 :            : }
     160                 :            : 
     161                 :            : static void
     162                 :       3005 : iscsi_check_pool(struct spdk_mempool *pool, size_t count)
     163                 :            : {
     164   [ +  -  -  + ]:       3005 :         if (pool && spdk_mempool_count(pool) != count) {
     165                 :          0 :                 SPDK_ERRLOG("spdk_mempool_count(%s) == %zu, should be %zu\n",
     166                 :            :                             spdk_mempool_get_name(pool), spdk_mempool_count(pool), count);
     167                 :            :         }
     168                 :       3005 : }
     169                 :            : 
     170                 :            : static void
     171                 :        601 : iscsi_check_pools(void)
     172                 :            : {
     173                 :        601 :         struct spdk_iscsi_globals *iscsi = &g_iscsi;
     174                 :            : 
     175                 :        601 :         iscsi_check_pool(iscsi->pdu_pool, iscsi->pdu_pool_size);
     176                 :        601 :         iscsi_check_pool(iscsi->session_pool, SESSION_POOL_SIZE(iscsi));
     177                 :        601 :         iscsi_check_pool(iscsi->pdu_immediate_data_pool, iscsi->immediate_data_pool_size);
     178                 :        601 :         iscsi_check_pool(iscsi->pdu_data_out_pool, iscsi->data_out_pool_size);
     179                 :        601 :         iscsi_check_pool(iscsi->task_pool, DEFAULT_TASK_POOL_SIZE);
     180                 :        601 : }
     181                 :            : 
     182                 :            : static void
     183                 :        601 : iscsi_free_pools(void)
     184                 :            : {
     185                 :        601 :         struct spdk_iscsi_globals *iscsi = &g_iscsi;
     186                 :            : 
     187                 :        601 :         spdk_mempool_free(iscsi->pdu_pool);
     188                 :        601 :         spdk_mempool_free(iscsi->session_pool);
     189                 :        601 :         spdk_mempool_free(iscsi->pdu_immediate_data_pool);
     190                 :        601 :         spdk_mempool_free(iscsi->pdu_data_out_pool);
     191                 :        601 :         spdk_mempool_free(iscsi->task_pool);
     192                 :        601 : }
     193                 :            : 
     194                 :            : void
     195                 :   61781226 : iscsi_put_pdu(struct spdk_iscsi_pdu *pdu)
     196                 :            : {
     197         [ -  + ]:   61781226 :         if (!pdu) {
     198                 :          0 :                 return;
     199                 :            :         }
     200                 :            : 
     201         [ -  + ]:   61781226 :         assert(pdu->ref > 0);
     202                 :   61781226 :         pdu->ref--;
     203                 :            : 
     204         [ +  + ]:   61781226 :         if (pdu->ref == 0) {
     205         [ +  + ]:   41281667 :                 if (pdu->mobj[0]) {
     206                 :    8802515 :                         iscsi_datapool_put(pdu->mobj[0]);
     207                 :            :                 }
     208         [ +  + ]:   41281667 :                 if (pdu->mobj[1]) {
     209                 :        619 :                         iscsi_datapool_put(pdu->mobj[1]);
     210                 :            :                 }
     211                 :            : 
     212   [ +  +  -  +  :   41281667 :                 if (pdu->data && !pdu->data_from_mempool) {
                   +  + ]
     213                 :     213085 :                         free(pdu->data);
     214                 :            :                 }
     215                 :            : 
     216                 :   41281667 :                 spdk_mempool_put(g_iscsi.pdu_pool, (void *)pdu);
     217                 :            :         }
     218                 :            : }
     219                 :            : 
     220                 :   41281667 : struct spdk_iscsi_pdu *iscsi_get_pdu(struct spdk_iscsi_conn *conn)
     221                 :            : {
     222                 :            :         struct spdk_iscsi_pdu *pdu;
     223                 :            : 
     224         [ -  + ]:   41281667 :         assert(conn != NULL);
     225                 :   41281667 :         pdu = spdk_mempool_get(g_iscsi.pdu_pool);
     226         [ -  + ]:   41281667 :         if (!pdu) {
     227                 :          0 :                 SPDK_ERRLOG("Unable to get PDU\n");
     228                 :          0 :                 abort();
     229                 :            :         }
     230                 :            : 
     231                 :            :         /* we do not want to zero out the last part of the structure reserved for AHS and sense data */
     232         [ -  + ]:   41281667 :         memset(pdu, 0, offsetof(struct spdk_iscsi_pdu, ahs));
     233                 :   41281667 :         pdu->ref = 1;
     234                 :   41281667 :         pdu->conn = conn;
     235                 :            :         /* Initialize CRC. */
     236                 :   41281667 :         pdu->crc32c = SPDK_CRC32C_INITIAL;
     237                 :            : 
     238                 :   41281667 :         return pdu;
     239                 :            : }
     240                 :            : 
     241                 :            : static void
     242                 :        601 : iscsi_log_globals(void)
     243                 :            : {
     244   [ -  +  -  +  :        601 :         SPDK_DEBUGLOG(iscsi, "AuthFile %s\n",
                   -  - ]
     245                 :            :                       g_iscsi.authfile ? g_iscsi.authfile : "(none)");
     246   [ -  +  -  + ]:        601 :         SPDK_DEBUGLOG(iscsi, "NodeBase %s\n", g_iscsi.nodebase);
     247   [ -  +  -  + ]:        601 :         SPDK_DEBUGLOG(iscsi, "MaxSessions %d\n", g_iscsi.MaxSessions);
     248   [ -  +  -  + ]:        601 :         SPDK_DEBUGLOG(iscsi, "MaxConnectionsPerSession %d\n",
     249                 :            :                       g_iscsi.MaxConnectionsPerSession);
     250   [ -  +  -  + ]:        601 :         SPDK_DEBUGLOG(iscsi, "MaxQueueDepth %d\n", g_iscsi.MaxQueueDepth);
     251   [ -  +  -  + ]:        601 :         SPDK_DEBUGLOG(iscsi, "DefaultTime2Wait %d\n",
     252                 :            :                       g_iscsi.DefaultTime2Wait);
     253   [ -  +  -  + ]:        601 :         SPDK_DEBUGLOG(iscsi, "DefaultTime2Retain %d\n",
     254                 :            :                       g_iscsi.DefaultTime2Retain);
     255   [ -  +  -  + ]:        601 :         SPDK_DEBUGLOG(iscsi, "FirstBurstLength %d\n",
     256                 :            :                       g_iscsi.FirstBurstLength);
     257   [ -  +  -  +  :        601 :         SPDK_DEBUGLOG(iscsi, "ImmediateData %s\n",
             -  -  -  - ]
     258                 :            :                       g_iscsi.ImmediateData ? "Yes" : "No");
     259   [ -  +  -  +  :        601 :         SPDK_DEBUGLOG(iscsi, "AllowDuplicateIsid %s\n",
             -  -  -  - ]
     260                 :            :                       g_iscsi.AllowDuplicateIsid ? "Yes" : "No");
     261   [ -  +  -  + ]:        601 :         SPDK_DEBUGLOG(iscsi, "ErrorRecoveryLevel %d\n",
     262                 :            :                       g_iscsi.ErrorRecoveryLevel);
     263   [ -  +  -  + ]:        601 :         SPDK_DEBUGLOG(iscsi, "Timeout %d\n", g_iscsi.timeout);
     264   [ -  +  -  + ]:        601 :         SPDK_DEBUGLOG(iscsi, "NopInInterval %d\n",
     265                 :            :                       g_iscsi.nopininterval);
     266   [ -  +  -  + ]:        601 :         if (g_iscsi.disable_chap) {
     267   [ #  #  #  # ]:          0 :                 SPDK_DEBUGLOG(iscsi,
     268                 :            :                               "DiscoveryAuthMethod None\n");
     269   [ +  +  +  - ]:        601 :         } else if (!g_iscsi.require_chap) {
     270   [ -  +  -  + ]:        601 :                 SPDK_DEBUGLOG(iscsi,
     271                 :            :                               "DiscoveryAuthMethod Auto\n");
     272                 :            :         } else {
     273   [ #  #  #  #  :          0 :                 SPDK_DEBUGLOG(iscsi,
          #  #  #  #  #  
                #  #  # ]
     274                 :            :                               "DiscoveryAuthMethod %s %s\n",
     275                 :            :                               g_iscsi.require_chap ? "CHAP" : "",
     276                 :            :                               g_iscsi.mutual_chap ? "Mutual" : "");
     277                 :            :         }
     278                 :            : 
     279         [ +  - ]:        601 :         if (g_iscsi.chap_group == 0) {
     280   [ -  +  -  + ]:        601 :                 SPDK_DEBUGLOG(iscsi,
     281                 :            :                               "DiscoveryAuthGroup None\n");
     282                 :            :         } else {
     283   [ #  #  #  # ]:          0 :                 SPDK_DEBUGLOG(iscsi,
     284                 :            :                               "DiscoveryAuthGroup AuthGroup%d\n",
     285                 :            :                               g_iscsi.chap_group);
     286                 :            :         }
     287                 :            : 
     288   [ -  +  -  + ]:        601 :         SPDK_DEBUGLOG(iscsi, "MaxLargeDataInPerConnection %d\n",
     289                 :            :                       g_iscsi.MaxLargeDataInPerConnection);
     290                 :            : 
     291   [ -  +  -  + ]:        601 :         SPDK_DEBUGLOG(iscsi, "MaxR2TPerConnection %d\n",
     292                 :            :                       g_iscsi.MaxR2TPerConnection);
     293                 :        601 : }
     294                 :            : 
     295                 :            : #define NUM_PDU_PER_CONNECTION(opts)    (2 * (opts->MaxQueueDepth +  \
     296                 :            :                                          opts->MaxLargeDataInPerConnection + \
     297                 :            :                                          2 * opts->MaxR2TPerConnection + 8))
     298                 :            : #define PDU_POOL_SIZE(opts)             (opts->MaxSessions * NUM_PDU_PER_CONNECTION(opts))
     299                 :            : #define IMMEDIATE_DATA_POOL_SIZE(opts)  (opts->MaxSessions * 128)
     300                 :            : #define DATA_OUT_POOL_SIZE(opts)        (opts->MaxSessions * MAX_DATA_OUT_PER_CONNECTION)
     301                 :            : 
     302                 :            : static void
     303                 :        601 : iscsi_opts_init(struct spdk_iscsi_opts *opts)
     304                 :            : {
     305                 :        601 :         opts->MaxSessions = DEFAULT_MAX_SESSIONS;
     306                 :        601 :         opts->MaxConnectionsPerSession = DEFAULT_MAX_CONNECTIONS_PER_SESSION;
     307                 :        601 :         opts->MaxQueueDepth = DEFAULT_MAX_QUEUE_DEPTH;
     308                 :        601 :         opts->DefaultTime2Wait = DEFAULT_DEFAULTTIME2WAIT;
     309                 :        601 :         opts->DefaultTime2Retain = DEFAULT_DEFAULTTIME2RETAIN;
     310                 :        601 :         opts->FirstBurstLength = SPDK_ISCSI_FIRST_BURST_LENGTH;
     311                 :        601 :         opts->ImmediateData = DEFAULT_IMMEDIATEDATA;
     312                 :        601 :         opts->AllowDuplicateIsid = false;
     313                 :        601 :         opts->ErrorRecoveryLevel = DEFAULT_ERRORRECOVERYLEVEL;
     314                 :        601 :         opts->timeout = DEFAULT_TIMEOUT;
     315                 :        601 :         opts->nopininterval = DEFAULT_NOPININTERVAL;
     316                 :        601 :         opts->disable_chap = false;
     317                 :        601 :         opts->require_chap = false;
     318                 :        601 :         opts->mutual_chap = false;
     319                 :        601 :         opts->chap_group = 0;
     320                 :        601 :         opts->authfile = NULL;
     321                 :        601 :         opts->nodebase = NULL;
     322                 :        601 :         opts->MaxLargeDataInPerConnection = DEFAULT_MAX_LARGE_DATAIN_PER_CONNECTION;
     323                 :        601 :         opts->MaxR2TPerConnection = DEFAULT_MAXR2T;
     324                 :        601 :         opts->pdu_pool_size = PDU_POOL_SIZE(opts);
     325                 :        601 :         opts->immediate_data_pool_size = IMMEDIATE_DATA_POOL_SIZE(opts);
     326                 :        601 :         opts->data_out_pool_size = DATA_OUT_POOL_SIZE(opts);
     327                 :        601 : }
     328                 :            : 
     329                 :            : struct spdk_iscsi_opts *
     330                 :        601 : iscsi_opts_alloc(void)
     331                 :            : {
     332                 :            :         struct spdk_iscsi_opts *opts;
     333                 :            : 
     334                 :        601 :         opts = calloc(1, sizeof(*opts));
     335         [ -  + ]:        601 :         if (!opts) {
     336                 :          0 :                 SPDK_ERRLOG("calloc() failed for iscsi options\n");
     337                 :          0 :                 return NULL;
     338                 :            :         }
     339                 :            : 
     340                 :        601 :         iscsi_opts_init(opts);
     341                 :            : 
     342                 :        601 :         return opts;
     343                 :            : }
     344                 :            : 
     345                 :            : void
     346                 :        669 : iscsi_opts_free(struct spdk_iscsi_opts *opts)
     347                 :            : {
     348                 :        669 :         free(opts->authfile);
     349                 :        669 :         free(opts->nodebase);
     350                 :        669 :         free(opts);
     351                 :        669 : }
     352                 :            : 
     353                 :            : /* Deep copy of spdk_iscsi_opts */
     354                 :            : struct spdk_iscsi_opts *
     355                 :         68 : iscsi_opts_copy(struct spdk_iscsi_opts *src)
     356                 :            : {
     357                 :            :         struct spdk_iscsi_opts *dst;
     358                 :            : 
     359                 :         68 :         dst = calloc(1, sizeof(*dst));
     360         [ -  + ]:         68 :         if (!dst) {
     361                 :          0 :                 SPDK_ERRLOG("calloc() failed for iscsi options\n");
     362                 :          0 :                 return NULL;
     363                 :            :         }
     364                 :            : 
     365         [ -  + ]:         68 :         if (src->authfile) {
     366         [ #  # ]:          0 :                 dst->authfile = strdup(src->authfile);
     367         [ #  # ]:          0 :                 if (!dst->authfile) {
     368                 :          0 :                         free(dst);
     369                 :          0 :                         SPDK_ERRLOG("failed to strdup for auth file %s\n", src->authfile);
     370                 :          0 :                         return NULL;
     371                 :            :                 }
     372                 :            :         }
     373                 :            : 
     374         [ +  + ]:         68 :         if (src->nodebase) {
     375         [ -  + ]:         37 :                 dst->nodebase = strdup(src->nodebase);
     376         [ -  + ]:         37 :                 if (!dst->nodebase) {
     377                 :          0 :                         free(dst->authfile);
     378                 :          0 :                         free(dst);
     379                 :          0 :                         SPDK_ERRLOG("failed to strdup for nodebase %s\n", src->nodebase);
     380                 :          0 :                         return NULL;
     381                 :            :                 }
     382                 :            :         }
     383                 :            : 
     384                 :         68 :         dst->MaxSessions = src->MaxSessions;
     385                 :         68 :         dst->MaxConnectionsPerSession = src->MaxConnectionsPerSession;
     386                 :         68 :         dst->MaxQueueDepth = src->MaxQueueDepth;
     387                 :         68 :         dst->DefaultTime2Wait = src->DefaultTime2Wait;
     388                 :         68 :         dst->DefaultTime2Retain = src->DefaultTime2Retain;
     389                 :         68 :         dst->FirstBurstLength = src->FirstBurstLength;
     390         [ -  + ]:         68 :         dst->ImmediateData = src->ImmediateData;
     391         [ -  + ]:         68 :         dst->AllowDuplicateIsid = src->AllowDuplicateIsid;
     392                 :         68 :         dst->ErrorRecoveryLevel = src->ErrorRecoveryLevel;
     393                 :         68 :         dst->timeout = src->timeout;
     394                 :         68 :         dst->nopininterval = src->nopininterval;
     395         [ -  + ]:         68 :         dst->disable_chap = src->disable_chap;
     396         [ -  + ]:         68 :         dst->require_chap = src->require_chap;
     397         [ -  + ]:         68 :         dst->mutual_chap = src->mutual_chap;
     398                 :         68 :         dst->chap_group = src->chap_group;
     399                 :         68 :         dst->MaxLargeDataInPerConnection = src->MaxLargeDataInPerConnection;
     400                 :         68 :         dst->MaxR2TPerConnection = src->MaxR2TPerConnection;
     401                 :         68 :         dst->pdu_pool_size = src->pdu_pool_size;
     402                 :         68 :         dst->immediate_data_pool_size = src->immediate_data_pool_size;
     403                 :         68 :         dst->data_out_pool_size = src->data_out_pool_size;
     404                 :            : 
     405                 :         68 :         return dst;
     406                 :            : }
     407                 :            : 
     408                 :            : static int
     409                 :        601 : iscsi_opts_verify(struct spdk_iscsi_opts *opts)
     410                 :            : {
     411         [ +  + ]:        601 :         if (!opts->nodebase) {
     412         [ -  + ]:        564 :                 opts->nodebase = strdup(SPDK_ISCSI_DEFAULT_NODEBASE);
     413         [ -  + ]:        564 :                 if (opts->nodebase == NULL) {
     414                 :          0 :                         SPDK_ERRLOG("strdup() failed for default nodebase\n");
     415                 :          0 :                         return -ENOMEM;
     416                 :            :                 }
     417                 :            :         }
     418                 :            : 
     419   [ +  -  -  + ]:        601 :         if (opts->MaxSessions == 0 || opts->MaxSessions > 65535) {
     420                 :          0 :                 SPDK_ERRLOG("%d is invalid. MaxSessions must be more than 0 and no more than 65535\n",
     421                 :            :                             opts->MaxSessions);
     422                 :          0 :                 return -EINVAL;
     423                 :            :         }
     424                 :            : 
     425   [ +  -  -  + ]:        601 :         if (opts->MaxConnectionsPerSession == 0 || opts->MaxConnectionsPerSession > 65535) {
     426                 :          0 :                 SPDK_ERRLOG("%d is invalid. MaxConnectionsPerSession must be more than 0 and no more than 65535\n",
     427                 :            :                             opts->MaxConnectionsPerSession);
     428                 :          0 :                 return -EINVAL;
     429                 :            :         }
     430                 :            : 
     431   [ +  -  -  + ]:        601 :         if (opts->MaxQueueDepth == 0 || opts->MaxQueueDepth > 256) {
     432                 :          0 :                 SPDK_ERRLOG("%d is invalid. MaxQueueDepth must be more than 0 and no more than 256\n",
     433                 :            :                             opts->MaxQueueDepth);
     434                 :          0 :                 return -EINVAL;
     435                 :            :         }
     436                 :            : 
     437         [ -  + ]:        601 :         if (opts->DefaultTime2Wait > 3600) {
     438                 :          0 :                 SPDK_ERRLOG("%d is invalid. DefaultTime2Wait must be no more than 3600\n",
     439                 :            :                             opts->DefaultTime2Wait);
     440                 :          0 :                 return -EINVAL;
     441                 :            :         }
     442                 :            : 
     443         [ -  + ]:        601 :         if (opts->DefaultTime2Retain > 3600) {
     444                 :          0 :                 SPDK_ERRLOG("%d is invalid. DefaultTime2Retain must be no more than 3600\n",
     445                 :            :                             opts->DefaultTime2Retain);
     446                 :          0 :                 return -EINVAL;
     447                 :            :         }
     448                 :            : 
     449         [ +  - ]:        601 :         if (opts->FirstBurstLength >= SPDK_ISCSI_MIN_FIRST_BURST_LENGTH) {
     450         [ -  + ]:        601 :                 if (opts->FirstBurstLength > SPDK_ISCSI_MAX_BURST_LENGTH) {
     451                 :          0 :                         SPDK_ERRLOG("FirstBurstLength %d shall not exceed MaxBurstLength %d\n",
     452                 :            :                                     opts->FirstBurstLength, SPDK_ISCSI_MAX_BURST_LENGTH);
     453                 :          0 :                         return -EINVAL;
     454                 :            :                 }
     455                 :            :         } else {
     456                 :          0 :                 SPDK_ERRLOG("FirstBurstLength %d shall be no less than %d\n",
     457                 :            :                             opts->FirstBurstLength, SPDK_ISCSI_MIN_FIRST_BURST_LENGTH);
     458                 :          0 :                 return -EINVAL;
     459                 :            :         }
     460                 :            : 
     461         [ -  + ]:        601 :         if (opts->ErrorRecoveryLevel > 2) {
     462                 :          0 :                 SPDK_ERRLOG("ErrorRecoveryLevel %d is not supported.\n", opts->ErrorRecoveryLevel);
     463                 :          0 :                 return -EINVAL;
     464                 :            :         }
     465                 :            : 
     466         [ -  + ]:        601 :         if (opts->timeout < 0) {
     467                 :          0 :                 SPDK_ERRLOG("%d is invalid. timeout must not be less than 0\n", opts->timeout);
     468                 :          0 :                 return -EINVAL;
     469                 :            :         }
     470                 :            : 
     471   [ +  -  -  + ]:        601 :         if (opts->nopininterval < 0 || opts->nopininterval > MAX_NOPININTERVAL) {
     472                 :          0 :                 SPDK_ERRLOG("%d is invalid. nopinterval must be between 0 and %d\n",
     473                 :            :                             opts->nopininterval, MAX_NOPININTERVAL);
     474                 :          0 :                 return -EINVAL;
     475                 :            :         }
     476                 :            : 
     477   [ -  +  -  +  :       1093 :         if (!iscsi_check_chap_params(opts->disable_chap, opts->require_chap,
                   -  + ]
     478         [ -  + ]:        601 :                                      opts->mutual_chap, opts->chap_group)) {
     479                 :          0 :                 SPDK_ERRLOG("CHAP params in opts are illegal combination\n");
     480                 :          0 :                 return -EINVAL;
     481                 :            :         }
     482                 :            : 
     483         [ -  + ]:        601 :         if (opts->MaxLargeDataInPerConnection == 0) {
     484                 :          0 :                 SPDK_ERRLOG("0 is invalid. MaxLargeDataInPerConnection must be more than 0\n");
     485                 :          0 :                 return -EINVAL;
     486                 :            :         }
     487                 :            : 
     488         [ -  + ]:        601 :         if (opts->MaxR2TPerConnection == 0) {
     489                 :          0 :                 SPDK_ERRLOG("0 is invalid. MaxR2TPerConnection must be more than 0\n");
     490                 :          0 :                 return -EINVAL;
     491                 :            :         }
     492                 :            : 
     493         [ -  + ]:        601 :         if (opts->pdu_pool_size == 0) {
     494                 :          0 :                 SPDK_ERRLOG("0 is invalid. pdu_pool_size must be more than 0\n");
     495                 :          0 :                 return -EINVAL;
     496                 :            :         }
     497                 :            : 
     498         [ -  + ]:        601 :         if (opts->immediate_data_pool_size == 0) {
     499                 :          0 :                 SPDK_ERRLOG("0 is invalid. immediate_data_pool_size must be more than 0\n");
     500                 :          0 :                 return -EINVAL;
     501                 :            :         }
     502                 :            : 
     503         [ -  + ]:        601 :         if (opts->data_out_pool_size == 0) {
     504                 :          0 :                 SPDK_ERRLOG("0 is invalid. data_out_pool_size must be more than 0\n");
     505                 :          0 :                 return -EINVAL;
     506                 :            :         }
     507                 :            : 
     508                 :        601 :         return 0;
     509                 :            : }
     510                 :            : 
     511                 :            : static int
     512                 :        601 : iscsi_set_global_params(struct spdk_iscsi_opts *opts)
     513                 :            : {
     514                 :            :         int rc;
     515                 :            : 
     516                 :        601 :         rc = iscsi_opts_verify(opts);
     517         [ -  + ]:        601 :         if (rc != 0) {
     518                 :          0 :                 SPDK_ERRLOG("spdk_iscsi_opts_verify() failed\n");
     519                 :          0 :                 return rc;
     520                 :            :         }
     521                 :            : 
     522         [ -  + ]:        601 :         if (opts->authfile != NULL) {
     523         [ #  # ]:          0 :                 g_iscsi.authfile = strdup(opts->authfile);
     524         [ #  # ]:          0 :                 if (!g_iscsi.authfile) {
     525                 :          0 :                         SPDK_ERRLOG("failed to strdup for auth file %s\n", opts->authfile);
     526                 :          0 :                         return -ENOMEM;
     527                 :            :                 }
     528                 :            :         }
     529                 :            : 
     530         [ -  + ]:        601 :         g_iscsi.nodebase = strdup(opts->nodebase);
     531         [ -  + ]:        601 :         if (!g_iscsi.nodebase) {
     532                 :          0 :                 SPDK_ERRLOG("failed to strdup for nodebase %s\n", opts->nodebase);
     533                 :          0 :                 return -ENOMEM;
     534                 :            :         }
     535                 :            : 
     536                 :        601 :         g_iscsi.MaxSessions = opts->MaxSessions;
     537                 :        601 :         g_iscsi.MaxConnectionsPerSession = opts->MaxConnectionsPerSession;
     538                 :        601 :         g_iscsi.MaxQueueDepth = opts->MaxQueueDepth;
     539                 :        601 :         g_iscsi.DefaultTime2Wait = opts->DefaultTime2Wait;
     540                 :        601 :         g_iscsi.DefaultTime2Retain = opts->DefaultTime2Retain;
     541                 :        601 :         g_iscsi.FirstBurstLength = opts->FirstBurstLength;
     542         [ -  + ]:        601 :         g_iscsi.ImmediateData = opts->ImmediateData;
     543         [ -  + ]:        601 :         g_iscsi.AllowDuplicateIsid = opts->AllowDuplicateIsid;
     544                 :        601 :         g_iscsi.ErrorRecoveryLevel = opts->ErrorRecoveryLevel;
     545                 :        601 :         g_iscsi.timeout = opts->timeout;
     546                 :        601 :         g_iscsi.nopininterval = opts->nopininterval;
     547         [ -  + ]:        601 :         g_iscsi.disable_chap = opts->disable_chap;
     548         [ -  + ]:        601 :         g_iscsi.require_chap = opts->require_chap;
     549         [ -  + ]:        601 :         g_iscsi.mutual_chap = opts->mutual_chap;
     550                 :        601 :         g_iscsi.chap_group = opts->chap_group;
     551                 :        601 :         g_iscsi.MaxLargeDataInPerConnection = opts->MaxLargeDataInPerConnection;
     552                 :        601 :         g_iscsi.MaxR2TPerConnection = opts->MaxR2TPerConnection;
     553                 :        601 :         g_iscsi.pdu_pool_size = opts->pdu_pool_size;
     554                 :        601 :         g_iscsi.immediate_data_pool_size = opts->immediate_data_pool_size;
     555                 :        601 :         g_iscsi.data_out_pool_size = opts->data_out_pool_size;
     556                 :            : 
     557                 :        601 :         iscsi_log_globals();
     558                 :            : 
     559                 :        601 :         return 0;
     560                 :            : }
     561                 :            : 
     562                 :            : int
     563                 :         10 : iscsi_set_discovery_auth(bool disable_chap, bool require_chap, bool mutual_chap,
     564                 :            :                          int32_t chap_group)
     565                 :            : {
     566         [ -  + ]:         10 :         if (!iscsi_check_chap_params(disable_chap, require_chap, mutual_chap,
     567                 :            :                                      chap_group)) {
     568                 :          0 :                 SPDK_ERRLOG("CHAP params are illegal combination\n");
     569                 :          0 :                 return -EINVAL;
     570                 :            :         }
     571                 :            : 
     572         [ -  + ]:         10 :         pthread_mutex_lock(&g_iscsi.mutex);
     573                 :         10 :         g_iscsi.disable_chap = disable_chap;
     574                 :         10 :         g_iscsi.require_chap = require_chap;
     575                 :         10 :         g_iscsi.mutual_chap = mutual_chap;
     576                 :         10 :         g_iscsi.chap_group = chap_group;
     577         [ -  + ]:         10 :         pthread_mutex_unlock(&g_iscsi.mutex);
     578                 :            : 
     579                 :         10 :         return 0;
     580                 :            : }
     581                 :            : 
     582                 :            : int
     583                 :         16 : iscsi_auth_group_add_secret(struct spdk_iscsi_auth_group *group,
     584                 :            :                             const char *user, const char *secret,
     585                 :            :                             const char *muser, const char *msecret)
     586                 :            : {
     587                 :            :         struct spdk_iscsi_auth_secret *_secret;
     588                 :            :         size_t len;
     589                 :            : 
     590   [ +  -  -  + ]:         16 :         if (user == NULL || secret == NULL) {
     591                 :          0 :                 SPDK_ERRLOG("user and secret must be specified\n");
     592                 :          0 :                 return -EINVAL;
     593                 :            :         }
     594                 :            : 
     595   [ +  +  -  + ]:         16 :         if (muser != NULL && msecret == NULL) {
     596                 :          0 :                 SPDK_ERRLOG("msecret must be specified with muser\n");
     597                 :          0 :                 return -EINVAL;
     598                 :            :         }
     599                 :            : 
     600         [ +  + ]:         22 :         TAILQ_FOREACH(_secret, &group->secret_head, tailq) {
     601   [ -  +  -  +  :          6 :                 if (strcmp(_secret->user, user) == 0) {
                   -  + ]
     602                 :          0 :                         SPDK_ERRLOG("user for secret is duplicated\n");
     603                 :          0 :                         return -EEXIST;
     604                 :            :                 }
     605                 :            :         }
     606                 :            : 
     607                 :         16 :         _secret = calloc(1, sizeof(*_secret));
     608         [ -  + ]:         16 :         if (_secret == NULL) {
     609                 :          0 :                 SPDK_ERRLOG("calloc() failed for CHAP secret\n");
     610                 :          0 :                 return -ENOMEM;
     611                 :            :         }
     612                 :            : 
     613         [ -  + ]:         16 :         len = strnlen(user, sizeof(_secret->user));
     614         [ -  + ]:         16 :         if (len > sizeof(_secret->user) - 1) {
     615                 :          0 :                 SPDK_ERRLOG("CHAP user longer than %zu characters: %s\n",
     616                 :            :                             sizeof(_secret->user) - 1, user);
     617                 :          0 :                 free(_secret);
     618                 :          0 :                 return -EINVAL;
     619                 :            :         }
     620   [ -  +  -  + ]:         16 :         memcpy(_secret->user, user, len);
     621                 :            : 
     622         [ -  + ]:         16 :         len = strnlen(secret, sizeof(_secret->secret));
     623         [ -  + ]:         16 :         if (len > sizeof(_secret->secret) - 1) {
     624                 :          0 :                 SPDK_ERRLOG("CHAP secret longer than %zu characters: %s\n",
     625                 :            :                             sizeof(_secret->secret) - 1, secret);
     626                 :          0 :                 free(_secret);
     627                 :          0 :                 return -EINVAL;
     628                 :            :         }
     629   [ -  +  -  + ]:         16 :         memcpy(_secret->secret, secret, len);
     630                 :            : 
     631         [ +  + ]:         16 :         if (muser != NULL) {
     632         [ -  + ]:         14 :                 len = strnlen(muser, sizeof(_secret->muser));
     633         [ -  + ]:         14 :                 if (len > sizeof(_secret->muser) - 1) {
     634                 :          0 :                         SPDK_ERRLOG("Mutual CHAP user longer than %zu characters: %s\n",
     635                 :            :                                     sizeof(_secret->muser) - 1, muser);
     636                 :          0 :                         free(_secret);
     637                 :          0 :                         return -EINVAL;
     638                 :            :                 }
     639   [ -  +  -  + ]:         14 :                 memcpy(_secret->muser, muser, len);
     640                 :            : 
     641         [ -  + ]:         14 :                 len = strnlen(msecret, sizeof(_secret->msecret));
     642         [ -  + ]:         14 :                 if (len > sizeof(_secret->msecret) - 1) {
     643                 :          0 :                         SPDK_ERRLOG("Mutual CHAP secret longer than %zu characters: %s\n",
     644                 :            :                                     sizeof(_secret->msecret) - 1, msecret);
     645                 :          0 :                         free(_secret);
     646                 :          0 :                         return -EINVAL;
     647                 :            :                 }
     648   [ -  +  -  + ]:         14 :                 memcpy(_secret->msecret, msecret, len);
     649                 :            :         }
     650                 :            : 
     651                 :         16 :         TAILQ_INSERT_TAIL(&group->secret_head, _secret, tailq);
     652                 :         16 :         return 0;
     653                 :            : }
     654                 :            : 
     655                 :            : int
     656                 :          6 : iscsi_auth_group_delete_secret(struct spdk_iscsi_auth_group *group,
     657                 :            :                                const char *user)
     658                 :            : {
     659                 :            :         struct spdk_iscsi_auth_secret *_secret;
     660                 :            : 
     661         [ -  + ]:          6 :         if (user == NULL) {
     662                 :          0 :                 SPDK_ERRLOG("user must be specified\n");
     663                 :          0 :                 return -EINVAL;
     664                 :            :         }
     665                 :            : 
     666         [ +  - ]:         10 :         TAILQ_FOREACH(_secret, &group->secret_head, tailq) {
     667   [ -  +  -  +  :         10 :                 if (strcmp(_secret->user, user) == 0) {
                   +  + ]
     668                 :          6 :                         break;
     669                 :            :                 }
     670                 :            :         }
     671                 :            : 
     672         [ -  + ]:          6 :         if (_secret == NULL) {
     673                 :          0 :                 SPDK_ERRLOG("secret is not found\n");
     674                 :          0 :                 return -ENODEV;
     675                 :            :         }
     676                 :            : 
     677         [ +  + ]:          6 :         TAILQ_REMOVE(&group->secret_head, _secret, tailq);
     678                 :          6 :         free(_secret);
     679                 :            : 
     680                 :          6 :         return 0;
     681                 :            : }
     682                 :            : 
     683                 :            : int
     684                 :         12 : iscsi_add_auth_group(int32_t tag, struct spdk_iscsi_auth_group **_group)
     685                 :            : {
     686                 :            :         struct spdk_iscsi_auth_group *group;
     687                 :            : 
     688         [ +  + ]:         16 :         TAILQ_FOREACH(group, &g_iscsi.auth_group_head, tailq) {
     689         [ -  + ]:          4 :                 if (group->tag == tag) {
     690                 :          0 :                         SPDK_ERRLOG("Auth group (%d) already exists\n", tag);
     691                 :          0 :                         return -EEXIST;
     692                 :            :                 }
     693                 :            :         }
     694                 :            : 
     695                 :         12 :         group = calloc(1, sizeof(*group));
     696         [ -  + ]:         12 :         if (group == NULL) {
     697                 :          0 :                 SPDK_ERRLOG("calloc() failed for auth group\n");
     698                 :          0 :                 return -ENOMEM;
     699                 :            :         }
     700                 :            : 
     701                 :         12 :         TAILQ_INIT(&group->secret_head);
     702                 :         12 :         group->tag = tag;
     703                 :            : 
     704                 :         12 :         TAILQ_INSERT_TAIL(&g_iscsi.auth_group_head, group, tailq);
     705                 :            : 
     706                 :         12 :         *_group = group;
     707                 :         12 :         return 0;
     708                 :            : }
     709                 :            : 
     710                 :            : void
     711                 :         12 : iscsi_delete_auth_group(struct spdk_iscsi_auth_group *group)
     712                 :            : {
     713                 :            :         struct spdk_iscsi_auth_secret *_secret, *tmp;
     714                 :            : 
     715         [ +  + ]:         12 :         TAILQ_REMOVE(&g_iscsi.auth_group_head, group, tailq);
     716                 :            : 
     717         [ +  + ]:         22 :         TAILQ_FOREACH_SAFE(_secret, &group->secret_head, tailq, tmp) {
     718         [ -  + ]:         10 :                 TAILQ_REMOVE(&group->secret_head, _secret, tailq);
     719                 :         10 :                 free(_secret);
     720                 :            :         }
     721                 :         12 :         free(group);
     722                 :         12 : }
     723                 :            : 
     724                 :            : struct spdk_iscsi_auth_group *
     725                 :         18 : iscsi_find_auth_group_by_tag(int32_t tag)
     726                 :            : {
     727                 :            :         struct spdk_iscsi_auth_group *group;
     728                 :            : 
     729         [ +  - ]:         20 :         TAILQ_FOREACH(group, &g_iscsi.auth_group_head, tailq) {
     730         [ +  + ]:         20 :                 if (group->tag == tag) {
     731                 :         18 :                         return group;
     732                 :            :                 }
     733                 :            :         }
     734                 :            : 
     735                 :          0 :         return NULL;
     736                 :            : }
     737                 :            : 
     738                 :            : static void
     739                 :        601 : iscsi_auth_groups_destroy(void)
     740                 :            : {
     741                 :            :         struct spdk_iscsi_auth_group *group, *tmp;
     742                 :            : 
     743         [ +  + ]:        609 :         TAILQ_FOREACH_SAFE(group, &g_iscsi.auth_group_head, tailq, tmp) {
     744                 :          8 :                 iscsi_delete_auth_group(group);
     745                 :            :         }
     746                 :        601 : }
     747                 :            : 
     748                 :            : static int
     749                 :          0 : iscsi_parse_auth_group(struct spdk_conf_section *sp)
     750                 :            : {
     751                 :            :         int rc;
     752                 :            :         int i;
     753                 :            :         int tag;
     754                 :            :         const char *val, *user, *secret, *muser, *msecret;
     755                 :          0 :         struct spdk_iscsi_auth_group *group = NULL;
     756                 :            : 
     757                 :          0 :         val = spdk_conf_section_get_val(sp, "Comment");
     758         [ #  # ]:          0 :         if (val != NULL) {
     759   [ #  #  #  # ]:          0 :                 SPDK_DEBUGLOG(iscsi, "Comment %s\n", val);
     760                 :            :         }
     761                 :            : 
     762                 :          0 :         tag = spdk_conf_section_get_num(sp);
     763                 :            : 
     764                 :          0 :         rc = iscsi_add_auth_group(tag, &group);
     765         [ #  # ]:          0 :         if (rc != 0) {
     766                 :          0 :                 SPDK_ERRLOG("Failed to add auth group\n");
     767                 :          0 :                 return rc;
     768                 :            :         }
     769                 :            : 
     770                 :          0 :         for (i = 0; ; i++) {
     771                 :          0 :                 val = spdk_conf_section_get_nval(sp, "Auth", i);
     772         [ #  # ]:          0 :                 if (val == NULL) {
     773                 :          0 :                         break;
     774                 :            :                 }
     775                 :            : 
     776                 :          0 :                 user = spdk_conf_section_get_nmval(sp, "Auth", i, 0);
     777                 :          0 :                 secret = spdk_conf_section_get_nmval(sp, "Auth", i, 1);
     778                 :          0 :                 muser = spdk_conf_section_get_nmval(sp, "Auth", i, 2);
     779                 :          0 :                 msecret = spdk_conf_section_get_nmval(sp, "Auth", i, 3);
     780                 :            : 
     781                 :          0 :                 rc = iscsi_auth_group_add_secret(group, user, secret, muser, msecret);
     782         [ #  # ]:          0 :                 if (rc != 0) {
     783                 :          0 :                         SPDK_ERRLOG("Failed to add secret to auth group\n");
     784                 :          0 :                         iscsi_delete_auth_group(group);
     785                 :          0 :                         return rc;
     786                 :            :                 }
     787                 :            :         }
     788                 :            : 
     789                 :          0 :         return 0;
     790                 :            : }
     791                 :            : 
     792                 :            : static int
     793                 :          0 : iscsi_parse_auth_info(void)
     794                 :            : {
     795                 :            :         struct spdk_conf *config;
     796                 :            :         struct spdk_conf_section *sp;
     797                 :            :         int rc;
     798                 :            : 
     799                 :          0 :         config = spdk_conf_allocate();
     800         [ #  # ]:          0 :         if (!config) {
     801                 :          0 :                 SPDK_ERRLOG("Failed to allocate config file\n");
     802                 :          0 :                 return -ENOMEM;
     803                 :            :         }
     804                 :            : 
     805                 :          0 :         rc = spdk_conf_read(config, g_iscsi.authfile);
     806         [ #  # ]:          0 :         if (rc != 0) {
     807   [ #  #  #  # ]:          0 :                 SPDK_INFOLOG(iscsi, "Failed to load auth file\n");
     808                 :          0 :                 spdk_conf_free(config);
     809                 :          0 :                 return rc;
     810                 :            :         }
     811                 :            : 
     812                 :          0 :         sp = spdk_conf_first_section(config);
     813         [ #  # ]:          0 :         while (sp != NULL) {
     814         [ #  # ]:          0 :                 if (spdk_conf_section_match_prefix(sp, "AuthGroup")) {
     815         [ #  # ]:          0 :                         if (spdk_conf_section_get_num(sp) == 0) {
     816                 :          0 :                                 SPDK_ERRLOG("Group 0 is invalid\n");
     817                 :          0 :                                 iscsi_auth_groups_destroy();
     818                 :          0 :                                 spdk_conf_free(config);
     819                 :          0 :                                 return -EINVAL;
     820                 :            :                         }
     821                 :            : 
     822                 :          0 :                         rc = iscsi_parse_auth_group(sp);
     823         [ #  # ]:          0 :                         if (rc != 0) {
     824                 :          0 :                                 SPDK_ERRLOG("parse_auth_group() failed\n");
     825                 :          0 :                                 iscsi_auth_groups_destroy();
     826                 :          0 :                                 spdk_conf_free(config);
     827                 :          0 :                                 return rc;
     828                 :            :                         }
     829                 :            :                 }
     830                 :          0 :                 sp = spdk_conf_next_section(sp);
     831                 :            :         }
     832                 :            : 
     833                 :          0 :         spdk_conf_free(config);
     834                 :          0 :         return 0;
     835                 :            : }
     836                 :            : 
     837                 :            : static struct spdk_iscsi_auth_secret *
     838                 :        352 : iscsi_find_auth_secret(const char *authuser, int ag_tag)
     839                 :            : {
     840                 :            :         struct spdk_iscsi_auth_group *group;
     841                 :            :         struct spdk_iscsi_auth_secret *_secret;
     842                 :            : 
     843         [ +  - ]:        356 :         TAILQ_FOREACH(group, &g_iscsi.auth_group_head, tailq) {
     844         [ +  + ]:        356 :                 if (group->tag == ag_tag) {
     845         [ +  - ]:        352 :                         TAILQ_FOREACH(_secret, &group->secret_head, tailq) {
     846   [ -  +  -  +  :        352 :                                 if (strcmp(_secret->user, authuser) == 0) {
                   +  - ]
     847                 :        352 :                                         return _secret;
     848                 :            :                                 }
     849                 :            :                         }
     850                 :            :                 }
     851                 :            :         }
     852                 :            : 
     853                 :          0 :         return NULL;
     854                 :            : }
     855                 :            : 
     856                 :            : int
     857                 :        352 : iscsi_chap_get_authinfo(struct iscsi_chap_auth *auth, const char *authuser,
     858                 :            :                         int ag_tag)
     859                 :            : {
     860                 :            :         struct spdk_iscsi_auth_secret *_secret;
     861                 :            : 
     862         [ -  + ]:        352 :         if (authuser == NULL) {
     863                 :          0 :                 return -EINVAL;
     864                 :            :         }
     865                 :            : 
     866         [ -  + ]:        352 :         if (auth->user[0] != '\0') {
     867         [ #  # ]:          0 :                 memset(auth->user, 0, sizeof(auth->user));
     868         [ #  # ]:          0 :                 memset(auth->secret, 0, sizeof(auth->secret));
     869         [ #  # ]:          0 :                 memset(auth->muser, 0, sizeof(auth->muser));
     870         [ #  # ]:          0 :                 memset(auth->msecret, 0, sizeof(auth->msecret));
     871                 :            :         }
     872                 :            : 
     873         [ -  + ]:        352 :         pthread_mutex_lock(&g_iscsi.mutex);
     874                 :            : 
     875                 :        352 :         _secret = iscsi_find_auth_secret(authuser, ag_tag);
     876         [ -  + ]:        352 :         if (_secret == NULL) {
     877         [ #  # ]:          0 :                 pthread_mutex_unlock(&g_iscsi.mutex);
     878                 :            : 
     879                 :          0 :                 SPDK_ERRLOG("CHAP secret is not found: user:%s, tag:%d\n",
     880                 :            :                             authuser, ag_tag);
     881                 :          0 :                 return -ENOENT;
     882                 :            :         }
     883                 :            : 
     884   [ -  +  -  + ]:        352 :         memcpy(auth->user, _secret->user, sizeof(auth->user));
     885   [ -  +  -  + ]:        352 :         memcpy(auth->secret, _secret->secret, sizeof(auth->secret));
     886                 :            : 
     887         [ +  + ]:        352 :         if (_secret->muser[0] != '\0') {
     888   [ -  +  -  + ]:          8 :                 memcpy(auth->muser, _secret->muser, sizeof(auth->muser));
     889   [ -  +  -  + ]:          8 :                 memcpy(auth->msecret, _secret->msecret, sizeof(auth->msecret));
     890                 :            :         }
     891                 :            : 
     892         [ -  + ]:        352 :         pthread_mutex_unlock(&g_iscsi.mutex);
     893                 :        352 :         return 0;
     894                 :            : }
     895                 :            : 
     896                 :            : static int
     897                 :        601 : iscsi_initialize_global_params(void)
     898                 :            : {
     899                 :            :         int rc;
     900                 :            : 
     901         [ +  + ]:        601 :         if (!g_spdk_iscsi_opts) {
     902                 :        533 :                 g_spdk_iscsi_opts = iscsi_opts_alloc();
     903         [ -  + ]:        533 :                 if (!g_spdk_iscsi_opts) {
     904                 :          0 :                         SPDK_ERRLOG("iscsi_opts_alloc_failed() failed\n");
     905                 :          0 :                         return -ENOMEM;
     906                 :            :                 }
     907                 :            :         }
     908                 :            : 
     909                 :        601 :         rc = iscsi_set_global_params(g_spdk_iscsi_opts);
     910         [ -  + ]:        601 :         if (rc != 0) {
     911                 :          0 :                 SPDK_ERRLOG("iscsi_set_global_params() failed\n");
     912                 :            :         }
     913                 :            : 
     914                 :        601 :         iscsi_opts_free(g_spdk_iscsi_opts);
     915                 :        601 :         g_spdk_iscsi_opts = NULL;
     916                 :            : 
     917                 :        601 :         return rc;
     918                 :            : }
     919                 :            : 
     920                 :            : static void
     921                 :        601 : iscsi_init_complete(int rc)
     922                 :            : {
     923                 :        601 :         spdk_iscsi_init_cb cb_fn = g_init_cb_fn;
     924                 :        601 :         void *cb_arg = g_init_cb_arg;
     925                 :            : 
     926                 :        601 :         g_init_cb_fn = NULL;
     927                 :        601 :         g_init_cb_arg = NULL;
     928                 :            : 
     929                 :        601 :         cb_fn(cb_arg, rc);
     930                 :        601 : }
     931                 :            : 
     932                 :            : static void
     933                 :        601 : iscsi_parse_configuration(void)
     934                 :            : {
     935                 :        601 :         int rc = 0;
     936                 :            : 
     937         [ -  + ]:        601 :         if (g_iscsi.authfile != NULL) {
     938   [ #  #  #  # ]:          0 :                 if (access(g_iscsi.authfile, R_OK) == 0) {
     939                 :          0 :                         rc = iscsi_parse_auth_info();
     940         [ #  # ]:          0 :                         if (rc < 0) {
     941                 :          0 :                                 SPDK_ERRLOG("iscsi_parse_auth_info() failed\n");
     942                 :            :                         }
     943                 :            :                 } else {
     944   [ #  #  #  # ]:          0 :                         SPDK_INFOLOG(iscsi, "CHAP secret file is not found in the path %s\n",
     945                 :            :                                      g_iscsi.authfile);
     946                 :            :                 }
     947                 :            :         }
     948                 :            : 
     949                 :        601 :         iscsi_init_complete(rc);
     950                 :        601 : }
     951                 :            : 
     952                 :            : static int
     953                 : 1427333231 : iscsi_poll_group_poll(void *ctx)
     954                 :            : {
     955                 : 1427333231 :         struct spdk_iscsi_poll_group *group = ctx;
     956                 :            :         struct spdk_iscsi_conn *conn, *tmp;
     957                 :            :         int rc;
     958                 :            : 
     959         [ +  + ]: 1427333231 :         if (spdk_unlikely(STAILQ_EMPTY(&group->connections))) {
     960                 : 1287495660 :                 return SPDK_POLLER_IDLE;
     961                 :            :         }
     962                 :            : 
     963                 :  139837571 :         rc = spdk_sock_group_poll(group->sock_group);
     964         [ -  + ]:  139837571 :         if (rc < 0) {
     965                 :          0 :                 SPDK_ERRLOG("Failed to poll sock_group=%p\n", group->sock_group);
     966                 :            :         }
     967                 :            : 
     968         [ +  + ]:  331544432 :         STAILQ_FOREACH_SAFE(conn, &group->connections, pg_link, tmp) {
     969         [ +  + ]:  191706861 :                 if (conn->state == ISCSI_CONN_STATE_EXITING) {
     970                 :        575 :                         iscsi_conn_destruct(conn);
     971                 :            :                 }
     972                 :            :         }
     973                 :            : 
     974                 :  139837571 :         return rc != 0 ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
     975                 :            : }
     976                 :            : 
     977                 :            : static int
     978                 :       7937 : iscsi_poll_group_handle_nop(void *ctx)
     979                 :            : {
     980                 :       7937 :         struct spdk_iscsi_poll_group *group = ctx;
     981                 :            :         struct spdk_iscsi_conn *conn, *tmp;
     982                 :            : 
     983         [ +  + ]:      11863 :         STAILQ_FOREACH_SAFE(conn, &group->connections, pg_link, tmp) {
     984                 :       3926 :                 iscsi_conn_handle_nop(conn);
     985                 :            :         }
     986                 :            : 
     987                 :       7937 :         return SPDK_POLLER_BUSY;
     988                 :            : }
     989                 :            : 
     990                 :            : static int
     991                 :        829 : iscsi_poll_group_create(void *io_device, void *ctx_buf)
     992                 :            : {
     993                 :        829 :         struct spdk_iscsi_poll_group *pg = ctx_buf;
     994                 :            : 
     995                 :        829 :         STAILQ_INIT(&pg->connections);
     996                 :        829 :         pg->sock_group = spdk_sock_group_create(NULL);
     997         [ -  + ]:        829 :         assert(pg->sock_group != NULL);
     998                 :            : 
     999                 :        829 :         pg->poller = SPDK_POLLER_REGISTER(iscsi_poll_group_poll, pg, 0);
    1000                 :            :         /* set the period to 1 sec */
    1001                 :        829 :         pg->nop_poller = SPDK_POLLER_REGISTER(iscsi_poll_group_handle_nop, pg, 1000000);
    1002                 :            : 
    1003                 :        829 :         return 0;
    1004                 :            : }
    1005                 :            : 
    1006                 :            : static void
    1007                 :        829 : iscsi_poll_group_destroy(void *io_device, void *ctx_buf)
    1008                 :            : {
    1009                 :        829 :         struct spdk_iscsi_poll_group *pg = ctx_buf;
    1010                 :            :         struct spdk_io_channel *ch;
    1011                 :            :         struct spdk_thread *thread;
    1012                 :            : 
    1013         [ -  + ]:        829 :         assert(pg->poller != NULL);
    1014         [ -  + ]:        829 :         assert(pg->sock_group != NULL);
    1015                 :            : 
    1016                 :        829 :         spdk_sock_group_close(&pg->sock_group);
    1017                 :        829 :         spdk_poller_unregister(&pg->poller);
    1018                 :        829 :         spdk_poller_unregister(&pg->nop_poller);
    1019                 :            : 
    1020                 :        829 :         ch = spdk_io_channel_from_ctx(pg);
    1021                 :        829 :         thread = spdk_io_channel_get_thread(ch);
    1022                 :            : 
    1023         [ -  + ]:        829 :         assert(thread == spdk_get_thread());
    1024                 :            : 
    1025                 :        829 :         spdk_thread_exit(thread);
    1026                 :        829 : }
    1027                 :            : 
    1028                 :            : static void
    1029                 :        829 : _iscsi_init_thread_done(void *ctx)
    1030                 :            : {
    1031                 :        829 :         struct spdk_iscsi_poll_group *pg = ctx;
    1032                 :            : 
    1033                 :        829 :         TAILQ_INSERT_TAIL(&g_iscsi.poll_group_head, pg, link);
    1034         [ +  + ]:        829 :         if (--g_iscsi.refcnt == 0) {
    1035                 :        601 :                 iscsi_parse_configuration();
    1036                 :            :         }
    1037                 :        829 : }
    1038                 :            : 
    1039                 :            : static void
    1040                 :        829 : _iscsi_init_thread(void *ctx)
    1041                 :            : {
    1042                 :            :         struct spdk_io_channel *ch;
    1043                 :            :         struct spdk_iscsi_poll_group *pg;
    1044                 :            : 
    1045                 :        829 :         ch = spdk_get_io_channel(&g_iscsi);
    1046                 :        829 :         pg = spdk_io_channel_get_ctx(ch);
    1047                 :            : 
    1048                 :        829 :         spdk_thread_send_msg(g_init_thread, _iscsi_init_thread_done, pg);
    1049                 :        829 : }
    1050                 :            : 
    1051                 :            : static void
    1052                 :        601 : initialize_iscsi_poll_group(void)
    1053                 :            : {
    1054                 :        601 :         struct spdk_cpuset tmp_cpumask = {};
    1055                 :            :         uint32_t i;
    1056                 :        274 :         char thread_name[32];
    1057                 :            :         struct spdk_thread *thread;
    1058                 :            : 
    1059                 :        601 :         spdk_io_device_register(&g_iscsi, iscsi_poll_group_create, iscsi_poll_group_destroy,
    1060                 :            :                                 sizeof(struct spdk_iscsi_poll_group), "iscsi_tgt");
    1061                 :            : 
    1062                 :            :         /* Create threads for CPU cores active for this application, and send a
    1063                 :            :          * message to each thread to create a poll group on it.
    1064                 :            :          */
    1065                 :        601 :         g_init_thread = spdk_get_thread();
    1066         [ -  + ]:        601 :         assert(g_init_thread != NULL);
    1067         [ -  + ]:        601 :         assert(g_iscsi.refcnt == 0);
    1068                 :            : 
    1069         [ +  + ]:       1430 :         SPDK_ENV_FOREACH_CORE(i) {
    1070                 :        829 :                 spdk_cpuset_zero(&tmp_cpumask);
    1071                 :        829 :                 spdk_cpuset_set_cpu(&tmp_cpumask, i, true);
    1072         [ -  + ]:        829 :                 snprintf(thread_name, sizeof(thread_name), "iscsi_poll_group_%u", i);
    1073                 :            : 
    1074                 :        829 :                 thread = spdk_thread_create(thread_name, &tmp_cpumask);
    1075         [ -  + ]:        829 :                 assert(thread != NULL);
    1076                 :            : 
    1077                 :        829 :                 g_iscsi.refcnt++;
    1078                 :        829 :                 spdk_thread_send_msg(thread, _iscsi_init_thread, NULL);
    1079                 :            :         }
    1080                 :        601 : }
    1081                 :            : 
    1082                 :            : static int
    1083                 :        601 : iscsi_parse_globals(void)
    1084                 :            : {
    1085                 :            :         int rc;
    1086                 :            : 
    1087                 :        601 :         rc = iscsi_initialize_global_params();
    1088         [ -  + ]:        601 :         if (rc != 0) {
    1089                 :          0 :                 SPDK_ERRLOG("iscsi_initialize_iscsi_global_params() failed\n");
    1090                 :          0 :                 return rc;
    1091                 :            :         }
    1092                 :            : 
    1093                 :        601 :         g_iscsi.session = calloc(1, sizeof(struct spdk_iscsi_sess *) * g_iscsi.MaxSessions);
    1094         [ -  + ]:        601 :         if (!g_iscsi.session) {
    1095                 :          0 :                 SPDK_ERRLOG("calloc() failed for session array\n");
    1096                 :          0 :                 return -1;
    1097                 :            :         }
    1098                 :            : 
    1099                 :            :         /*
    1100                 :            :          * For now, just support same number of total connections, rather
    1101                 :            :          *  than MaxSessions * MaxConnectionsPerSession.  After we add better
    1102                 :            :          *  handling for low resource conditions from our various buffer
    1103                 :            :          *  pools, we can bump this up to support more connections.
    1104                 :            :          */
    1105                 :        601 :         g_iscsi.MaxConnections = g_iscsi.MaxSessions;
    1106                 :            : 
    1107                 :        601 :         rc = iscsi_initialize_all_pools();
    1108         [ -  + ]:        601 :         if (rc != 0) {
    1109                 :          0 :                 SPDK_ERRLOG("initialize_all_pools() failed\n");
    1110                 :          0 :                 free(g_iscsi.session);
    1111                 :          0 :                 g_iscsi.session = NULL;
    1112                 :          0 :                 return -1;
    1113                 :            :         }
    1114                 :            : 
    1115                 :        601 :         rc = initialize_iscsi_conns();
    1116         [ -  + ]:        601 :         if (rc < 0) {
    1117                 :          0 :                 SPDK_ERRLOG("initialize_iscsi_conns() failed\n");
    1118                 :          0 :                 free(g_iscsi.session);
    1119                 :          0 :                 g_iscsi.session = NULL;
    1120                 :          0 :                 return rc;
    1121                 :            :         }
    1122                 :            : 
    1123                 :        601 :         initialize_iscsi_poll_group();
    1124                 :        601 :         return 0;
    1125                 :            : }
    1126                 :            : 
    1127                 :            : void
    1128                 :        601 : spdk_iscsi_init(spdk_iscsi_init_cb cb_fn, void *cb_arg)
    1129                 :            : {
    1130                 :            :         int rc;
    1131                 :            : 
    1132         [ -  + ]:        601 :         assert(cb_fn != NULL);
    1133                 :        601 :         g_init_cb_fn = cb_fn;
    1134                 :        601 :         g_init_cb_arg = cb_arg;
    1135                 :            : 
    1136                 :        601 :         rc = iscsi_parse_globals();
    1137         [ -  + ]:        601 :         if (rc < 0) {
    1138                 :          0 :                 SPDK_ERRLOG("iscsi_parse_globals() failed\n");
    1139                 :          0 :                 iscsi_init_complete(-1);
    1140                 :            :         }
    1141                 :            : 
    1142                 :            :         /*
    1143                 :            :          * iscsi_parse_configuration() will be called as the callback to
    1144                 :            :          * spdk_initialize_iscsi_poll_group() and will complete iSCSI
    1145                 :            :          * subsystem initialization.
    1146                 :            :          */
    1147                 :        601 : }
    1148                 :            : 
    1149                 :            : void
    1150                 :        601 : spdk_iscsi_fini(spdk_iscsi_fini_cb cb_fn, void *cb_arg)
    1151                 :            : {
    1152                 :        601 :         g_fini_cb_fn = cb_fn;
    1153                 :        601 :         g_fini_cb_arg = cb_arg;
    1154                 :            : 
    1155                 :        601 :         iscsi_portal_grp_close_all();
    1156                 :        601 :         shutdown_iscsi_conns();
    1157                 :        601 : }
    1158                 :            : 
    1159                 :            : static void
    1160                 :        601 : iscsi_fini_done(void *io_device)
    1161                 :            : {
    1162                 :        601 :         g_fini_cb_fn(g_fini_cb_arg);
    1163                 :        601 : }
    1164                 :            : 
    1165                 :            : static void
    1166                 :        601 : _iscsi_fini_dev_unreg(struct spdk_io_channel_iter *i, int status)
    1167                 :            : {
    1168                 :        601 :         iscsi_check_pools();
    1169                 :        601 :         iscsi_free_pools();
    1170                 :        601 :         free(g_iscsi.session);
    1171                 :            : 
    1172         [ -  + ]:        601 :         assert(TAILQ_EMPTY(&g_iscsi.poll_group_head));
    1173                 :            : 
    1174                 :        601 :         iscsi_shutdown_tgt_nodes();
    1175                 :        601 :         iscsi_init_grps_destroy();
    1176                 :        601 :         iscsi_portal_grps_destroy();
    1177                 :        601 :         iscsi_auth_groups_destroy();
    1178                 :            : 
    1179                 :        601 :         free(g_iscsi.authfile);
    1180                 :        601 :         free(g_iscsi.nodebase);
    1181                 :            : 
    1182         [ -  + ]:        601 :         pthread_mutex_destroy(&g_iscsi.mutex);
    1183         [ +  - ]:        601 :         if (g_init_thread != NULL) {
    1184                 :            :                 /* g_init_thread is set just after the io_device is
    1185                 :            :                  * registered, so we can use it to determine if it
    1186                 :            :                  * needs to be unregistered (in cases where iscsi init
    1187                 :            :                  * fails).
    1188                 :            :                  */
    1189                 :        601 :                 spdk_io_device_unregister(&g_iscsi, iscsi_fini_done);
    1190                 :            :         } else {
    1191                 :          0 :                 iscsi_fini_done(NULL);
    1192                 :            :         }
    1193                 :        601 : }
    1194                 :            : 
    1195                 :            : static void
    1196                 :        829 : _iscsi_fini_thread(struct spdk_io_channel_iter *i)
    1197                 :            : {
    1198                 :            :         struct spdk_io_channel *ch;
    1199                 :            :         struct spdk_iscsi_poll_group *pg;
    1200                 :            : 
    1201                 :        829 :         ch = spdk_io_channel_iter_get_channel(i);
    1202                 :        829 :         pg = spdk_io_channel_get_ctx(ch);
    1203                 :            : 
    1204         [ -  + ]:        829 :         pthread_mutex_lock(&g_iscsi.mutex);
    1205         [ +  + ]:        829 :         TAILQ_REMOVE(&g_iscsi.poll_group_head, pg, link);
    1206         [ -  + ]:        829 :         pthread_mutex_unlock(&g_iscsi.mutex);
    1207                 :            : 
    1208                 :        829 :         spdk_put_io_channel(ch);
    1209                 :            : 
    1210                 :        829 :         spdk_for_each_channel_continue(i, 0);
    1211                 :        829 : }
    1212                 :            : 
    1213                 :            : void
    1214                 :        601 : shutdown_iscsi_conns_done(void)
    1215                 :            : {
    1216                 :        601 :         spdk_for_each_channel(&g_iscsi, _iscsi_fini_thread, NULL, _iscsi_fini_dev_unreg);
    1217                 :        601 : }
    1218                 :            : 
    1219                 :            : void
    1220                 :        218 : iscsi_opts_info_json(struct spdk_json_write_ctx *w)
    1221                 :            : {
    1222                 :        218 :         spdk_json_write_object_begin(w);
    1223                 :            : 
    1224         [ -  + ]:        218 :         if (g_iscsi.authfile != NULL) {
    1225                 :          0 :                 spdk_json_write_named_string(w, "auth_file", g_iscsi.authfile);
    1226                 :            :         }
    1227                 :        218 :         spdk_json_write_named_string(w, "node_base", g_iscsi.nodebase);
    1228                 :            : 
    1229                 :        218 :         spdk_json_write_named_uint32(w, "max_sessions", g_iscsi.MaxSessions);
    1230                 :        218 :         spdk_json_write_named_uint32(w, "max_connections_per_session",
    1231                 :            :                                      g_iscsi.MaxConnectionsPerSession);
    1232                 :            : 
    1233                 :        218 :         spdk_json_write_named_uint32(w, "max_queue_depth", g_iscsi.MaxQueueDepth);
    1234                 :            : 
    1235                 :        218 :         spdk_json_write_named_uint32(w, "default_time2wait", g_iscsi.DefaultTime2Wait);
    1236                 :        218 :         spdk_json_write_named_uint32(w, "default_time2retain", g_iscsi.DefaultTime2Retain);
    1237                 :            : 
    1238                 :        218 :         spdk_json_write_named_uint32(w, "first_burst_length", g_iscsi.FirstBurstLength);
    1239                 :            : 
    1240         [ -  + ]:        218 :         spdk_json_write_named_bool(w, "immediate_data", g_iscsi.ImmediateData);
    1241                 :            : 
    1242         [ -  + ]:        218 :         spdk_json_write_named_bool(w, "allow_duplicated_isid", g_iscsi.AllowDuplicateIsid);
    1243                 :            : 
    1244                 :        218 :         spdk_json_write_named_uint32(w, "error_recovery_level", g_iscsi.ErrorRecoveryLevel);
    1245                 :            : 
    1246                 :        218 :         spdk_json_write_named_int32(w, "nop_timeout", g_iscsi.timeout);
    1247                 :        218 :         spdk_json_write_named_int32(w, "nop_in_interval", g_iscsi.nopininterval);
    1248                 :            : 
    1249         [ -  + ]:        218 :         spdk_json_write_named_bool(w, "disable_chap", g_iscsi.disable_chap);
    1250         [ -  + ]:        218 :         spdk_json_write_named_bool(w, "require_chap", g_iscsi.require_chap);
    1251         [ -  + ]:        218 :         spdk_json_write_named_bool(w, "mutual_chap", g_iscsi.mutual_chap);
    1252                 :        218 :         spdk_json_write_named_int32(w, "chap_group", g_iscsi.chap_group);
    1253                 :            : 
    1254                 :        218 :         spdk_json_write_named_uint32(w, "max_large_datain_per_connection",
    1255                 :            :                                      g_iscsi.MaxLargeDataInPerConnection);
    1256                 :        218 :         spdk_json_write_named_uint32(w, "max_r2t_per_connection",
    1257                 :            :                                      g_iscsi.MaxR2TPerConnection);
    1258                 :            : 
    1259                 :        218 :         spdk_json_write_named_uint32(w, "pdu_pool_size", g_iscsi.pdu_pool_size);
    1260                 :        218 :         spdk_json_write_named_uint32(w, "immediate_data_pool_size",
    1261                 :            :                                      g_iscsi.immediate_data_pool_size);
    1262                 :        218 :         spdk_json_write_named_uint32(w, "data_out_pool_size", g_iscsi.data_out_pool_size);
    1263                 :            : 
    1264                 :        218 :         spdk_json_write_object_end(w);
    1265                 :        218 : }
    1266                 :            : 
    1267                 :            : static void
    1268                 :         52 : iscsi_auth_group_info_json(struct spdk_iscsi_auth_group *group,
    1269                 :            :                            struct spdk_json_write_ctx *w)
    1270                 :            : {
    1271                 :            :         struct spdk_iscsi_auth_secret *_secret;
    1272                 :            : 
    1273                 :         52 :         spdk_json_write_object_begin(w);
    1274                 :            : 
    1275                 :         52 :         spdk_json_write_named_int32(w, "tag", group->tag);
    1276                 :            : 
    1277                 :         52 :         spdk_json_write_named_array_begin(w, "secrets");
    1278         [ +  + ]:        140 :         TAILQ_FOREACH(_secret, &group->secret_head, tailq) {
    1279                 :         88 :                 spdk_json_write_object_begin(w);
    1280                 :            : 
    1281                 :         88 :                 spdk_json_write_named_string(w, "user", _secret->user);
    1282                 :         88 :                 spdk_json_write_named_string(w, "secret", _secret->secret);
    1283                 :            : 
    1284         [ +  - ]:         88 :                 if (_secret->muser[0] != '\0') {
    1285                 :         88 :                         spdk_json_write_named_string(w, "muser", _secret->muser);
    1286                 :         88 :                         spdk_json_write_named_string(w, "msecret", _secret->msecret);
    1287                 :            :                 }
    1288                 :            : 
    1289                 :         88 :                 spdk_json_write_object_end(w);
    1290                 :            :         }
    1291                 :         52 :         spdk_json_write_array_end(w);
    1292                 :            : 
    1293                 :         52 :         spdk_json_write_object_end(w);
    1294                 :         52 : }
    1295                 :            : 
    1296                 :            : static void
    1297                 :          0 : iscsi_auth_group_config_json(struct spdk_iscsi_auth_group *group,
    1298                 :            :                              struct spdk_json_write_ctx *w)
    1299                 :            : {
    1300                 :          0 :         spdk_json_write_object_begin(w);
    1301                 :            : 
    1302                 :          0 :         spdk_json_write_named_string(w, "method", "iscsi_create_auth_group");
    1303                 :            : 
    1304                 :          0 :         spdk_json_write_name(w, "params");
    1305                 :          0 :         iscsi_auth_group_info_json(group, w);
    1306                 :            : 
    1307                 :          0 :         spdk_json_write_object_end(w);
    1308                 :          0 : }
    1309                 :            : 
    1310                 :            : void
    1311                 :        132 : iscsi_auth_groups_info_json(struct spdk_json_write_ctx *w)
    1312                 :            : {
    1313                 :            :         struct spdk_iscsi_auth_group *group;
    1314                 :            : 
    1315         [ +  + ]:        184 :         TAILQ_FOREACH(group, &g_iscsi.auth_group_head, tailq) {
    1316                 :         52 :                 iscsi_auth_group_info_json(group, w);
    1317                 :            :         }
    1318                 :        132 : }
    1319                 :            : 
    1320                 :            : static void
    1321                 :         94 : iscsi_auth_groups_config_json(struct spdk_json_write_ctx *w)
    1322                 :            : {
    1323                 :            :         struct spdk_iscsi_auth_group *group;
    1324                 :            : 
    1325         [ -  + ]:         94 :         TAILQ_FOREACH(group, &g_iscsi.auth_group_head, tailq) {
    1326                 :          0 :                 iscsi_auth_group_config_json(group, w);
    1327                 :            :         }
    1328                 :         94 : }
    1329                 :            : 
    1330                 :            : static void
    1331                 :         94 : iscsi_opts_config_json(struct spdk_json_write_ctx *w)
    1332                 :            : {
    1333                 :         94 :         spdk_json_write_object_begin(w);
    1334                 :            : 
    1335                 :         94 :         spdk_json_write_named_string(w, "method", "iscsi_set_options");
    1336                 :            : 
    1337                 :         94 :         spdk_json_write_name(w, "params");
    1338                 :         94 :         iscsi_opts_info_json(w);
    1339                 :            : 
    1340                 :         94 :         spdk_json_write_object_end(w);
    1341                 :         94 : }
    1342                 :            : 
    1343                 :            : void
    1344                 :         94 : spdk_iscsi_config_json(struct spdk_json_write_ctx *w)
    1345                 :            : {
    1346                 :         94 :         spdk_json_write_array_begin(w);
    1347                 :         94 :         iscsi_opts_config_json(w);
    1348                 :         94 :         iscsi_portal_grps_config_json(w);
    1349                 :         94 :         iscsi_init_grps_config_json(w);
    1350                 :         94 :         iscsi_tgt_nodes_config_json(w);
    1351                 :         94 :         iscsi_auth_groups_config_json(w);
    1352                 :         94 :         spdk_json_write_array_end(w);
    1353                 :         94 : }
    1354                 :            : 
    1355                 :        675 : SPDK_LOG_REGISTER_COMPONENT(iscsi)

Generated by: LCOV version 1.14