4 * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
5 * Copyright (c) Intel Corporation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
18 * * Neither the name of Intel Corporation nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include "spdk/stdinc.h"
37 #include "spdk/string.h"
38 #include "spdk/sock.h"
39 #include "spdk/likely.h"
41 #include "iscsi/iscsi.h"
42 #include "iscsi/init_grp.h"
43 #include "iscsi/portal_grp.h"
44 #include "iscsi/conn.h"
45 #include "iscsi/task.h"
47 #include "spdk_internal/event.h"
48 #include "spdk_internal/log.h"
50 struct spdk_iscsi_opts
*g_spdk_iscsi_opts
= NULL
;
52 static spdk_iscsi_init_cb g_init_cb_fn
= NULL
;
53 static void *g_init_cb_arg
= NULL
;
55 static spdk_iscsi_fini_cb g_fini_cb_fn
;
56 static void *g_fini_cb_arg
;
58 #define ISCSI_CONFIG_TMPL \
60 " # node name (not include optional part)\n" \
61 " # Users can optionally change this to fit their environment.\n" \
62 " NodeBase \"%s\"\n" \
67 " # socket I/O timeout sec. (polling is infinity)\n" \
70 " # authentication information for discovery session\n" \
71 " DiscoveryAuthMethod %s\n" \
72 " DiscoveryAuthGroup %s\n" \
75 " MaxConnectionsPerSession %d\n" \
76 " MaxConnections %d\n" \
77 " MaxQueueDepth %d\n" \
79 " # iSCSI initial parameters negotiate with initiators\n" \
80 " # NOTE: incorrect values might crash\n" \
81 " DefaultTime2Wait %d\n" \
82 " DefaultTime2Retain %d\n" \
84 " FirstBurstLength %d\n" \
85 " ImmediateData %s\n" \
86 " ErrorRecoveryLevel %d\n" \
90 iscsi_globals_config_text(FILE *fp
)
92 const char *authmethod
= "None";
93 char authgroup
[32] = "None";
99 if (g_spdk_iscsi
.require_chap
) {
101 } else if (g_spdk_iscsi
.mutual_chap
) {
102 authmethod
= "CHAP Mutual";
103 } else if (!g_spdk_iscsi
.disable_chap
) {
107 if (g_spdk_iscsi
.chap_group
) {
108 snprintf(authgroup
, sizeof(authgroup
), "AuthGroup%d", g_spdk_iscsi
.chap_group
);
111 fprintf(fp
, ISCSI_CONFIG_TMPL
,
112 g_spdk_iscsi
.nodebase
,
113 g_spdk_iscsi
.authfile
? "AuthFile" : "",
114 g_spdk_iscsi
.authfile
? g_spdk_iscsi
.authfile
: "",
115 g_spdk_iscsi
.timeout
, authmethod
, authgroup
,
116 g_spdk_iscsi
.MaxSessions
, g_spdk_iscsi
.MaxConnectionsPerSession
,
117 g_spdk_iscsi
.MaxConnections
,
118 g_spdk_iscsi
.MaxQueueDepth
,
119 g_spdk_iscsi
.DefaultTime2Wait
, g_spdk_iscsi
.DefaultTime2Retain
,
120 g_spdk_iscsi
.FirstBurstLength
,
121 (g_spdk_iscsi
.ImmediateData
) ? "Yes" : "No",
122 g_spdk_iscsi
.ErrorRecoveryLevel
);
125 #define ISCSI_DATA_BUFFER_ALIGNMENT (0x1000)
126 #define ISCSI_DATA_BUFFER_MASK (ISCSI_DATA_BUFFER_ALIGNMENT - 1)
129 mobj_ctor(struct spdk_mempool
*mp
, __attribute__((unused
)) void *arg
,
130 void *_m
, __attribute__((unused
)) unsigned i
)
132 struct spdk_mobj
*m
= _m
;
135 m
->buf
= (uint8_t *)m
+ sizeof(struct spdk_mobj
);
136 m
->buf
= (void *)((unsigned long)((uint8_t *)m
->buf
+ ISCSI_DATA_BUFFER_ALIGNMENT
) &
137 ~ISCSI_DATA_BUFFER_MASK
);
140 #define NUM_PDU_PER_CONNECTION(iscsi) (2 * (iscsi->MaxQueueDepth + MAX_LARGE_DATAIN_PER_CONNECTION + 8))
141 #define PDU_POOL_SIZE(iscsi) (iscsi->MaxConnections * NUM_PDU_PER_CONNECTION(iscsi))
142 #define IMMEDIATE_DATA_POOL_SIZE(iscsi) (iscsi->MaxConnections * 128)
143 #define DATA_OUT_POOL_SIZE(iscsi) (iscsi->MaxConnections * MAX_DATA_OUT_PER_CONNECTION)
146 iscsi_initialize_pdu_pool(void)
148 struct spdk_iscsi_globals
*iscsi
= &g_spdk_iscsi
;
149 int imm_mobj_size
= SPDK_BDEV_BUF_SIZE_WITH_MD(spdk_get_max_immediate_data_size()) +
150 sizeof(struct spdk_mobj
) + ISCSI_DATA_BUFFER_ALIGNMENT
;
151 int dout_mobj_size
= SPDK_BDEV_BUF_SIZE_WITH_MD(SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH
) +
152 sizeof(struct spdk_mobj
) + ISCSI_DATA_BUFFER_ALIGNMENT
;
154 /* create PDU pool */
155 iscsi
->pdu_pool
= spdk_mempool_create("PDU_Pool",
156 PDU_POOL_SIZE(iscsi
),
157 sizeof(struct spdk_iscsi_pdu
),
158 256, SPDK_ENV_SOCKET_ID_ANY
);
159 if (!iscsi
->pdu_pool
) {
160 SPDK_ERRLOG("create PDU pool failed\n");
164 iscsi
->pdu_immediate_data_pool
= spdk_mempool_create_ctor("PDU_immediate_data_Pool",
165 IMMEDIATE_DATA_POOL_SIZE(iscsi
),
167 SPDK_ENV_SOCKET_ID_ANY
,
169 if (!iscsi
->pdu_immediate_data_pool
) {
170 SPDK_ERRLOG("create PDU immediate data pool failed\n");
174 iscsi
->pdu_data_out_pool
= spdk_mempool_create_ctor("PDU_data_out_Pool",
175 DATA_OUT_POOL_SIZE(iscsi
),
177 SPDK_ENV_SOCKET_ID_ANY
,
179 if (!iscsi
->pdu_data_out_pool
) {
180 SPDK_ERRLOG("create PDU data out pool failed\n");
188 iscsi_sess_ctor(struct spdk_mempool
*pool
, void *arg
, void *session_buf
,
191 struct spdk_iscsi_globals
*iscsi
= arg
;
192 struct spdk_iscsi_sess
*sess
= session_buf
;
194 iscsi
->session
[index
] = sess
;
196 /* tsih 0 is reserved, so start tsih values at 1. */
197 sess
->tsih
= index
+ 1;
200 #define DEFAULT_TASK_POOL_SIZE 32768
203 iscsi_initialize_task_pool(void)
205 struct spdk_iscsi_globals
*iscsi
= &g_spdk_iscsi
;
207 /* create scsi_task pool */
208 iscsi
->task_pool
= spdk_mempool_create("SCSI_TASK_Pool",
209 DEFAULT_TASK_POOL_SIZE
,
210 sizeof(struct spdk_iscsi_task
),
211 128, SPDK_ENV_SOCKET_ID_ANY
);
212 if (!iscsi
->task_pool
) {
213 SPDK_ERRLOG("create task pool failed\n");
220 #define SESSION_POOL_SIZE(iscsi) (iscsi->MaxSessions)
222 iscsi_initialize_session_pool(void)
224 struct spdk_iscsi_globals
*iscsi
= &g_spdk_iscsi
;
226 iscsi
->session_pool
= spdk_mempool_create_ctor("Session_Pool",
227 SESSION_POOL_SIZE(iscsi
),
228 sizeof(struct spdk_iscsi_sess
), 0,
229 SPDK_ENV_SOCKET_ID_ANY
,
230 iscsi_sess_ctor
, iscsi
);
231 if (!iscsi
->session_pool
) {
232 SPDK_ERRLOG("create session pool failed\n");
240 iscsi_initialize_all_pools(void)
242 if (iscsi_initialize_pdu_pool() != 0) {
246 if (iscsi_initialize_session_pool() != 0) {
250 if (iscsi_initialize_task_pool() != 0) {
258 iscsi_check_pool(struct spdk_mempool
*pool
, size_t count
)
260 if (pool
&& spdk_mempool_count(pool
) != count
) {
261 SPDK_ERRLOG("spdk_mempool_count(%s) == %zu, should be %zu\n",
262 spdk_mempool_get_name(pool
), spdk_mempool_count(pool
), count
);
267 iscsi_check_pools(void)
269 struct spdk_iscsi_globals
*iscsi
= &g_spdk_iscsi
;
271 iscsi_check_pool(iscsi
->pdu_pool
, PDU_POOL_SIZE(iscsi
));
272 iscsi_check_pool(iscsi
->session_pool
, SESSION_POOL_SIZE(iscsi
));
273 iscsi_check_pool(iscsi
->pdu_immediate_data_pool
, IMMEDIATE_DATA_POOL_SIZE(iscsi
));
274 iscsi_check_pool(iscsi
->pdu_data_out_pool
, DATA_OUT_POOL_SIZE(iscsi
));
275 iscsi_check_pool(iscsi
->task_pool
, DEFAULT_TASK_POOL_SIZE
);
279 iscsi_free_pools(void)
281 struct spdk_iscsi_globals
*iscsi
= &g_spdk_iscsi
;
283 spdk_mempool_free(iscsi
->pdu_pool
);
284 spdk_mempool_free(iscsi
->session_pool
);
285 spdk_mempool_free(iscsi
->pdu_immediate_data_pool
);
286 spdk_mempool_free(iscsi
->pdu_data_out_pool
);
287 spdk_mempool_free(iscsi
->task_pool
);
290 void spdk_put_pdu(struct spdk_iscsi_pdu
*pdu
)
299 SPDK_ERRLOG("Negative PDU refcount: %p\n", pdu
);
305 spdk_mempool_put(pdu
->mobj
->mp
, (void *)pdu
->mobj
);
308 if (pdu
->data
&& !pdu
->data_from_mempool
) {
312 spdk_mempool_put(g_spdk_iscsi
.pdu_pool
, (void *)pdu
);
316 struct spdk_iscsi_pdu
*spdk_get_pdu(void)
318 struct spdk_iscsi_pdu
*pdu
;
320 pdu
= spdk_mempool_get(g_spdk_iscsi
.pdu_pool
);
322 SPDK_ERRLOG("Unable to get PDU\n");
326 /* we do not want to zero out the last part of the structure reserved for AHS and sense data */
327 memset(pdu
, 0, offsetof(struct spdk_iscsi_pdu
, ahs
));
334 iscsi_log_globals(void)
336 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "AuthFile %s\n",
337 g_spdk_iscsi
.authfile
? g_spdk_iscsi
.authfile
: "(none)");
338 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "NodeBase %s\n", g_spdk_iscsi
.nodebase
);
339 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "MaxSessions %d\n", g_spdk_iscsi
.MaxSessions
);
340 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "MaxConnectionsPerSession %d\n",
341 g_spdk_iscsi
.MaxConnectionsPerSession
);
342 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "MaxQueueDepth %d\n", g_spdk_iscsi
.MaxQueueDepth
);
343 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "DefaultTime2Wait %d\n",
344 g_spdk_iscsi
.DefaultTime2Wait
);
345 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "DefaultTime2Retain %d\n",
346 g_spdk_iscsi
.DefaultTime2Retain
);
347 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "FirstBurstLength %d\n",
348 g_spdk_iscsi
.FirstBurstLength
);
349 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "ImmediateData %s\n",
350 g_spdk_iscsi
.ImmediateData
? "Yes" : "No");
351 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "AllowDuplicateIsid %s\n",
352 g_spdk_iscsi
.AllowDuplicateIsid
? "Yes" : "No");
353 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "ErrorRecoveryLevel %d\n",
354 g_spdk_iscsi
.ErrorRecoveryLevel
);
355 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "Timeout %d\n", g_spdk_iscsi
.timeout
);
356 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "NopInInterval %d\n",
357 g_spdk_iscsi
.nopininterval
);
358 if (g_spdk_iscsi
.disable_chap
) {
359 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
,
360 "DiscoveryAuthMethod None\n");
361 } else if (!g_spdk_iscsi
.require_chap
) {
362 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
,
363 "DiscoveryAuthMethod Auto\n");
365 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
,
366 "DiscoveryAuthMethod %s %s\n",
367 g_spdk_iscsi
.require_chap
? "CHAP" : "",
368 g_spdk_iscsi
.mutual_chap
? "Mutual" : "");
371 if (g_spdk_iscsi
.chap_group
== 0) {
372 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
,
373 "DiscoveryAuthGroup None\n");
375 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
,
376 "DiscoveryAuthGroup AuthGroup%d\n",
377 g_spdk_iscsi
.chap_group
);
382 iscsi_opts_init(struct spdk_iscsi_opts
*opts
)
384 opts
->MaxSessions
= DEFAULT_MAX_SESSIONS
;
385 opts
->MaxConnectionsPerSession
= DEFAULT_MAX_CONNECTIONS_PER_SESSION
;
386 opts
->MaxQueueDepth
= DEFAULT_MAX_QUEUE_DEPTH
;
387 opts
->DefaultTime2Wait
= DEFAULT_DEFAULTTIME2WAIT
;
388 opts
->DefaultTime2Retain
= DEFAULT_DEFAULTTIME2RETAIN
;
389 opts
->FirstBurstLength
= SPDK_ISCSI_FIRST_BURST_LENGTH
;
390 opts
->ImmediateData
= DEFAULT_IMMEDIATEDATA
;
391 opts
->AllowDuplicateIsid
= false;
392 opts
->ErrorRecoveryLevel
= DEFAULT_ERRORRECOVERYLEVEL
;
393 opts
->timeout
= DEFAULT_TIMEOUT
;
394 opts
->nopininterval
= DEFAULT_NOPININTERVAL
;
395 opts
->disable_chap
= false;
396 opts
->require_chap
= false;
397 opts
->mutual_chap
= false;
398 opts
->chap_group
= 0;
399 opts
->authfile
= NULL
;
400 opts
->nodebase
= NULL
;
401 opts
->min_connections_per_core
= 0;
404 struct spdk_iscsi_opts
*
405 spdk_iscsi_opts_alloc(void)
407 struct spdk_iscsi_opts
*opts
;
409 opts
= calloc(1, sizeof(*opts
));
411 SPDK_ERRLOG("calloc() failed for iscsi options\n");
415 iscsi_opts_init(opts
);
421 spdk_iscsi_opts_free(struct spdk_iscsi_opts
*opts
)
423 free(opts
->authfile
);
424 free(opts
->nodebase
);
428 /* Deep copy of spdk_iscsi_opts */
429 struct spdk_iscsi_opts
*
430 spdk_iscsi_opts_copy(struct spdk_iscsi_opts
*src
)
432 struct spdk_iscsi_opts
*dst
;
434 dst
= calloc(1, sizeof(*dst
));
436 SPDK_ERRLOG("calloc() failed for iscsi options\n");
441 dst
->authfile
= strdup(src
->authfile
);
442 if (!dst
->authfile
) {
444 SPDK_ERRLOG("failed to strdup for auth file %s\n", src
->authfile
);
450 dst
->nodebase
= strdup(src
->nodebase
);
451 if (!dst
->nodebase
) {
454 SPDK_ERRLOG("failed to strdup for nodebase %s\n", src
->nodebase
);
459 dst
->MaxSessions
= src
->MaxSessions
;
460 dst
->MaxConnectionsPerSession
= src
->MaxConnectionsPerSession
;
461 dst
->MaxQueueDepth
= src
->MaxQueueDepth
;
462 dst
->DefaultTime2Wait
= src
->DefaultTime2Wait
;
463 dst
->DefaultTime2Retain
= src
->DefaultTime2Retain
;
464 dst
->FirstBurstLength
= src
->FirstBurstLength
;
465 dst
->ImmediateData
= src
->ImmediateData
;
466 dst
->AllowDuplicateIsid
= src
->AllowDuplicateIsid
;
467 dst
->ErrorRecoveryLevel
= src
->ErrorRecoveryLevel
;
468 dst
->timeout
= src
->timeout
;
469 dst
->nopininterval
= src
->nopininterval
;
470 dst
->disable_chap
= src
->disable_chap
;
471 dst
->require_chap
= src
->require_chap
;
472 dst
->mutual_chap
= src
->mutual_chap
;
473 dst
->chap_group
= src
->chap_group
;
474 dst
->min_connections_per_core
= 0;
480 iscsi_read_config_file_params(struct spdk_conf_section
*sp
,
481 struct spdk_iscsi_opts
*opts
)
485 int MaxConnectionsPerSession
;
487 int DefaultTime2Wait
;
488 int DefaultTime2Retain
;
489 int FirstBurstLength
;
490 int ErrorRecoveryLevel
;
493 int min_conn_per_core
= 0;
498 val
= spdk_conf_section_get_val(sp
, "Comment");
500 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "Comment %s\n", val
);
503 val
= spdk_conf_section_get_val(sp
, "AuthFile");
505 opts
->authfile
= strdup(val
);
506 if (!opts
->authfile
) {
507 SPDK_ERRLOG("strdup() failed for AuthFile\n");
512 val
= spdk_conf_section_get_val(sp
, "NodeBase");
514 opts
->nodebase
= strdup(val
);
515 if (!opts
->nodebase
) {
516 free(opts
->authfile
);
517 SPDK_ERRLOG("strdup() failed for NodeBase\n");
522 MaxSessions
= spdk_conf_section_get_intval(sp
, "MaxSessions");
523 if (MaxSessions
>= 0) {
524 opts
->MaxSessions
= MaxSessions
;
527 MaxConnectionsPerSession
= spdk_conf_section_get_intval(sp
, "MaxConnectionsPerSession");
528 if (MaxConnectionsPerSession
>= 0) {
529 opts
->MaxConnectionsPerSession
= MaxConnectionsPerSession
;
532 MaxQueueDepth
= spdk_conf_section_get_intval(sp
, "MaxQueueDepth");
533 if (MaxQueueDepth
>= 0) {
534 opts
->MaxQueueDepth
= MaxQueueDepth
;
537 DefaultTime2Wait
= spdk_conf_section_get_intval(sp
, "DefaultTime2Wait");
538 if (DefaultTime2Wait
>= 0) {
539 opts
->DefaultTime2Wait
= DefaultTime2Wait
;
542 DefaultTime2Retain
= spdk_conf_section_get_intval(sp
, "DefaultTime2Retain");
543 if (DefaultTime2Retain
>= 0) {
544 opts
->DefaultTime2Retain
= DefaultTime2Retain
;
547 FirstBurstLength
= spdk_conf_section_get_intval(sp
, "FirstBurstLength");
548 if (FirstBurstLength
>= 0) {
549 opts
->FirstBurstLength
= FirstBurstLength
;
552 opts
->ImmediateData
= spdk_conf_section_get_boolval(sp
, "ImmediateData",
553 opts
->ImmediateData
);
555 /* This option is only for test.
556 * If AllowDuplicateIsid is enabled, it allows different connections carrying
557 * TSIH=0 login the target within the same session.
559 opts
->AllowDuplicateIsid
= spdk_conf_section_get_boolval(sp
, "AllowDuplicateIsid",
560 opts
->AllowDuplicateIsid
);
562 ErrorRecoveryLevel
= spdk_conf_section_get_intval(sp
, "ErrorRecoveryLevel");
563 if (ErrorRecoveryLevel
>= 0) {
564 opts
->ErrorRecoveryLevel
= ErrorRecoveryLevel
;
566 timeout
= spdk_conf_section_get_intval(sp
, "Timeout");
568 opts
->timeout
= timeout
;
570 nopininterval
= spdk_conf_section_get_intval(sp
, "NopInInterval");
571 if (nopininterval
>= 0) {
572 opts
->nopininterval
= nopininterval
;
574 val
= spdk_conf_section_get_val(sp
, "DiscoveryAuthMethod");
577 val
= spdk_conf_section_get_nmval(sp
, "DiscoveryAuthMethod", 0, i
);
581 if (strcasecmp(val
, "CHAP") == 0) {
582 opts
->require_chap
= true;
583 } else if (strcasecmp(val
, "Mutual") == 0) {
584 opts
->require_chap
= true;
585 opts
->mutual_chap
= true;
586 } else if (strcasecmp(val
, "Auto") == 0) {
587 opts
->disable_chap
= false;
588 opts
->require_chap
= false;
589 opts
->mutual_chap
= false;
590 } else if (strcasecmp(val
, "None") == 0) {
591 opts
->disable_chap
= true;
592 opts
->require_chap
= false;
593 opts
->mutual_chap
= false;
595 SPDK_ERRLOG("unknown CHAP mode %s\n", val
);
598 if (opts
->mutual_chap
&& !opts
->require_chap
) {
599 free(opts
->authfile
);
600 free(opts
->nodebase
);
601 SPDK_ERRLOG("CHAP must set to be required when using mutual CHAP.\n");
605 val
= spdk_conf_section_get_val(sp
, "DiscoveryAuthGroup");
608 if (strcasecmp(ag_tag
, "None") == 0) {
609 opts
->chap_group
= 0;
611 if (strncasecmp(ag_tag
, "AuthGroup",
612 strlen("AuthGroup")) != 0
613 || sscanf(ag_tag
, "%*[^0-9]%d", &ag_tag_i
) != 1
615 SPDK_ERRLOG("invalid auth group %s, ignoring\n", ag_tag
);
617 opts
->chap_group
= ag_tag_i
;
621 min_conn_per_core
= spdk_conf_section_get_intval(sp
, "MinConnectionsPerCore");
622 if (min_conn_per_core
>= 0) {
623 SPDK_WARNLOG("MinConnectionsPerCore is deprecated and will be ignored.\n");
630 iscsi_opts_verify(struct spdk_iscsi_opts
*opts
)
632 if (!opts
->nodebase
) {
633 opts
->nodebase
= strdup(SPDK_ISCSI_DEFAULT_NODEBASE
);
634 if (opts
->nodebase
== NULL
) {
635 SPDK_ERRLOG("strdup() failed for default nodebase\n");
640 if (opts
->MaxSessions
== 0 || opts
->MaxSessions
> 65535) {
641 SPDK_ERRLOG("%d is invalid. MaxSessions must be more than 0 and no more than 65535\n",
646 if (opts
->MaxConnectionsPerSession
== 0 || opts
->MaxConnectionsPerSession
> 65535) {
647 SPDK_ERRLOG("%d is invalid. MaxConnectionsPerSession must be more than 0 and no more than 65535\n",
648 opts
->MaxConnectionsPerSession
);
652 if (opts
->MaxQueueDepth
== 0 || opts
->MaxQueueDepth
> 256) {
653 SPDK_ERRLOG("%d is invalid. MaxQueueDepth must be more than 0 and no more than 256\n",
654 opts
->MaxQueueDepth
);
658 if (opts
->DefaultTime2Wait
> 3600) {
659 SPDK_ERRLOG("%d is invalid. DefaultTime2Wait must be no more than 3600\n",
660 opts
->DefaultTime2Wait
);
664 if (opts
->DefaultTime2Retain
> 3600) {
665 SPDK_ERRLOG("%d is invalid. DefaultTime2Retain must be no more than 3600\n",
666 opts
->DefaultTime2Retain
);
670 if (opts
->FirstBurstLength
>= SPDK_ISCSI_MIN_FIRST_BURST_LENGTH
) {
671 if (opts
->FirstBurstLength
> SPDK_ISCSI_MAX_BURST_LENGTH
) {
672 SPDK_ERRLOG("FirstBurstLength %d shall not exceed MaxBurstLength %d\n",
673 opts
->FirstBurstLength
, SPDK_ISCSI_MAX_BURST_LENGTH
);
677 SPDK_ERRLOG("FirstBurstLength %d shall be no less than %d\n",
678 opts
->FirstBurstLength
, SPDK_ISCSI_MIN_FIRST_BURST_LENGTH
);
682 if (opts
->ErrorRecoveryLevel
> 2) {
683 SPDK_ERRLOG("ErrorRecoveryLevel %d is not supported.\n", opts
->ErrorRecoveryLevel
);
687 if (opts
->timeout
< 0) {
688 SPDK_ERRLOG("%d is invalid. timeout must not be less than 0\n", opts
->timeout
);
692 if (opts
->nopininterval
< 0 || opts
->nopininterval
> MAX_NOPININTERVAL
) {
693 SPDK_ERRLOG("%d is invalid. nopinterval must be between 0 and %d\n",
694 opts
->nopininterval
, MAX_NOPININTERVAL
);
698 if (!spdk_iscsi_check_chap_params(opts
->disable_chap
, opts
->require_chap
,
699 opts
->mutual_chap
, opts
->chap_group
)) {
700 SPDK_ERRLOG("CHAP params in opts are illegal combination\n");
708 iscsi_parse_options(struct spdk_iscsi_opts
**popts
)
710 struct spdk_iscsi_opts
*opts
;
711 struct spdk_conf_section
*sp
;
714 opts
= spdk_iscsi_opts_alloc();
716 SPDK_ERRLOG("spdk_iscsi_opts_alloc_failed() failed\n");
720 /* Process parameters */
721 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "iscsi_read_config_file_parmas\n");
722 sp
= spdk_conf_find_section(NULL
, "iSCSI");
724 rc
= iscsi_read_config_file_params(sp
, opts
);
727 SPDK_ERRLOG("iscsi_read_config_file_params() failed\n");
738 iscsi_set_global_params(struct spdk_iscsi_opts
*opts
)
742 rc
= iscsi_opts_verify(opts
);
744 SPDK_ERRLOG("spdk_iscsi_opts_verify() failed\n");
748 if (opts
->authfile
!= NULL
) {
749 g_spdk_iscsi
.authfile
= strdup(opts
->authfile
);
750 if (!g_spdk_iscsi
.authfile
) {
751 SPDK_ERRLOG("failed to strdup for auth file %s\n", opts
->authfile
);
756 g_spdk_iscsi
.nodebase
= strdup(opts
->nodebase
);
757 if (!g_spdk_iscsi
.nodebase
) {
758 SPDK_ERRLOG("failed to strdup for nodebase %s\n", opts
->nodebase
);
762 g_spdk_iscsi
.MaxSessions
= opts
->MaxSessions
;
763 g_spdk_iscsi
.MaxConnectionsPerSession
= opts
->MaxConnectionsPerSession
;
764 g_spdk_iscsi
.MaxQueueDepth
= opts
->MaxQueueDepth
;
765 g_spdk_iscsi
.DefaultTime2Wait
= opts
->DefaultTime2Wait
;
766 g_spdk_iscsi
.DefaultTime2Retain
= opts
->DefaultTime2Retain
;
767 g_spdk_iscsi
.FirstBurstLength
= opts
->FirstBurstLength
;
768 g_spdk_iscsi
.ImmediateData
= opts
->ImmediateData
;
769 g_spdk_iscsi
.AllowDuplicateIsid
= opts
->AllowDuplicateIsid
;
770 g_spdk_iscsi
.ErrorRecoveryLevel
= opts
->ErrorRecoveryLevel
;
771 g_spdk_iscsi
.timeout
= opts
->timeout
;
772 g_spdk_iscsi
.nopininterval
= opts
->nopininterval
;
773 g_spdk_iscsi
.disable_chap
= opts
->disable_chap
;
774 g_spdk_iscsi
.require_chap
= opts
->require_chap
;
775 g_spdk_iscsi
.mutual_chap
= opts
->mutual_chap
;
776 g_spdk_iscsi
.chap_group
= opts
->chap_group
;
778 if (opts
->min_connections_per_core
) {
779 SPDK_WARNLOG("iSCSI option 'min_connections_per_core' has been deprecated and will be ignored.\n");
788 spdk_iscsi_set_discovery_auth(bool disable_chap
, bool require_chap
, bool mutual_chap
,
791 if (!spdk_iscsi_check_chap_params(disable_chap
, require_chap
, mutual_chap
,
793 SPDK_ERRLOG("CHAP params are illegal combination\n");
797 pthread_mutex_lock(&g_spdk_iscsi
.mutex
);
798 g_spdk_iscsi
.disable_chap
= disable_chap
;
799 g_spdk_iscsi
.require_chap
= require_chap
;
800 g_spdk_iscsi
.mutual_chap
= mutual_chap
;
801 g_spdk_iscsi
.chap_group
= chap_group
;
802 pthread_mutex_unlock(&g_spdk_iscsi
.mutex
);
808 spdk_iscsi_auth_group_add_secret(struct spdk_iscsi_auth_group
*group
,
809 const char *user
, const char *secret
,
810 const char *muser
, const char *msecret
)
812 struct spdk_iscsi_auth_secret
*_secret
;
815 if (user
== NULL
|| secret
== NULL
) {
816 SPDK_ERRLOG("user and secret must be specified\n");
820 if (muser
!= NULL
&& msecret
== NULL
) {
821 SPDK_ERRLOG("msecret must be specified with muser\n");
825 TAILQ_FOREACH(_secret
, &group
->secret_head
, tailq
) {
826 if (strcmp(_secret
->user
, user
) == 0) {
827 SPDK_ERRLOG("user for secret is duplicated\n");
832 _secret
= calloc(1, sizeof(*_secret
));
833 if (_secret
== NULL
) {
834 SPDK_ERRLOG("calloc() failed for CHAP secret\n");
838 len
= strnlen(user
, sizeof(_secret
->user
));
839 if (len
> sizeof(_secret
->user
) - 1) {
840 SPDK_ERRLOG("CHAP user longer than %zu characters: %s\n",
841 sizeof(_secret
->user
) - 1, user
);
845 memcpy(_secret
->user
, user
, len
);
847 len
= strnlen(secret
, sizeof(_secret
->secret
));
848 if (len
> sizeof(_secret
->secret
) - 1) {
849 SPDK_ERRLOG("CHAP secret longer than %zu characters: %s\n",
850 sizeof(_secret
->secret
) - 1, secret
);
854 memcpy(_secret
->secret
, secret
, len
);
857 len
= strnlen(muser
, sizeof(_secret
->muser
));
858 if (len
> sizeof(_secret
->muser
) - 1) {
859 SPDK_ERRLOG("Mutual CHAP user longer than %zu characters: %s\n",
860 sizeof(_secret
->muser
) - 1, muser
);
864 memcpy(_secret
->muser
, muser
, len
);
866 len
= strnlen(msecret
, sizeof(_secret
->msecret
));
867 if (len
> sizeof(_secret
->msecret
) - 1) {
868 SPDK_ERRLOG("Mutual CHAP secret longer than %zu characters: %s\n",
869 sizeof(_secret
->msecret
) - 1, msecret
);
873 memcpy(_secret
->msecret
, msecret
, len
);
876 TAILQ_INSERT_TAIL(&group
->secret_head
, _secret
, tailq
);
881 spdk_iscsi_auth_group_delete_secret(struct spdk_iscsi_auth_group
*group
,
884 struct spdk_iscsi_auth_secret
*_secret
;
887 SPDK_ERRLOG("user must be specified\n");
891 TAILQ_FOREACH(_secret
, &group
->secret_head
, tailq
) {
892 if (strcmp(_secret
->user
, user
) == 0) {
897 if (_secret
== NULL
) {
898 SPDK_ERRLOG("secret is not found\n");
902 TAILQ_REMOVE(&group
->secret_head
, _secret
, tailq
);
909 spdk_iscsi_add_auth_group(int32_t tag
, struct spdk_iscsi_auth_group
**_group
)
911 struct spdk_iscsi_auth_group
*group
;
913 TAILQ_FOREACH(group
, &g_spdk_iscsi
.auth_group_head
, tailq
) {
914 if (group
->tag
== tag
) {
915 SPDK_ERRLOG("Auth group (%d) already exists\n", tag
);
920 group
= calloc(1, sizeof(*group
));
922 SPDK_ERRLOG("calloc() failed for auth group\n");
926 TAILQ_INIT(&group
->secret_head
);
929 TAILQ_INSERT_TAIL(&g_spdk_iscsi
.auth_group_head
, group
, tailq
);
936 spdk_iscsi_delete_auth_group(struct spdk_iscsi_auth_group
*group
)
938 struct spdk_iscsi_auth_secret
*_secret
, *tmp
;
940 TAILQ_REMOVE(&g_spdk_iscsi
.auth_group_head
, group
, tailq
);
942 TAILQ_FOREACH_SAFE(_secret
, &group
->secret_head
, tailq
, tmp
) {
943 TAILQ_REMOVE(&group
->secret_head
, _secret
, tailq
);
949 struct spdk_iscsi_auth_group
*
950 spdk_iscsi_find_auth_group_by_tag(int32_t tag
)
952 struct spdk_iscsi_auth_group
*group
;
954 TAILQ_FOREACH(group
, &g_spdk_iscsi
.auth_group_head
, tailq
) {
955 if (group
->tag
== tag
) {
964 iscsi_auth_groups_destroy(void)
966 struct spdk_iscsi_auth_group
*group
, *tmp
;
968 TAILQ_FOREACH_SAFE(group
, &g_spdk_iscsi
.auth_group_head
, tailq
, tmp
) {
969 spdk_iscsi_delete_auth_group(group
);
974 iscsi_parse_auth_group(struct spdk_conf_section
*sp
)
979 const char *val
, *user
, *secret
, *muser
, *msecret
;
980 struct spdk_iscsi_auth_group
*group
= NULL
;
982 val
= spdk_conf_section_get_val(sp
, "Comment");
984 SPDK_DEBUGLOG(SPDK_LOG_ISCSI
, "Comment %s\n", val
);
987 tag
= spdk_conf_section_get_num(sp
);
989 rc
= spdk_iscsi_add_auth_group(tag
, &group
);
991 SPDK_ERRLOG("Failed to add auth group\n");
996 val
= spdk_conf_section_get_nval(sp
, "Auth", i
);
1001 user
= spdk_conf_section_get_nmval(sp
, "Auth", i
, 0);
1002 secret
= spdk_conf_section_get_nmval(sp
, "Auth", i
, 1);
1003 muser
= spdk_conf_section_get_nmval(sp
, "Auth", i
, 2);
1004 msecret
= spdk_conf_section_get_nmval(sp
, "Auth", i
, 3);
1006 rc
= spdk_iscsi_auth_group_add_secret(group
, user
, secret
, muser
, msecret
);
1008 SPDK_ERRLOG("Failed to add secret to auth group\n");
1009 spdk_iscsi_delete_auth_group(group
);
1018 iscsi_parse_auth_info(void)
1020 struct spdk_conf
*config
;
1021 struct spdk_conf_section
*sp
;
1024 config
= spdk_conf_allocate();
1026 SPDK_ERRLOG("Failed to allocate config file\n");
1030 rc
= spdk_conf_read(config
, g_spdk_iscsi
.authfile
);
1032 SPDK_INFOLOG(SPDK_LOG_ISCSI
, "Failed to load auth file\n");
1033 spdk_conf_free(config
);
1037 sp
= spdk_conf_first_section(config
);
1038 while (sp
!= NULL
) {
1039 if (spdk_conf_section_match_prefix(sp
, "AuthGroup")) {
1040 if (spdk_conf_section_get_num(sp
) == 0) {
1041 SPDK_ERRLOG("Group 0 is invalid\n");
1042 iscsi_auth_groups_destroy();
1043 spdk_conf_free(config
);
1047 rc
= iscsi_parse_auth_group(sp
);
1049 SPDK_ERRLOG("parse_auth_group() failed\n");
1050 iscsi_auth_groups_destroy();
1051 spdk_conf_free(config
);
1055 sp
= spdk_conf_next_section(sp
);
1058 spdk_conf_free(config
);
1062 static struct spdk_iscsi_auth_secret
*
1063 iscsi_find_auth_secret(const char *authuser
, int ag_tag
)
1065 struct spdk_iscsi_auth_group
*group
;
1066 struct spdk_iscsi_auth_secret
*_secret
;
1068 TAILQ_FOREACH(group
, &g_spdk_iscsi
.auth_group_head
, tailq
) {
1069 if (group
->tag
== ag_tag
) {
1070 TAILQ_FOREACH(_secret
, &group
->secret_head
, tailq
) {
1071 if (strcmp(_secret
->user
, authuser
) == 0) {
1082 spdk_iscsi_chap_get_authinfo(struct iscsi_chap_auth
*auth
, const char *authuser
,
1085 struct spdk_iscsi_auth_secret
*_secret
;
1087 if (authuser
== NULL
) {
1091 if (auth
->user
[0] != '\0') {
1092 memset(auth
->user
, 0, sizeof(auth
->user
));
1093 memset(auth
->secret
, 0, sizeof(auth
->secret
));
1094 memset(auth
->muser
, 0, sizeof(auth
->muser
));
1095 memset(auth
->msecret
, 0, sizeof(auth
->msecret
));
1098 pthread_mutex_lock(&g_spdk_iscsi
.mutex
);
1100 _secret
= iscsi_find_auth_secret(authuser
, ag_tag
);
1101 if (_secret
== NULL
) {
1102 pthread_mutex_unlock(&g_spdk_iscsi
.mutex
);
1104 SPDK_ERRLOG("CHAP secret is not found: user:%s, tag:%d\n",
1109 memcpy(auth
->user
, _secret
->user
, sizeof(auth
->user
));
1110 memcpy(auth
->secret
, _secret
->secret
, sizeof(auth
->secret
));
1112 if (_secret
->muser
[0] != '\0') {
1113 memcpy(auth
->muser
, _secret
->muser
, sizeof(auth
->muser
));
1114 memcpy(auth
->msecret
, _secret
->msecret
, sizeof(auth
->msecret
));
1117 pthread_mutex_unlock(&g_spdk_iscsi
.mutex
);
1122 iscsi_initialize_global_params(void)
1126 if (!g_spdk_iscsi_opts
) {
1127 rc
= iscsi_parse_options(&g_spdk_iscsi_opts
);
1129 SPDK_ERRLOG("spdk_iscsi_parse_options() failed\n");
1134 rc
= iscsi_set_global_params(g_spdk_iscsi_opts
);
1136 SPDK_ERRLOG("spdk_iscsi_set_global_params() failed\n");
1139 spdk_iscsi_opts_free(g_spdk_iscsi_opts
);
1140 g_spdk_iscsi_opts
= NULL
;
1146 iscsi_init_complete(int rc
)
1148 spdk_iscsi_init_cb cb_fn
= g_init_cb_fn
;
1149 void *cb_arg
= g_init_cb_arg
;
1151 g_init_cb_fn
= NULL
;
1152 g_init_cb_arg
= NULL
;
1158 iscsi_poll_group_poll(void *ctx
)
1160 struct spdk_iscsi_poll_group
*group
= ctx
;
1161 struct spdk_iscsi_conn
*conn
, *tmp
;
1164 if (spdk_unlikely(STAILQ_EMPTY(&group
->connections
))) {
1168 rc
= spdk_sock_group_poll(group
->sock_group
);
1170 SPDK_ERRLOG("Failed to poll sock_group=%p\n", group
->sock_group
);
1173 STAILQ_FOREACH_SAFE(conn
, &group
->connections
, link
, tmp
) {
1174 if (conn
->state
== ISCSI_CONN_STATE_EXITING
) {
1175 spdk_iscsi_conn_destruct(conn
);
1183 iscsi_poll_group_handle_nop(void *ctx
)
1185 struct spdk_iscsi_poll_group
*group
= ctx
;
1186 struct spdk_iscsi_conn
*conn
, *tmp
;
1188 STAILQ_FOREACH_SAFE(conn
, &group
->connections
, link
, tmp
) {
1189 spdk_iscsi_conn_handle_nop(conn
);
1196 iscsi_poll_group_create(void *ctx
)
1198 struct spdk_iscsi_poll_group
*pg
;
1200 assert(g_spdk_iscsi
.poll_group
!= NULL
);
1201 pg
= &g_spdk_iscsi
.poll_group
[spdk_env_get_current_core()];
1202 pg
->core
= spdk_env_get_current_core();
1204 STAILQ_INIT(&pg
->connections
);
1205 pg
->sock_group
= spdk_sock_group_create();
1206 assert(pg
->sock_group
!= NULL
);
1208 pg
->poller
= spdk_poller_register(iscsi_poll_group_poll
, pg
, 0);
1209 /* set the period to 1 sec */
1210 pg
->nop_poller
= spdk_poller_register(iscsi_poll_group_handle_nop
, pg
, 1000000);
1214 iscsi_poll_group_destroy(void *ctx
)
1216 struct spdk_iscsi_poll_group
*pg
;
1218 assert(g_spdk_iscsi
.poll_group
!= NULL
);
1219 pg
= &g_spdk_iscsi
.poll_group
[spdk_env_get_current_core()];
1220 assert(pg
->poller
!= NULL
);
1221 assert(pg
->sock_group
!= NULL
);
1223 spdk_sock_group_close(&pg
->sock_group
);
1224 spdk_poller_unregister(&pg
->poller
);
1225 spdk_poller_unregister(&pg
->nop_poller
);
1229 initialize_iscsi_poll_group(spdk_msg_fn cpl
)
1231 size_t g_num_poll_groups
= spdk_env_get_last_core() + 1;
1233 g_spdk_iscsi
.poll_group
= calloc(g_num_poll_groups
, sizeof(struct spdk_iscsi_poll_group
));
1234 if (!g_spdk_iscsi
.poll_group
) {
1235 SPDK_ERRLOG("Failed to allocated iscsi poll group\n");
1236 iscsi_init_complete(-1);
1240 /* Send a message to each thread and create a poll group */
1241 spdk_for_each_thread(iscsi_poll_group_create
, NULL
, cpl
);
1245 iscsi_parse_configuration(void *ctx
)
1249 rc
= spdk_iscsi_parse_portal_grps();
1251 SPDK_ERRLOG("spdk_iscsi_parse_portal_grps() failed\n");
1255 rc
= spdk_iscsi_parse_init_grps();
1257 SPDK_ERRLOG("spdk_iscsi_parse_init_grps() failed\n");
1261 rc
= spdk_iscsi_parse_tgt_nodes();
1263 SPDK_ERRLOG("spdk_iscsi_parse_tgt_nodes() failed\n");
1266 if (g_spdk_iscsi
.authfile
!= NULL
) {
1267 if (access(g_spdk_iscsi
.authfile
, R_OK
) == 0) {
1268 rc
= iscsi_parse_auth_info();
1270 SPDK_ERRLOG("spdk_iscsi_parse_auth_info() failed\n");
1273 SPDK_INFOLOG(SPDK_LOG_ISCSI
, "CHAP secret file is not found in the path %s\n",
1274 g_spdk_iscsi
.authfile
);
1279 iscsi_init_complete(rc
);
1283 iscsi_parse_globals(void)
1287 rc
= iscsi_initialize_global_params();
1289 SPDK_ERRLOG("spdk_iscsi_initialize_iscsi_global_params() failed\n");
1293 g_spdk_iscsi
.session
= calloc(1, sizeof(void *) * g_spdk_iscsi
.MaxSessions
);
1294 if (!g_spdk_iscsi
.session
) {
1295 SPDK_ERRLOG("calloc() failed for session array\n");
1300 * For now, just support same number of total connections, rather
1301 * than MaxSessions * MaxConnectionsPerSession. After we add better
1302 * handling for low resource conditions from our various buffer
1303 * pools, we can bump this up to support more connections.
1305 g_spdk_iscsi
.MaxConnections
= g_spdk_iscsi
.MaxSessions
;
1307 rc
= iscsi_initialize_all_pools();
1309 SPDK_ERRLOG("spdk_initialize_all_pools() failed\n");
1310 free(g_spdk_iscsi
.session
);
1311 g_spdk_iscsi
.session
= NULL
;
1315 rc
= spdk_initialize_iscsi_conns();
1317 SPDK_ERRLOG("spdk_initialize_iscsi_conns() failed\n");
1318 free(g_spdk_iscsi
.session
);
1319 g_spdk_iscsi
.session
= NULL
;
1323 initialize_iscsi_poll_group(iscsi_parse_configuration
);
1328 spdk_iscsi_init(spdk_iscsi_init_cb cb_fn
, void *cb_arg
)
1332 assert(cb_fn
!= NULL
);
1333 g_init_cb_fn
= cb_fn
;
1334 g_init_cb_arg
= cb_arg
;
1336 rc
= iscsi_parse_globals();
1338 SPDK_ERRLOG("spdk_iscsi_parse_globals() failed\n");
1339 iscsi_init_complete(-1);
1343 * spdk_iscsi_parse_configuration() will be called as the callback to
1344 * spdk_initialize_iscsi_poll_group() and will complete iSCSI
1345 * subsystem initialization.
1350 spdk_iscsi_fini(spdk_iscsi_fini_cb cb_fn
, void *cb_arg
)
1352 g_fini_cb_fn
= cb_fn
;
1353 g_fini_cb_arg
= cb_arg
;
1355 spdk_iscsi_portal_grp_close_all();
1356 spdk_shutdown_iscsi_conns();
1357 free(g_spdk_iscsi
.session
);
1361 iscsi_fini_done(void *arg
)
1363 iscsi_check_pools();
1366 spdk_iscsi_shutdown_tgt_nodes();
1367 spdk_iscsi_init_grps_destroy();
1368 spdk_iscsi_portal_grps_destroy();
1369 iscsi_auth_groups_destroy();
1370 free(g_spdk_iscsi
.authfile
);
1371 free(g_spdk_iscsi
.nodebase
);
1372 free(g_spdk_iscsi
.poll_group
);
1374 pthread_mutex_destroy(&g_spdk_iscsi
.mutex
);
1375 g_fini_cb_fn(g_fini_cb_arg
);
1379 spdk_shutdown_iscsi_conns_done(void)
1381 if (g_spdk_iscsi
.poll_group
) {
1382 spdk_for_each_thread(iscsi_poll_group_destroy
, NULL
, iscsi_fini_done
);
1384 iscsi_fini_done(NULL
);
1389 spdk_iscsi_config_text(FILE *fp
)
1391 iscsi_globals_config_text(fp
);
1392 spdk_iscsi_portal_grps_config_text(fp
);
1393 spdk_iscsi_init_grps_config_text(fp
);
1394 spdk_iscsi_tgt_nodes_config_text(fp
);
1398 spdk_iscsi_opts_info_json(struct spdk_json_write_ctx
*w
)
1400 spdk_json_write_object_begin(w
);
1402 if (g_spdk_iscsi
.authfile
!= NULL
) {
1403 spdk_json_write_named_string(w
, "auth_file", g_spdk_iscsi
.authfile
);
1405 spdk_json_write_named_string(w
, "node_base", g_spdk_iscsi
.nodebase
);
1407 spdk_json_write_named_uint32(w
, "max_sessions", g_spdk_iscsi
.MaxSessions
);
1408 spdk_json_write_named_uint32(w
, "max_connections_per_session",
1409 g_spdk_iscsi
.MaxConnectionsPerSession
);
1411 spdk_json_write_named_uint32(w
, "max_queue_depth", g_spdk_iscsi
.MaxQueueDepth
);
1413 spdk_json_write_named_uint32(w
, "default_time2wait", g_spdk_iscsi
.DefaultTime2Wait
);
1414 spdk_json_write_named_uint32(w
, "default_time2retain", g_spdk_iscsi
.DefaultTime2Retain
);
1416 spdk_json_write_named_uint32(w
, "first_burst_length", g_spdk_iscsi
.FirstBurstLength
);
1418 spdk_json_write_named_bool(w
, "immediate_data", g_spdk_iscsi
.ImmediateData
);
1420 spdk_json_write_named_bool(w
, "allow_duplicated_isid", g_spdk_iscsi
.AllowDuplicateIsid
);
1422 spdk_json_write_named_uint32(w
, "error_recovery_level", g_spdk_iscsi
.ErrorRecoveryLevel
);
1424 spdk_json_write_named_int32(w
, "nop_timeout", g_spdk_iscsi
.timeout
);
1425 spdk_json_write_named_int32(w
, "nop_in_interval", g_spdk_iscsi
.nopininterval
);
1427 spdk_json_write_named_bool(w
, "disable_chap", g_spdk_iscsi
.disable_chap
);
1428 spdk_json_write_named_bool(w
, "require_chap", g_spdk_iscsi
.require_chap
);
1429 spdk_json_write_named_bool(w
, "mutual_chap", g_spdk_iscsi
.mutual_chap
);
1430 spdk_json_write_named_int32(w
, "chap_group", g_spdk_iscsi
.chap_group
);
1432 spdk_json_write_object_end(w
);
1436 iscsi_auth_group_info_json(struct spdk_iscsi_auth_group
*group
,
1437 struct spdk_json_write_ctx
*w
)
1439 struct spdk_iscsi_auth_secret
*_secret
;
1441 spdk_json_write_object_begin(w
);
1443 spdk_json_write_named_int32(w
, "tag", group
->tag
);
1445 spdk_json_write_named_array_begin(w
, "secrets");
1446 TAILQ_FOREACH(_secret
, &group
->secret_head
, tailq
) {
1447 spdk_json_write_object_begin(w
);
1449 spdk_json_write_named_string(w
, "user", _secret
->user
);
1450 spdk_json_write_named_string(w
, "secret", _secret
->secret
);
1452 if (_secret
->muser
[0] != '\0') {
1453 spdk_json_write_named_string(w
, "muser", _secret
->muser
);
1454 spdk_json_write_named_string(w
, "msecret", _secret
->msecret
);
1457 spdk_json_write_object_end(w
);
1459 spdk_json_write_array_end(w
);
1461 spdk_json_write_object_end(w
);
1465 iscsi_auth_group_config_json(struct spdk_iscsi_auth_group
*group
,
1466 struct spdk_json_write_ctx
*w
)
1468 spdk_json_write_object_begin(w
);
1470 spdk_json_write_named_string(w
, "method", "add_iscsi_auth_group");
1472 spdk_json_write_name(w
, "params");
1473 iscsi_auth_group_info_json(group
, w
);
1475 spdk_json_write_object_end(w
);
1479 spdk_iscsi_auth_groups_info_json(struct spdk_json_write_ctx
*w
)
1481 struct spdk_iscsi_auth_group
*group
;
1483 TAILQ_FOREACH(group
, &g_spdk_iscsi
.auth_group_head
, tailq
) {
1484 iscsi_auth_group_info_json(group
, w
);
1489 iscsi_auth_groups_config_json(struct spdk_json_write_ctx
*w
)
1491 struct spdk_iscsi_auth_group
*group
;
1493 TAILQ_FOREACH(group
, &g_spdk_iscsi
.auth_group_head
, tailq
) {
1494 iscsi_auth_group_config_json(group
, w
);
1499 iscsi_opts_config_json(struct spdk_json_write_ctx
*w
)
1501 spdk_json_write_object_begin(w
);
1503 spdk_json_write_named_string(w
, "method", "set_iscsi_options");
1505 spdk_json_write_name(w
, "params");
1506 spdk_iscsi_opts_info_json(w
);
1508 spdk_json_write_object_end(w
);
1512 spdk_iscsi_config_json(struct spdk_json_write_ctx
*w
)
1514 spdk_json_write_array_begin(w
);
1515 iscsi_opts_config_json(w
);
1516 spdk_iscsi_portal_grps_config_json(w
);
1517 spdk_iscsi_init_grps_config_json(w
);
1518 spdk_iscsi_tgt_nodes_config_json(w
);
1519 iscsi_auth_groups_config_json(w
);
1520 spdk_json_write_array_end(w
);
1523 SPDK_LOG_REGISTER_COMPONENT("iscsi", SPDK_LOG_ISCSI
)