]>
git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/lib/iscsi/portal_grp.c
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.
49 #include <sys/types.h>
51 #include "spdk/conf.h"
54 #include "spdk_internal/log.h"
56 #include "iscsi/iscsi.h"
57 #include "iscsi/tgt_node.h"
58 #include "iscsi/conn.h"
59 #include "iscsi/portal_grp.h"
61 #define PORTNUMSTRLEN 32
64 spdk_iscsi_portal_grp_open(struct spdk_iscsi_portal_grp
*pg
);
66 /* Assumes caller allocated host and port strings on the heap */
67 struct spdk_iscsi_portal
*
68 spdk_iscsi_portal_create(const char *host
, const char *port
, uint64_t cpumask
)
70 struct spdk_iscsi_portal
*p
= NULL
;
75 p
= malloc(sizeof(*p
));
77 SPDK_ERRLOG("portal malloc error (%s, %s)\n", host
, port
);
80 p
->host
= strdup(host
);
81 p
->port
= strdup(port
);
84 p
->group
= NULL
; /* set at a later time by caller */
90 spdk_iscsi_portal_destroy(struct spdk_iscsi_portal
*p
)
94 SPDK_TRACELOG(SPDK_TRACE_DEBUG
, "spdk_iscsi_portal_destroy\n");
101 spdk_iscsi_portal_create_from_configline(const char *portalstring
,
102 struct spdk_iscsi_portal
**ip
,
105 char *host
= NULL
, *port
= NULL
;
106 const char *cpumask_str
;
107 uint64_t cpumask
= 0;
112 if (portalstring
== NULL
) {
113 SPDK_ERRLOG("portal error\n");
117 if (portalstring
[0] == '[') {
119 p
= strchr(portalstring
+ 1, ']');
121 SPDK_ERRLOG("portal error\n");
125 n
= p
- portalstring
;
127 host
= malloc(n
+ 1);
132 memcpy(host
, portalstring
, n
);
137 port
= malloc(PORTNUMSTRLEN
);
142 snprintf(port
, PORTNUMSTRLEN
, "%d", DEFAULT_PORT
);
146 SPDK_ERRLOG("portal error\n");
150 q
= strchr(portalstring
, '@');
152 q
= portalstring
+ strlen(portalstring
);
156 port
= malloc(len
+ 1);
161 memset(port
, 0, len
+ 1);
162 memcpy(port
, p
+ 1, len
);
167 p
= strchr(portalstring
, ':');
169 p
= portalstring
+ strlen(portalstring
);
171 n
= p
- portalstring
;
173 host
= malloc(n
+ 1);
178 memcpy(host
, portalstring
, n
);
183 port
= malloc(PORTNUMSTRLEN
);
188 snprintf(port
, PORTNUMSTRLEN
, "%d", DEFAULT_PORT
);
192 SPDK_ERRLOG("portal error\n");
196 q
= strchr(portalstring
, '@');
198 q
= portalstring
+ strlen(portalstring
);
202 SPDK_ERRLOG("no port specified\n");
207 port
= malloc(len
+ 1);
212 memset(port
, 0, len
+ 1);
213 memcpy(port
, p
+ 1, len
);
219 p
= strchr(portalstring
, '@');
222 if (spdk_app_parse_core_mask(cpumask_str
, &cpumask
)) {
223 SPDK_ERRLOG("invalid portal cpumask %s\n", cpumask_str
);
226 if ((cpumask
& spdk_app_get_core_mask()) != cpumask
) {
227 SPDK_ERRLOG("portal cpumask %s not a subset of "
228 "reactor mask %jx\n", cpumask_str
,
229 spdk_app_get_core_mask());
233 cpumask
= spdk_app_get_core_mask();
237 *ip
= spdk_iscsi_portal_create(host
, port
, cpumask
);
251 struct spdk_iscsi_portal_grp
*
252 spdk_iscsi_portal_grp_create(int tag
)
254 struct spdk_iscsi_portal_grp
*pg
= malloc(sizeof(*pg
));
257 SPDK_ERRLOG("portal group malloc error (%d)\n", tag
);
261 /* Make sure there are no duplicate portal group tags */
262 if (spdk_iscsi_portal_grp_find_by_tag(tag
)) {
263 SPDK_ERRLOG("portal group creation failed. duplicate portal group tag (%d)\n", tag
);
268 pg
->state
= GROUP_INIT
;
272 TAILQ_INIT(&pg
->head
);
278 spdk_iscsi_portal_grp_destroy(struct spdk_iscsi_portal_grp
*pg
)
280 struct spdk_iscsi_portal
*p
;
284 SPDK_TRACELOG(SPDK_TRACE_DEBUG
, "spdk_iscsi_portal_grp_destroy\n");
285 while (!TAILQ_EMPTY(&pg
->head
)) {
286 p
= TAILQ_FIRST(&pg
->head
);
287 TAILQ_REMOVE(&pg
->head
, p
, tailq
);
288 spdk_iscsi_portal_destroy(p
);
294 spdk_iscsi_portal_grp_register(struct spdk_iscsi_portal_grp
*pg
)
297 assert(!TAILQ_EMPTY(&pg
->head
));
299 pthread_mutex_lock(&g_spdk_iscsi
.mutex
);
300 pg
->state
= GROUP_READY
;
301 TAILQ_INSERT_TAIL(&g_spdk_iscsi
.pg_head
, pg
, tailq
);
302 pthread_mutex_unlock(&g_spdk_iscsi
.mutex
);
306 * If all portals are valid, this function will take their ownership.
309 spdk_iscsi_portal_grp_create_from_portal_list(int tag
,
310 struct spdk_iscsi_portal
**portal_list
,
313 int i
= 0, rc
= 0, port
;
314 struct spdk_iscsi_portal_grp
*pg
;
316 SPDK_TRACELOG(SPDK_TRACE_DEBUG
, "add portal group (from portal list) %d\n", tag
);
318 if (num_portals
> MAX_PORTAL
) {
319 SPDK_ERRLOG("%d > MAX_PORTAL\n", num_portals
);
323 pg
= spdk_iscsi_portal_grp_create(tag
);
325 SPDK_ERRLOG("portal group creation error (%d)\n", tag
);
329 for (i
= 0; i
< num_portals
; i
++) {
330 struct spdk_iscsi_portal
*p
= portal_list
[i
];
332 SPDK_TRACELOG(SPDK_TRACE_DEBUG
,
333 "RIndex=%d, Host=%s, Port=%s, Tag=%d\n",
334 i
, p
->host
, p
->port
, tag
);
336 port
= (int)strtol(p
->port
, NULL
, 0);
337 p
->sock
= spdk_sock_listen(p
->host
, port
);
340 /* if listening failed on any port, do not register the portal group
341 * and close any previously opened. */
342 SPDK_ERRLOG("listen error %.64s:%d\n", p
->host
, port
);
345 for (--i
; i
>= 0; --i
) {
346 spdk_sock_close(portal_list
[i
]->sock
);
347 portal_list
[i
]->sock
= -1;
355 spdk_iscsi_portal_grp_destroy(pg
);
357 /* Add portals to portal group */
358 for (i
= 0; i
< num_portals
; i
++) {
359 spdk_iscsi_portal_grp_add_portal(pg
, portal_list
[i
]);
362 /* Add portal group to the end of the pg list */
363 spdk_iscsi_portal_grp_register(pg
);
370 spdk_iscsi_portal_grp_create_from_configfile(struct spdk_conf_section
*sp
)
372 struct spdk_iscsi_portal_grp
*pg
;
373 struct spdk_iscsi_portal
*p
;
375 char *label
, *portal
;
376 int portals
= 0, i
= 0, rc
= 0;
378 SPDK_TRACELOG(SPDK_TRACE_DEBUG
, "add portal group (from config file) %d\n",
379 spdk_conf_section_get_num(sp
));
381 val
= spdk_conf_section_get_val(sp
, "Comment");
383 SPDK_TRACELOG(SPDK_TRACE_DEBUG
, "Comment %s\n", val
);
386 /* counts number of definitions */
389 * label is no longer used, but we keep it in the config
390 * file definition so that we do not break existing config
393 label
= spdk_conf_section_get_nmval(sp
, "Portal", i
, 0);
394 portal
= spdk_conf_section_get_nmval(sp
, "Portal", i
, 1);
395 if (label
== NULL
|| portal
== NULL
)
397 rc
= spdk_iscsi_portal_create_from_configline(portal
, &p
, 1);
399 SPDK_ERRLOG("parse portal error (%s)\n", portal
);
405 if (portals
> MAX_PORTAL
) {
406 SPDK_ERRLOG("%d > MAX_PORTAL\n", portals
);
410 pg
= spdk_iscsi_portal_grp_create(spdk_conf_section_get_num(sp
));
412 SPDK_ERRLOG("portal group malloc error (%s)\n", spdk_conf_section_get_name(sp
));
416 for (i
= 0; i
< portals
; i
++) {
417 label
= spdk_conf_section_get_nmval(sp
, "Portal", i
, 0);
418 portal
= spdk_conf_section_get_nmval(sp
, "Portal", i
, 1);
419 if (label
== NULL
|| portal
== NULL
) {
420 spdk_iscsi_portal_grp_destroy(pg
);
421 SPDK_ERRLOG("portal error\n");
425 rc
= spdk_iscsi_portal_create_from_configline(portal
, &p
, 0);
427 spdk_iscsi_portal_grp_destroy(pg
);
428 SPDK_ERRLOG("parse portal error (%s)\n", portal
);
432 SPDK_TRACELOG(SPDK_TRACE_DEBUG
,
433 "RIndex=%d, Host=%s, Port=%s, Tag=%d\n",
434 i
, p
->host
, p
->port
, spdk_conf_section_get_num(sp
));
436 spdk_iscsi_portal_grp_add_portal(pg
, p
);
439 /* Add portal group to the end of the pg list */
440 spdk_iscsi_portal_grp_register(pg
);
449 spdk_iscsi_portal_grp_add_portal(struct spdk_iscsi_portal_grp
*pg
,
450 struct spdk_iscsi_portal
*p
)
456 TAILQ_INSERT_TAIL(&pg
->head
, p
, tailq
);
459 struct spdk_iscsi_portal_grp
*
460 spdk_iscsi_portal_grp_find_by_tag(int tag
)
462 struct spdk_iscsi_portal_grp
*pg
;
464 TAILQ_FOREACH(pg
, &g_spdk_iscsi
.pg_head
, tailq
) {
465 if (pg
->tag
== tag
) {
474 spdk_iscsi_portal_grp_array_create(void)
477 struct spdk_conf_section
*sp
;
479 TAILQ_INIT(&g_spdk_iscsi
.pg_head
);
480 sp
= spdk_conf_first_section(NULL
);
482 if (spdk_conf_section_match_prefix(sp
, "PortalGroup")) {
483 if (spdk_conf_section_get_num(sp
) == 0) {
484 SPDK_ERRLOG("Group 0 is invalid\n");
488 /* Build portal group from cfg section PortalGroup */
489 rc
= spdk_iscsi_portal_grp_create_from_configfile(sp
);
491 SPDK_ERRLOG("parse_portal_group() failed\n");
495 sp
= spdk_conf_next_section(sp
);
501 spdk_iscsi_portal_grp_array_destroy(void)
503 struct spdk_iscsi_portal_grp
*pg
, *tmp
;
505 SPDK_TRACELOG(SPDK_TRACE_DEBUG
, "spdk_iscsi_portal_grp_array_destroy\n");
506 pthread_mutex_lock(&g_spdk_iscsi
.mutex
);
507 TAILQ_FOREACH_SAFE(pg
, &g_spdk_iscsi
.pg_head
, tailq
, tmp
) {
508 pg
->state
= GROUP_DESTROY
;
509 TAILQ_REMOVE(&g_spdk_iscsi
.pg_head
, pg
, tailq
);
510 spdk_iscsi_portal_grp_destroy(pg
);
512 pthread_mutex_unlock(&g_spdk_iscsi
.mutex
);
516 spdk_iscsi_portal_grp_open(struct spdk_iscsi_portal_grp
*pg
)
518 struct spdk_iscsi_portal
*p
;
522 TAILQ_FOREACH(p
, &pg
->head
, tailq
) {
524 SPDK_TRACELOG(SPDK_TRACE_NET
, "open host %s, port %s, tag %d\n",
525 p
->host
, p
->port
, pg
->tag
);
526 port
= (int)strtol(p
->port
, NULL
, 0);
527 sock
= spdk_sock_listen(p
->host
, port
);
529 SPDK_ERRLOG("listen error %.64s:%d\n", p
->host
, port
);
539 spdk_iscsi_portal_grp_open_all(void)
541 struct spdk_iscsi_portal_grp
*pg
;
544 SPDK_TRACELOG(SPDK_TRACE_DEBUG
, "spdk_iscsi_portal_grp_open_all\n");
545 pthread_mutex_lock(&g_spdk_iscsi
.mutex
);
546 TAILQ_FOREACH(pg
, &g_spdk_iscsi
.pg_head
, tailq
) {
547 rc
= spdk_iscsi_portal_grp_open(pg
);
549 pthread_mutex_unlock(&g_spdk_iscsi
.mutex
);
553 pthread_mutex_unlock(&g_spdk_iscsi
.mutex
);
558 spdk_iscsi_portal_grp_close(struct spdk_iscsi_portal_grp
*pg
)
560 struct spdk_iscsi_portal
*p
;
562 TAILQ_FOREACH(p
, &pg
->head
, tailq
) {
564 SPDK_TRACELOG(SPDK_TRACE_NET
, "close host %s, port %s, tag %d\n",
565 p
->host
, p
->port
, pg
->tag
);
574 spdk_iscsi_portal_grp_close_all(void)
576 struct spdk_iscsi_portal_grp
*pg
;
579 SPDK_TRACELOG(SPDK_TRACE_DEBUG
, "spdk_iscsi_portal_grp_close_all\n");
580 pthread_mutex_lock(&g_spdk_iscsi
.mutex
);
581 TAILQ_FOREACH(pg
, &g_spdk_iscsi
.pg_head
, tailq
) {
582 rc
= spdk_iscsi_portal_grp_close(pg
);
584 pthread_mutex_unlock(&g_spdk_iscsi
.mutex
);
588 pthread_mutex_unlock(&g_spdk_iscsi
.mutex
);
593 spdk_iscsi_portal_grp_unregister(struct spdk_iscsi_portal_grp
*pg
)
595 struct spdk_iscsi_portal_grp
*portal_group
;
596 struct spdk_iscsi_portal_grp
*portal_group_tmp
;
599 assert(!TAILQ_EMPTY(&pg
->head
));
601 pthread_mutex_lock(&g_spdk_iscsi
.mutex
);
602 TAILQ_FOREACH_SAFE(portal_group
, &g_spdk_iscsi
.pg_head
, tailq
, portal_group_tmp
) {
603 if (portal_group
->tag
== pg
->tag
)
604 TAILQ_REMOVE(&g_spdk_iscsi
.pg_head
, portal_group
, tailq
);
606 pthread_mutex_unlock(&g_spdk_iscsi
.mutex
);
610 spdk_iscsi_portal_grp_deletable(int tag
)
613 struct spdk_iscsi_portal_grp
*pg
;
615 pthread_mutex_lock(&g_spdk_iscsi
.mutex
);
616 pg
= spdk_iscsi_portal_grp_find_by_tag(tag
);
622 if (pg
->state
!= GROUP_READY
) {
634 pg
->state
= GROUP_DESTROY
;
635 pthread_mutex_unlock(&g_spdk_iscsi
.mutex
);
640 spdk_iscsi_portal_grp_release(struct spdk_iscsi_portal_grp
*pg
)
642 spdk_iscsi_portal_grp_close(pg
);
643 spdk_iscsi_portal_grp_unregister(pg
);
644 pthread_mutex_lock(&g_spdk_iscsi
.mutex
);
645 spdk_iscsi_portal_grp_destroy(pg
);
646 pthread_mutex_unlock(&g_spdk_iscsi
.mutex
);
649 SPDK_LOG_REGISTER_TRACE_FLAG("net", SPDK_TRACE_NET
)