Annotation of embedaddon/istgt/src/istgt.c, revision 1.1.1.2
1.1 misho 1: /*
1.1.1.2 ! misho 2: * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
1.1 misho 3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: *
14: * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17: * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24: * SUCH DAMAGE.
25: *
26: */
27:
28: #ifdef HAVE_CONFIG_H
29: #include "config.h"
30: #endif
31:
32: #include <inttypes.h>
33: #include <stdint.h>
34:
35: #include <errno.h>
36: #include <stdarg.h>
37: #include <stdio.h>
38: #include <stdlib.h>
39: #include <string.h>
40: #include <poll.h>
41: #include <pthread.h>
42: #ifdef HAVE_PTHREAD_NP_H
43: #include <pthread_np.h>
44: #endif
45: #include <fcntl.h>
46: #include <unistd.h>
47: #include <signal.h>
48:
49: #include <sys/types.h>
50: #include <sys/socket.h>
51: #include <netinet/in.h>
52:
53: #include "istgt.h"
54: #include "istgt_ver.h"
55: #include "istgt_log.h"
56: #include "istgt_conf.h"
57: #include "istgt_sock.h"
58: #include "istgt_misc.h"
59: #include "istgt_crc32c.h"
60: #include "istgt_iscsi.h"
61: #include "istgt_lu.h"
62: #include "istgt_proto.h"
63:
64: #ifdef ISTGT_USE_KQUEUE
65: #include <sys/types.h>
66: #include <sys/event.h>
67: #include <sys/time.h>
68: #endif
69:
1.1.1.2 ! misho 70: #if !defined(__GNUC__)
! 71: #undef __attribute__
! 72: #define __attribute__(x)
! 73: #endif
! 74:
! 75: #define POLLWAIT 5000
1.1 misho 76: #define PORTNUMLEN 32
77:
78: ISTGT g_istgt;
79:
80: static int
81: istgt_parse_portal(const char *portal, char **host, char **port)
82: {
83: const char *p;
84: int n;
85:
86: if (portal == NULL) {
87: ISTGT_ERRLOG("portal error\n");
88: return -1;
89: }
90:
91: if (portal[0] == '[') {
92: /* IPv6 */
93: p = strchr(portal + 1, ']');
94: if (p == NULL) {
95: ISTGT_ERRLOG("portal error\n");
96: return -1;
97: }
98: p++;
99: n = p - portal;
1.1.1.2 ! misho 100: if (host != NULL) {
! 101: *host = xmalloc(n + 1);
! 102: memcpy(*host, portal, n);
! 103: (*host)[n] = '\0';
! 104: }
1.1 misho 105: if (p[0] == '\0') {
1.1.1.2 ! misho 106: if (port != NULL) {
! 107: *port = xmalloc(PORTNUMLEN);
! 108: snprintf(*port, PORTNUMLEN, "%d", DEFAULT_PORT);
! 109: }
1.1 misho 110: } else {
111: if (p[0] != ':') {
112: ISTGT_ERRLOG("portal error\n");
1.1.1.2 ! misho 113: if (host != NULL)
! 114: xfree(*host);
1.1 misho 115: return -1;
116: }
1.1.1.2 ! misho 117: if (port != NULL)
! 118: *port = xstrdup(p + 1);
1.1 misho 119: }
120: } else {
121: /* IPv4 */
122: p = strchr(portal, ':');
123: if (p == NULL) {
124: p = portal + strlen(portal);
125: }
126: n = p - portal;
1.1.1.2 ! misho 127: if (host != NULL) {
! 128: *host = xmalloc(n + 1);
! 129: memcpy(*host, portal, n);
! 130: (*host)[n] = '\0';
! 131: }
1.1 misho 132: if (p[0] == '\0') {
1.1.1.2 ! misho 133: if (port != NULL) {
! 134: *port = xmalloc(PORTNUMLEN);
! 135: snprintf(*port, PORTNUMLEN, "%d", DEFAULT_PORT);
! 136: }
1.1 misho 137: } else {
138: if (p[0] != ':') {
139: ISTGT_ERRLOG("portal error\n");
1.1.1.2 ! misho 140: if (host != NULL)
! 141: xfree(*host);
1.1 misho 142: return -1;
143: }
1.1.1.2 ! misho 144: if (port != NULL)
! 145: *port = xstrdup(p + 1);
1.1 misho 146: }
147: }
148: return 0;
149: }
150:
151: static int
1.1.1.2 ! misho 152: istgt_add_portal_group(ISTGT_Ptr istgt, CF_SECTION *sp, int *pgp_idx)
1.1 misho 153: {
1.1.1.2 ! misho 154: const char *val;
1.1 misho 155: char *label, *portal, *host, *port;
1.1.1.2 ! misho 156: int alloc_len;
! 157: int idx, free_idx;
! 158: int portals;
1.1 misho 159: int rc;
1.1.1.2 ! misho 160: int i;
1.1 misho 161:
1.1.1.2 ! misho 162: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "add portal group %d\n", sp->num);
! 163:
! 164: val = istgt_get_val(sp, "Comment");
! 165: if (val != NULL) {
! 166: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Comment %s\n", val);
1.1 misho 167: }
168:
1.1.1.2 ! misho 169: /* counts number of definition */
! 170: for (i = 0; ; i++) {
! 171: label = istgt_get_nmval(sp, "Portal", i, 0);
! 172: portal = istgt_get_nmval(sp, "Portal", i, 1);
! 173: if (label == NULL || portal == NULL)
! 174: break;
! 175: rc = istgt_parse_portal(portal, NULL, NULL);
! 176: if (rc < 0) {
! 177: ISTGT_ERRLOG("parse portal error (%s)\n", portal);
! 178: return -1;
! 179: }
! 180: }
! 181: portals = i;
! 182: if (portals > MAX_PORTAL) {
! 183: ISTGT_ERRLOG("%d > MAX_PORTAL\n", portals);
1.1 misho 184: return -1;
185: }
186:
1.1.1.2 ! misho 187: MTX_LOCK(&istgt->mutex);
! 188: idx = istgt->nportal_group;
! 189: free_idx = -1;
! 190: for (i = 0; i < istgt->nportal_group; i++) {
! 191: if (istgt->portal_group[i].tag != 0)
! 192: continue;
! 193: if (istgt->portal_group[i].nportals == portals) {
! 194: free_idx = i;
! 195: break;
! 196: }
! 197: }
! 198: if (free_idx >= 0)
! 199: idx = free_idx;
1.1 misho 200: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
1.1.1.2 ! misho 201: "Index=%d, Tag=%d, Portals=%d\n",
! 202: idx, sp->num, portals);
! 203: if (idx < MAX_PORTAL_GROUP) {
! 204: if (free_idx < 0) {
! 205: istgt->portal_group[idx].nportals = portals;
! 206: alloc_len = sizeof (PORTAL *) * portals;
! 207: istgt->portal_group[idx].portals = xmalloc(alloc_len);
! 208: }
! 209: istgt->portal_group[idx].ref = 0;
! 210: istgt->portal_group[idx].idx = idx;
! 211: istgt->portal_group[idx].tag = sp->num;
! 212:
! 213: for (i = 0; i < portals; i++) {
! 214: label = istgt_get_nmval(sp, "Portal", i, 0);
! 215: portal = istgt_get_nmval(sp, "Portal", i, 1);
! 216: if (label == NULL || portal == NULL) {
! 217: if (free_idx < 0) {
! 218: xfree(istgt->portal_group[idx].portals);
! 219: istgt->portal_group[idx].nportals = 0;
! 220: }
! 221: istgt->portal_group[idx].tag = 0;
! 222: MTX_UNLOCK(&istgt->mutex);
! 223: ISTGT_ERRLOG("portal error\n");
! 224: return -1;
! 225: }
! 226: rc = istgt_parse_portal(portal, &host, &port);
! 227: if (rc < 0) {
! 228: if (free_idx < 0) {
! 229: xfree(istgt->portal_group[idx].portals);
! 230: istgt->portal_group[idx].nportals = 0;
! 231: }
! 232: istgt->portal_group[idx].tag = 0;
! 233: MTX_UNLOCK(&istgt->mutex);
! 234: ISTGT_ERRLOG("parse portal error (%s)\n", portal);
! 235: return -1;
! 236: }
! 237: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
! 238: "RIndex=%d, Host=%s, Port=%s, Tag=%d\n",
! 239: i, host, port, sp->num);
! 240:
! 241: if (free_idx < 0) {
! 242: istgt->portal_group[idx].portals[i] = xmalloc(sizeof (PORTAL));
! 243: } else {
! 244: xfree(istgt->portal_group[idx].portals[i]->label);
! 245: xfree(istgt->portal_group[idx].portals[i]->host);
! 246: xfree(istgt->portal_group[idx].portals[i]->port);
! 247: }
! 248: istgt->portal_group[idx].portals[i]->label = xstrdup(label);
! 249: istgt->portal_group[idx].portals[i]->host = host;
! 250: istgt->portal_group[idx].portals[i]->port = port;
! 251: istgt->portal_group[idx].portals[i]->ref = 0;
! 252: istgt->portal_group[idx].portals[i]->idx = i;
! 253: istgt->portal_group[idx].portals[i]->tag = sp->num;
! 254: istgt->portal_group[idx].portals[i]->sock = -1;
! 255: }
! 256:
! 257: if (pgp_idx != NULL)
! 258: *pgp_idx = idx;
! 259: if (free_idx < 0) {
! 260: idx++;
! 261: istgt->nportal_group = idx;
! 262: }
1.1 misho 263: } else {
1.1.1.2 ! misho 264: MTX_UNLOCK(&istgt->mutex);
! 265: ISTGT_ERRLOG("nportal_group(%d) >= MAX_PORTAL_GROUP\n", idx);
1.1 misho 266: return -1;
267: }
1.1.1.2 ! misho 268: MTX_UNLOCK(&istgt->mutex);
1.1 misho 269: return 0;
270: }
271:
272: static int
1.1.1.2 ! misho 273: istgt_pg_match_all(PORTAL_GROUP *pgp, CF_SECTION *sp)
! 274: {
! 275: char *label, *portal, *host, *port;
! 276: int rc;
! 277: int i;
! 278:
! 279: for (i = 0; i < pgp->nportals; i++) {
! 280: label = istgt_get_nmval(sp, "Portal", i, 0);
! 281: portal = istgt_get_nmval(sp, "Portal", i, 1);
! 282: if (label == NULL || portal == NULL)
! 283: return 0;
! 284: rc = istgt_parse_portal(portal, &host, &port);
! 285: if (rc < 0)
! 286: return 0;
! 287: if (strcmp(pgp->portals[i]->label, label) != 0)
! 288: return 0;
! 289: if (strcmp(pgp->portals[i]->host, host) != 0)
! 290: return 0;
! 291: if (strcmp(pgp->portals[i]->port, port) != 0)
! 292: return 0;
! 293: }
! 294: label = istgt_get_nmval(sp, "Portal", i, 0);
! 295: portal = istgt_get_nmval(sp, "Portal", i, 1);
! 296: if (label != NULL || portal != NULL)
! 297: return 0;
! 298: return 1;
! 299: }
! 300:
! 301: static int
! 302: istgt_update_portal_group(ISTGT_Ptr istgt, CF_SECTION *sp, int *pgp_idx)
1.1 misho 303: {
304: const char *val;
1.1.1.2 ! misho 305: char *label, *portal, *host, *port;
! 306: int alloc_len;
! 307: int idx, free_idx;
! 308: int portals;
1.1 misho 309: int rc;
310: int i;
311:
1.1.1.2 ! misho 312: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "update portal group %d\n", sp->num);
! 313:
! 314: val = istgt_get_val(sp, "Comment");
! 315: if (val != NULL) {
! 316: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Comment %s\n", val);
! 317: }
! 318:
! 319: /* counts number of definition */
! 320: for (i = 0; ; i++) {
! 321: label = istgt_get_nmval(sp, "Portal", i, 0);
! 322: portal = istgt_get_nmval(sp, "Portal", i, 1);
! 323: if (label == NULL || portal == NULL)
! 324: break;
! 325: rc = istgt_parse_portal(portal, NULL, NULL);
! 326: if (rc < 0) {
! 327: ISTGT_ERRLOG("parse portal error (%s)\n", portal);
! 328: return -1;
! 329: }
! 330: }
! 331: portals = i;
! 332: if (portals > MAX_PORTAL) {
! 333: ISTGT_ERRLOG("%d > MAX_PORTAL\n", portals);
! 334: return -1;
! 335: }
! 336:
! 337: MTX_LOCK(&istgt->mutex);
! 338: idx = -1;
! 339: for (i = 0; i < istgt->nportal_group; i++) {
! 340: if (istgt->portal_group[i].tag == sp->num) {
! 341: idx = i;
! 342: break;
! 343: }
! 344: }
! 345: if (idx < 0) {
! 346: MTX_UNLOCK(&istgt->mutex);
! 347: ISTGT_ERRLOG("can't find PG%d\n", sp->num);
! 348: return -1;
! 349: }
! 350: if (istgt_pg_match_all(&istgt->portal_group[i], sp)) {
! 351: MTX_UNLOCK(&istgt->mutex);
! 352: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "skip for PG%d\n", sp->num);
! 353: return 0;
! 354: }
! 355: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
! 356: "Index=%d, Tag=%d, Portals=%d\n",
! 357: idx, sp->num, portals);
! 358: if (istgt->portal_group[idx].nportals == portals) {
! 359: /* udpate PG */
! 360: for (i = 0; i < portals; i++) {
! 361: label = istgt_get_nmval(sp, "Portal", i, 0);
! 362: portal = istgt_get_nmval(sp, "Portal", i, 1);
! 363: if (label == NULL || portal == NULL) {
! 364: xfree(istgt->portal_group[idx].portals);
! 365: istgt->portal_group[idx].nportals = 0;
! 366: istgt->portal_group[idx].tag = 0;
! 367: MTX_UNLOCK(&istgt->mutex);
! 368: ISTGT_ERRLOG("portal error\n");
1.1 misho 369: return -1;
370: }
1.1.1.2 ! misho 371: rc = istgt_parse_portal(portal, &host, &port);
! 372: if (rc < 0) {
! 373: xfree(istgt->portal_group[idx].portals);
! 374: istgt->portal_group[idx].nportals = 0;
! 375: istgt->portal_group[idx].tag = 0;
! 376: MTX_UNLOCK(&istgt->mutex);
! 377: ISTGT_ERRLOG("parse portal error (%s)\n", portal);
1.1 misho 378: return -1;
379: }
1.1.1.2 ! misho 380: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
! 381: "RIndex=%d, Host=%s, Port=%s, Tag=%d\n",
! 382: i, host, port, sp->num);
1.1 misho 383:
1.1.1.2 ! misho 384: /* free old PG */
! 385: xfree(istgt->portal_group[idx].portals[i]->label);
! 386: xfree(istgt->portal_group[idx].portals[i]->host);
! 387: xfree(istgt->portal_group[idx].portals[i]->port);
! 388:
! 389: /* allocate new PG */
! 390: istgt->portal_group[idx].portals[i]->label = xstrdup(label);
! 391: istgt->portal_group[idx].portals[i]->host = host;
! 392: istgt->portal_group[idx].portals[i]->port = port;
! 393: //istgt->portal_group[idx].portals[i]->ref = 0;
! 394: //istgt->portal_group[idx].portals[i]->idx = i;
! 395: //istgt->portal_group[idx].portals[i]->tag = sp->num;
! 396: //istgt->portal_group[idx].portals[i]->sock = -1;
! 397: }
! 398: if (pgp_idx != NULL)
! 399: *pgp_idx = idx;
! 400: } else {
! 401: /* mark as free */
! 402: istgt->portal_group[*pgp_idx].tag = 0;
! 403:
! 404: /* allocate new PG */
! 405: idx = istgt->nportal_group;
! 406: free_idx = -1;
! 407: for (i = 0; i < istgt->nportal_group; i++) {
! 408: if (istgt->portal_group[i].tag != 0)
! 409: continue;
! 410: if (istgt->portal_group[i].nportals == portals) {
! 411: free_idx = i;
! 412: break;
1.1 misho 413: }
1.1.1.2 ! misho 414: }
! 415: if (free_idx >= 0)
! 416: idx = free_idx;
! 417: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
! 418: "Index=%d, Tag=%d, Portals=%d -> %d\n",
! 419: idx, sp->num, istgt->portal_group[*pgp_idx].nportals, portals);
! 420: if (idx < MAX_PORTAL_GROUP) {
! 421: if (free_idx < 0) {
! 422: istgt->portal_group[idx].nportals = portals;
! 423: alloc_len = sizeof (PORTAL *) * portals;
! 424: istgt->portal_group[idx].portals = xmalloc(alloc_len);
! 425: }
! 426: istgt->portal_group[idx].ref = istgt->portal_group[*pgp_idx].ref;
! 427: istgt->portal_group[idx].idx = idx;
! 428: istgt->portal_group[idx].tag = sp->num;
! 429:
! 430: for (i = 0; i < portals; i++) {
! 431: label = istgt_get_nmval(sp, "Portal", i, 0);
! 432: portal = istgt_get_nmval(sp, "Portal", i, 1);
! 433: if (label == NULL || portal == NULL) {
! 434: if (free_idx < 0) {
! 435: xfree(istgt->portal_group[idx].portals);
! 436: istgt->portal_group[idx].nportals = 0;
! 437: }
! 438: istgt->portal_group[idx].tag = 0;
! 439: MTX_UNLOCK(&istgt->mutex);
! 440: ISTGT_ERRLOG("portal error\n");
! 441: return -1;
! 442: }
! 443: rc = istgt_parse_portal(portal, &host, &port);
1.1 misho 444: if (rc < 0) {
1.1.1.2 ! misho 445: if (free_idx < 0) {
! 446: xfree(istgt->portal_group[idx].portals);
! 447: istgt->portal_group[idx].nportals = 0;
! 448: }
! 449: istgt->portal_group[idx].tag = 0;
! 450: MTX_UNLOCK(&istgt->mutex);
! 451: ISTGT_ERRLOG("parse portal error (%s)\n", portal);
1.1 misho 452: return -1;
453: }
1.1.1.2 ! misho 454: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
! 455: "RIndex=%d, Host=%s, Port=%s, Tag=%d\n",
! 456: i, host, port, sp->num);
! 457:
! 458: if (free_idx < 0) {
! 459: istgt->portal_group[idx].portals[i] = xmalloc(sizeof (PORTAL));
! 460: } else {
! 461: xfree(istgt->portal_group[idx].portals[i]->label);
! 462: xfree(istgt->portal_group[idx].portals[i]->host);
! 463: xfree(istgt->portal_group[idx].portals[i]->port);
! 464: }
! 465: istgt->portal_group[idx].portals[i]->label = xstrdup(label);
! 466: istgt->portal_group[idx].portals[i]->host = host;
! 467: istgt->portal_group[idx].portals[i]->port = port;
! 468: istgt->portal_group[idx].portals[i]->ref = 0;
! 469: istgt->portal_group[idx].portals[i]->idx = i;
! 470: istgt->portal_group[idx].portals[i]->tag = sp->num;
! 471: istgt->portal_group[idx].portals[i]->sock = -1;
! 472: }
! 473:
! 474: if (pgp_idx != NULL)
! 475: *pgp_idx = idx;
! 476: if (free_idx < 0) {
! 477: idx++;
! 478: istgt->nportal_group = idx;
! 479: }
! 480: } else {
! 481: MTX_UNLOCK(&istgt->mutex);
! 482: ISTGT_ERRLOG("nportal_group(%d) >= MAX_PORTAL_GROUP\n", idx);
! 483: return -1;
! 484: }
! 485: }
! 486: MTX_UNLOCK(&istgt->mutex);
! 487: return 1;
! 488: }
! 489:
! 490: static int
! 491: istgt_build_portal_group_array(ISTGT_Ptr istgt)
! 492: {
! 493: CF_SECTION *sp;
! 494: int rc;
! 495:
! 496: sp = istgt->config->section;
! 497: while (sp != NULL) {
! 498: if (sp->type == ST_PORTALGROUP) {
! 499: if (sp->num == 0) {
! 500: ISTGT_ERRLOG("Group 0 is invalid\n");
! 501: return -1;
! 502: }
! 503: rc = istgt_add_portal_group(istgt, sp, NULL);
! 504: if (rc < 0) {
! 505: ISTGT_ERRLOG("add_portal_group() failed\n");
! 506: return -1;
1.1 misho 507: }
508: }
509: sp = sp->next;
510: }
511: return 0;
512: }
513:
514: static void
1.1.1.2 ! misho 515: istgt_destroy_portal_group_array(ISTGT_Ptr istgt)
1.1 misho 516: {
1.1.1.2 ! misho 517: int i, j;
1.1 misho 518:
1.1.1.2 ! misho 519: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_destory_portal_group_array\n");
! 520: MTX_LOCK(&istgt->mutex);
! 521: for (i = 0; i < istgt->nportal_group; i++) {
! 522: for (j = 0; j < istgt->portal_group[i].nportals; j++) {
! 523: xfree(istgt->portal_group[i].portals[j]->label);
! 524: xfree(istgt->portal_group[i].portals[j]->host);
! 525: xfree(istgt->portal_group[i].portals[j]->port);
! 526: xfree(istgt->portal_group[i].portals[j]);
! 527: }
! 528: xfree(istgt->portal_group[i].portals);
! 529:
! 530: istgt->portal_group[i].nportals = 0;
! 531: istgt->portal_group[i].portals = NULL;
! 532: istgt->portal_group[i].ref = 0;
! 533: istgt->portal_group[i].idx = i;
! 534: istgt->portal_group[i].tag = 0;
1.1 misho 535: }
1.1.1.2 ! misho 536: istgt->nportal_group = 0;
! 537: MTX_UNLOCK(&istgt->mutex);
1.1 misho 538: }
539:
540: static int
1.1.1.2 ! misho 541: istgt_open_portal_group(PORTAL_GROUP *pgp)
1.1 misho 542: {
543: int port;
544: int sock;
545: int i;
546:
1.1.1.2 ! misho 547: for (i = 0; i < pgp->nportals; i++) {
! 548: if (pgp->portals[i]->sock < 0) {
! 549: ISTGT_TRACELOG(ISTGT_TRACE_NET, "open host %s, port %s, tag %d\n",
! 550: pgp->portals[i]->host, pgp->portals[i]->port,
! 551: pgp->portals[i]->tag);
! 552: port = (int)strtol(pgp->portals[i]->port, NULL, 0);
! 553: sock = istgt_listen(pgp->portals[i]->host, port);
1.1 misho 554: if (sock < 0) {
555: ISTGT_ERRLOG("listen error %.64s:%d\n",
1.1.1.2 ! misho 556: pgp->portals[i]->host, port);
1.1 misho 557: return -1;
558: }
1.1.1.2 ! misho 559: pgp->portals[i]->sock = sock;
! 560: }
! 561: }
! 562: return 0;
! 563: }
! 564:
! 565: static int
! 566: istgt_open_all_portals(ISTGT_Ptr istgt)
! 567: {
! 568: int rc;
! 569: int i;
! 570:
! 571: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_open_portal\n");
! 572: MTX_LOCK(&istgt->mutex);
! 573: for (i = 0; i < istgt->nportal_group; i++) {
! 574: rc = istgt_open_portal_group(&istgt->portal_group[i]);
! 575: if (rc < 0) {
! 576: MTX_UNLOCK(&istgt->mutex);
! 577: return -1;
! 578: }
! 579: }
! 580: MTX_UNLOCK(&istgt->mutex);
! 581: return 0;
! 582: }
! 583:
! 584: static int
! 585: istgt_close_portal_group(PORTAL_GROUP *pgp)
! 586: {
! 587: int i;
! 588:
! 589: for (i = 0; i < pgp->nportals; i++) {
! 590: if (pgp->portals[i]->sock >= 0) {
! 591: ISTGT_TRACELOG(ISTGT_TRACE_NET, "close host %s, port %s, tag %d\n",
! 592: pgp->portals[i]->host, pgp->portals[i]->port,
! 593: pgp->portals[i]->tag);
! 594: close(pgp->portals[i]->sock);
! 595: pgp->portals[i]->sock = -1;
1.1 misho 596: }
597: }
598: return 0;
599: }
600:
601: static int
1.1.1.2 ! misho 602: istgt_close_all_portals(ISTGT_Ptr istgt)
1.1 misho 603: {
1.1.1.2 ! misho 604: int rc;
1.1 misho 605: int i;
606:
607: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_close_portal\n");
1.1.1.2 ! misho 608: MTX_LOCK(&istgt->mutex);
! 609: for (i = 0; i < istgt->nportal_group; i++) {
! 610: rc = istgt_close_portal_group(&istgt->portal_group[i]);
! 611: if (rc < 0) {
! 612: MTX_UNLOCK(&istgt->mutex);
! 613: return -1;
1.1 misho 614: }
615: }
1.1.1.2 ! misho 616: MTX_UNLOCK(&istgt->mutex);
1.1 misho 617: return 0;
618: }
619:
620: static int
621: istgt_add_initiator_group(ISTGT_Ptr istgt, CF_SECTION *sp)
622: {
623: const char *val;
624: int alloc_len;
625: int idx;
626: int names;
627: int masks;
628: int i;
629:
630: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "add initiator group %d\n", sp->num);
631:
632: val = istgt_get_val(sp, "Comment");
633: if (val != NULL) {
634: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Comment %s\n", val);
635: }
636:
637: /* counts number of definition */
638: for (i = 0; ; i++) {
639: val = istgt_get_nval(sp, "InitiatorName", i);
640: if (val == NULL)
641: break;
642: }
643: names = i;
644: if (names > MAX_INITIATOR) {
645: ISTGT_ERRLOG("%d > MAX_INITIATOR\n", names);
646: return -1;
647: }
648: for (i = 0; ; i++) {
649: val = istgt_get_nval(sp, "Netmask", i);
650: if (val == NULL)
651: break;
652: }
653: masks = i;
654: if (masks > MAX_NETMASK) {
655: ISTGT_ERRLOG("%d > MAX_NETMASK\n", masks);
656: return -1;
657: }
658:
1.1.1.2 ! misho 659: MTX_LOCK(&istgt->mutex);
1.1 misho 660: idx = istgt->ninitiator_group;
661: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
662: "Index=%d, Tag=%d, Names=%d, Masks=%d\n",
663: idx, sp->num, names, masks);
664: if (idx < MAX_INITIATOR_GROUP) {
665: istgt->initiator_group[idx].ninitiators = names;
666: alloc_len = sizeof (char *) * names;
667: istgt->initiator_group[idx].initiators = xmalloc(alloc_len);
668: istgt->initiator_group[idx].nnetmasks = masks;
669: alloc_len = sizeof (char *) * masks;
670: istgt->initiator_group[idx].netmasks = xmalloc(alloc_len);
1.1.1.2 ! misho 671: istgt->initiator_group[idx].ref = 0;
1.1 misho 672: istgt->initiator_group[idx].idx = idx;
673: istgt->initiator_group[idx].tag = sp->num;
674:
675: for (i = 0; i < names; i++) {
676: val = istgt_get_nval(sp, "InitiatorName", i);
677: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
678: "InitiatorName %s\n", val);
679: istgt->initiator_group[idx].initiators[i] = xstrdup(val);
680: }
681: for (i = 0; i < masks; i++) {
682: val = istgt_get_nval(sp, "Netmask", i);
683: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Netmask %s\n", val);
684: istgt->initiator_group[idx].netmasks[i] = xstrdup(val);
685: }
686:
687: idx++;
688: istgt->ninitiator_group = idx;
689: } else {
1.1.1.2 ! misho 690: MTX_UNLOCK(&istgt->mutex);
1.1 misho 691: ISTGT_ERRLOG("ninitiator_group(%d) >= MAX_INITIATOR_GROUP\n", idx);
692: return -1;
693: }
1.1.1.2 ! misho 694: MTX_UNLOCK(&istgt->mutex);
1.1 misho 695: return 0;
696: }
697:
698: static int
1.1.1.2 ! misho 699: istgt_ig_match_all(INITIATOR_GROUP *igp, CF_SECTION *sp)
! 700: {
! 701: const char *val;
! 702: int i;
! 703:
! 704: for (i = 0; i < igp->ninitiators; i++) {
! 705: val = istgt_get_nval(sp, "InitiatorName", i);
! 706: if (val == NULL)
! 707: return 0;
! 708: if (strcmp(igp->initiators[i], val) != 0)
! 709: return 0;
! 710: }
! 711: val = istgt_get_nval(sp, "InitiatorName", i);
! 712: if (val != NULL)
! 713: return 0;
! 714: for (i = 0; i < igp->nnetmasks; i++) {
! 715: val = istgt_get_nval(sp, "Netmask", i);
! 716: if (val == NULL)
! 717: return 0;
! 718: if (strcmp(igp->netmasks[i], val) != 0)
! 719: return 0;
! 720: }
! 721: val = istgt_get_nval(sp, "Netmask", i);
! 722: if (val != NULL)
! 723: return 0;
! 724: return 1;
! 725: }
! 726:
! 727: static int
! 728: istgt_update_initiator_group(ISTGT_Ptr istgt, CF_SECTION *sp)
! 729: {
! 730: const char *val;
! 731: int alloc_len;
! 732: int idx;
! 733: int names;
! 734: int masks;
! 735: int i;
! 736:
! 737: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "update initiator group %d\n", sp->num);
! 738:
! 739: val = istgt_get_val(sp, "Comment");
! 740: if (val != NULL) {
! 741: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Comment %s\n", val);
! 742: }
! 743:
! 744: /* counts number of definition */
! 745: for (i = 0; ; i++) {
! 746: val = istgt_get_nval(sp, "InitiatorName", i);
! 747: if (val == NULL)
! 748: break;
! 749: }
! 750: names = i;
! 751: if (names > MAX_INITIATOR) {
! 752: ISTGT_ERRLOG("%d > MAX_INITIATOR\n", names);
! 753: return -1;
! 754: }
! 755: for (i = 0; ; i++) {
! 756: val = istgt_get_nval(sp, "Netmask", i);
! 757: if (val == NULL)
! 758: break;
! 759: }
! 760: masks = i;
! 761: if (masks > MAX_NETMASK) {
! 762: ISTGT_ERRLOG("%d > MAX_NETMASK\n", masks);
! 763: return -1;
! 764: }
! 765:
! 766: MTX_LOCK(&istgt->mutex);
! 767: idx = -1;
! 768: for (i = 0; i < istgt->ninitiator_group; i++) {
! 769: if (istgt->initiator_group[i].tag == sp->num) {
! 770: idx = i;
! 771: break;
! 772: }
! 773: }
! 774: if (idx < 0) {
! 775: MTX_UNLOCK(&istgt->mutex);
! 776: ISTGT_ERRLOG("can't find IG%d\n", sp->num);
! 777: return -1;
! 778: }
! 779: if (istgt_ig_match_all(&istgt->initiator_group[i], sp)) {
! 780: MTX_UNLOCK(&istgt->mutex);
! 781: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "skip for IG%d\n", sp->num);
! 782: return 0;
! 783: }
! 784: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
! 785: "Index=%d, Tag=%d, Names=%d, Masks=%d\n",
! 786: idx, sp->num, names, masks);
! 787:
! 788: /* free old IG */
! 789: for (i = 0; i < istgt->initiator_group[idx].ninitiators; i++) {
! 790: xfree(istgt->initiator_group[idx].initiators[i]);
! 791: }
! 792: xfree(istgt->initiator_group[idx].initiators);
! 793: for (i = 0; i < istgt->initiator_group[idx].nnetmasks; i++) {
! 794: xfree(istgt->initiator_group[idx].netmasks[i]);
! 795: }
! 796: xfree(istgt->initiator_group[idx].netmasks);
! 797:
! 798: /* allocate new IG */
! 799: istgt->initiator_group[idx].ninitiators = names;
! 800: alloc_len = sizeof (char *) * names;
! 801: istgt->initiator_group[idx].initiators = xmalloc(alloc_len);
! 802: istgt->initiator_group[idx].nnetmasks = masks;
! 803: alloc_len = sizeof (char *) * masks;
! 804: istgt->initiator_group[idx].netmasks = xmalloc(alloc_len);
! 805: //istgt->initiator_group[idx].ref = 0;
! 806: //istgt->initiator_group[idx].idx = idx;
! 807: //istgt->initiator_group[idx].tag = sp->num;
! 808:
! 809: /* copy new strings */
! 810: for (i = 0; i < names; i++) {
! 811: val = istgt_get_nval(sp, "InitiatorName", i);
! 812: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
! 813: "InitiatorName %s\n", val);
! 814: istgt->initiator_group[idx].initiators[i] = xstrdup(val);
! 815: }
! 816: for (i = 0; i < masks; i++) {
! 817: val = istgt_get_nval(sp, "Netmask", i);
! 818: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Netmask %s\n", val);
! 819: istgt->initiator_group[idx].netmasks[i] = xstrdup(val);
! 820: }
! 821: MTX_UNLOCK(&istgt->mutex);
! 822: return 1;
! 823: }
! 824:
! 825: static int
1.1 misho 826: istgt_build_initiator_group_array(ISTGT_Ptr istgt)
827: {
828: CF_SECTION *sp;
829: int rc;
830:
831: sp = istgt->config->section;
832: while (sp != NULL) {
833: if (sp->type == ST_INITIATORGROUP) {
834: if (sp->num == 0) {
835: ISTGT_ERRLOG("Group 0 is invalid\n");
836: return -1;
837: }
838: rc = istgt_add_initiator_group(istgt, sp);
839: if (rc < 0) {
840: ISTGT_ERRLOG("add_initiator_group() failed\n");
841: return -1;
842: }
843: }
844: sp = sp->next;
845: }
846: return 0;
847: }
848:
849: static void
850: istgt_destory_initiator_group_array(ISTGT_Ptr istgt)
851: {
852: int i, j;
853:
854: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_destory_initiator_group_array\n");
1.1.1.2 ! misho 855: MTX_LOCK(&istgt->mutex);
1.1 misho 856: for (i = 0; i < istgt->ninitiator_group; i++) {
857: for (j = 0; j < istgt->initiator_group[i].ninitiators; j++) {
858: xfree(istgt->initiator_group[i].initiators[j]);
859: }
860: xfree(istgt->initiator_group[i].initiators);
861: for (j = 0; j < istgt->initiator_group[i].nnetmasks; j++) {
862: xfree(istgt->initiator_group[i].netmasks[j]);
863: }
864: xfree(istgt->initiator_group[i].netmasks);
865:
866: istgt->initiator_group[i].ninitiators = 0;
867: istgt->initiator_group[i].initiators = NULL;
868: istgt->initiator_group[i].nnetmasks = 0;
869: istgt->initiator_group[i].netmasks = NULL;
1.1.1.2 ! misho 870: istgt->initiator_group[i].ref = 0;
1.1 misho 871: istgt->initiator_group[i].idx = i;
872: istgt->initiator_group[i].tag = 0;
873: }
874: istgt->ninitiator_group = 0;
1.1.1.2 ! misho 875: MTX_UNLOCK(&istgt->mutex);
1.1 misho 876: }
877:
878: static int
879: istgt_build_uctl_portal(ISTGT_Ptr istgt)
880: {
881: CF_SECTION *sp;
882: const char *val;
883: char *label, *portal, *host, *port;
884: int tag;
885: int idx;
886: int rc;
887: int i;
888:
889: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_build_uctl_portal\n");
890:
891: sp = istgt_find_cf_section(istgt->config, "UnitControl");
892: if (sp == NULL) {
893: ISTGT_ERRLOG("find_cf_section failed()\n");
894: return -1;
895: }
896:
897: for (i = 0; ; i++) {
898: val = istgt_get_nval(sp, "Portal", i);
899: if (val == NULL)
900: break;
901:
902: label = istgt_get_nmval(sp, "Portal", i, 0);
903: portal = istgt_get_nmval(sp, "Portal", i, 1);
904: if (label == NULL || portal == NULL) {
905: ISTGT_ERRLOG("uctl portal error\n");
906: return -1;
907: }
908:
909: rc = istgt_parse_portal(portal, &host, &port);
910: if (rc < 0) {
911: ISTGT_ERRLOG("parse uctl portal error\n");
912: return -1;
913: }
914:
915: idx = istgt->nuctl_portal;
916: tag = ISTGT_UC_TAG;
917: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
918: "Index=%d, Host=%s, Port=%s, Tag=%d\n",
919: idx, host, port, tag);
920: if (idx < MAX_UCPORTAL) {
921: istgt->uctl_portal[idx].label = xstrdup(label);
922: istgt->uctl_portal[idx].host = host;
923: istgt->uctl_portal[idx].port = port;
1.1.1.2 ! misho 924: istgt->uctl_portal[idx].ref = 0;
1.1 misho 925: istgt->uctl_portal[idx].idx = idx;
926: istgt->uctl_portal[idx].tag = tag;
927: istgt->uctl_portal[idx].sock = -1;
928: idx++;
929: istgt->nuctl_portal = idx;
930: } else {
931: ISTGT_ERRLOG("nportal(%d) >= MAX_UCPORTAL\n", idx);
932: xfree(host);
933: xfree(port);
934: return -1;
935: }
936: }
937:
938: return 0;
939: }
940:
941: static void
942: istgt_destroy_uctl_portal(ISTGT_Ptr istgt)
943: {
944: int i;
945:
946: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_destroy_uctl_portal\n");
1.1.1.2 ! misho 947: for (i = 0; i < istgt->nuctl_portal; i++) {
1.1 misho 948: xfree(istgt->uctl_portal[i].label);
949: xfree(istgt->uctl_portal[i].host);
950: xfree(istgt->uctl_portal[i].port);
951:
952: istgt->uctl_portal[i].label = NULL;
953: istgt->uctl_portal[i].host = NULL;
954: istgt->uctl_portal[i].port = NULL;
1.1.1.2 ! misho 955: istgt->uctl_portal[i].ref = 0;
1.1 misho 956: istgt->uctl_portal[i].idx = i;
957: istgt->uctl_portal[i].tag = 0;
958: }
959: istgt->nuctl_portal = 0;
960: }
961:
962: static int
963: istgt_open_uctl_portal(ISTGT_Ptr istgt)
964: {
965: int port;
966: int sock;
967: int i;
968:
969: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_open_uctl_portal\n");
970: for (i = 0; i < istgt->nuctl_portal; i++) {
971: if (istgt->uctl_portal[i].sock < 0) {
972: ISTGT_TRACELOG(ISTGT_TRACE_NET,
973: "open host %s, port %s, tag %d\n",
974: istgt->uctl_portal[i].host,
975: istgt->uctl_portal[i].port,
976: istgt->uctl_portal[i].tag);
977: port = (int)strtol(istgt->uctl_portal[i].port, NULL, 0);
978: sock = istgt_listen(istgt->uctl_portal[i].host, port);
979: if (sock < 0) {
980: ISTGT_ERRLOG("listen error %.64s:%d\n",
981: istgt->uctl_portal[i].host, port);
982: return -1;
983: }
984: istgt->uctl_portal[i].sock = sock;
985: }
986: }
987: return 0;
988: }
989:
990: static int
991: istgt_close_uctl_portal(ISTGT_Ptr istgt)
992: {
993: int i;
994:
995: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_close_uctl_portal\n");
996: for (i = 0; i < istgt->nuctl_portal; i++) {
997: if (istgt->uctl_portal[i].sock >= 0) {
998: ISTGT_TRACELOG(ISTGT_TRACE_NET,
999: "close host %s, port %s, tag %d\n",
1000: istgt->uctl_portal[i].host,
1001: istgt->uctl_portal[i].port,
1002: istgt->uctl_portal[i].tag);
1003: close(istgt->uctl_portal[i].sock);
1004: istgt->uctl_portal[i].sock = -1;
1005: }
1006: }
1007: return 0;
1008: }
1009:
1010: static int
1011: istgt_write_pidfile(ISTGT_Ptr istgt)
1012: {
1013: FILE *fp;
1014: pid_t pid;
1015: int rc;
1016:
1017: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_write_pidfile\n");
1018: rc = remove(istgt->pidfile);
1019: if (rc != 0) {
1020: if (errno != ENOENT) {
1021: ISTGT_ERRLOG("pidfile remove error %d\n", errno);
1022: return -1;
1023: }
1024: }
1025: fp = fopen(istgt->pidfile, "w");
1026: if (fp == NULL) {
1027: ISTGT_ERRLOG("pidfile open error %d\n", errno);
1028: return -1;
1029: }
1030: pid = getpid();
1031: fprintf(fp, "%d\n", (int)pid);
1032: fclose(fp);
1033: return 0;
1034: }
1035:
1036: static void
1037: istgt_remove_pidfile(ISTGT_Ptr istgt)
1038: {
1039: int rc;
1040:
1041: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_remove_pidfile\n");
1042: rc = remove(istgt->pidfile);
1043: if (rc != 0) {
1044: ISTGT_ERRLOG("pidfile remove error %d\n", errno);
1045: /* ignore error */
1046: }
1047: }
1048:
1049: char *
1050: istgt_get_nmval(CF_SECTION *sp, const char *key, int idx1, int idx2)
1051: {
1052: CF_ITEM *ip;
1053: CF_VALUE *vp;
1054: int i;
1055:
1056: ip = istgt_find_cf_nitem(sp, key, idx1);
1057: if (ip == NULL)
1058: return NULL;
1059: vp = ip->val;
1060: if (vp == NULL)
1061: return NULL;
1062: for (i = 0; vp != NULL; vp = vp->next) {
1063: if (i == idx2)
1064: return vp->value;
1065: i++;
1066: }
1067: return NULL;
1068: }
1069:
1070: char *
1071: istgt_get_nval(CF_SECTION *sp, const char *key, int idx)
1072: {
1073: CF_ITEM *ip;
1074: CF_VALUE *vp;
1075:
1076: ip = istgt_find_cf_nitem(sp, key, idx);
1077: if (ip == NULL)
1078: return NULL;
1079: vp = ip->val;
1080: if (vp == NULL)
1081: return NULL;
1082: return vp->value;
1083: }
1084:
1085: char *
1086: istgt_get_val(CF_SECTION *sp, const char *key)
1087: {
1088: return istgt_get_nval(sp, key, 0);
1089: }
1090:
1091: int
1092: istgt_get_nintval(CF_SECTION *sp, const char *key, int idx)
1093: {
1094: const char *v;
1095: int value;
1096:
1097: v = istgt_get_nval(sp, key, idx);
1098: if (v == NULL)
1099: return -1;
1100: value = (int)strtol(v, NULL, 10);
1101: return value;
1102: }
1103:
1104: int
1105: istgt_get_intval(CF_SECTION *sp, const char *key)
1106: {
1107: return istgt_get_nintval(sp, key, 0);
1108: }
1109:
1110: static const char *
1111: istgt_get_log_facility(CONFIG *config)
1112: {
1113: CF_SECTION *sp;
1114: const char *logfacility;
1115:
1116: sp = istgt_find_cf_section(config, "Global");
1117: if (sp == NULL) {
1118: return NULL;
1119: }
1120: logfacility = istgt_get_val(sp, "LogFacility");
1121: if (logfacility == NULL) {
1122: logfacility = DEFAULT_LOG_FACILITY;
1123: }
1124: #if 0
1125: if (g_trace_flag & ISTGT_TRACE_DEBUG) {
1126: fprintf(stderr, "LogFacility %s\n", logfacility);
1127: }
1128: #endif
1129:
1130: return logfacility;
1131: }
1132:
1133: static int
1134: istgt_init(ISTGT_Ptr istgt)
1135: {
1136: CF_SECTION *sp;
1137: const char *ag_tag;
1138: const char *val;
1139: size_t stacksize;
1140: int ag_tag_i;
1141: int MaxSessions;
1142: int MaxConnections;
1143: int MaxOutstandingR2T;
1144: int DefaultTime2Wait;
1145: int DefaultTime2Retain;
1146: int FirstBurstLength;
1147: int MaxBurstLength;
1148: int MaxRecvDataSegmentLength;
1149: int InitialR2T;
1150: int ImmediateData;
1151: int DataPDUInOrder;
1152: int DataSequenceInOrder;
1153: int ErrorRecoveryLevel;
1154: int timeout;
1155: int nopininterval;
1156: int maxr2t;
1157: int rc;
1158: int i;
1159:
1160: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_init\n");
1161: sp = istgt_find_cf_section(istgt->config, "Global");
1162: if (sp == NULL) {
1163: ISTGT_ERRLOG("find_cf_section failed()\n");
1164: return -1;
1165: }
1166:
1167: val = istgt_get_val(sp, "Comment");
1168: if (val != NULL) {
1169: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Comment %s\n", val);
1170: }
1171:
1172: val = istgt_get_val(sp, "PidFile");
1173: if (val == NULL) {
1174: val = DEFAULT_PIDFILE;
1175: }
1176: istgt->pidfile = xstrdup(val);
1177: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "PidFile %s\n",
1178: istgt->pidfile);
1179:
1180: val = istgt_get_val(sp, "AuthFile");
1181: if (val == NULL) {
1182: val = DEFAULT_AUTHFILE;
1183: }
1184: istgt->authfile = xstrdup(val);
1185: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "AuthFile %s\n",
1186: istgt->authfile);
1187:
1188: #if 0
1189: val = istgt_get_val(sp, "MediaFile");
1190: if (val == NULL) {
1191: val = DEFAULT_MEDIAFILE;
1192: }
1193: istgt->mediafile = xstrdup(val);
1194: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "MediaFile %s\n",
1195: istgt->mediafile);
1196: #endif
1197:
1198: #if 0
1199: val = istgt_get_val(sp, "LiveFile");
1200: if (val == NULL) {
1201: val = DEFAULT_LIVEFILE;
1202: }
1203: istgt->livefile = xstrdup(val);
1204: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "LiveFile %s\n",
1205: istgt->livefile);
1206: #endif
1207:
1208: val = istgt_get_val(sp, "MediaDirectory");
1209: if (val == NULL) {
1210: val = DEFAULT_MEDIADIRECTORY;
1211: }
1212: istgt->mediadirectory = xstrdup(val);
1213: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "MediaDirectory %s\n",
1214: istgt->mediadirectory);
1215:
1216: val = istgt_get_val(sp, "NodeBase");
1217: if (val == NULL) {
1218: val = DEFAULT_NODEBASE;
1219: }
1220: istgt->nodebase = xstrdup(val);
1221: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "NodeBase %s\n",
1222: istgt->nodebase);
1223:
1224: MaxSessions = istgt_get_intval(sp, "MaxSessions");
1225: if (MaxSessions < 1) {
1226: MaxSessions = DEFAULT_MAX_SESSIONS;
1227: }
1228: istgt->MaxSessions = MaxSessions;
1229: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "MaxSessions %d\n",
1230: istgt->MaxSessions);
1231:
1232: MaxConnections = istgt_get_intval(sp, "MaxConnections");
1233: if (MaxConnections < 1) {
1234: MaxConnections = DEFAULT_MAX_CONNECTIONS;
1235: }
1236: istgt->MaxConnections = MaxConnections;
1237: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "MaxConnections %d\n",
1238: istgt->MaxConnections);
1239:
1240: /* limited to 16bits - RFC3720(12.2) */
1241: if (MaxSessions > 0xffff) {
1242: ISTGT_ERRLOG("over 65535 sessions are not supported\n");
1243: return -1;
1244: }
1245: if (MaxConnections > 0xffff) {
1246: ISTGT_ERRLOG("over 65535 connections are not supported\n");
1247: return -1;
1248: }
1249:
1250: MaxOutstandingR2T = istgt_get_intval(sp, "MaxOutstandingR2T");
1251: if (MaxOutstandingR2T < 1) {
1252: MaxOutstandingR2T = DEFAULT_MAXOUTSTANDINGR2T;
1253: }
1254: istgt->MaxOutstandingR2T = MaxOutstandingR2T;
1255: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "MaxOutstandingR2T %d\n",
1256: istgt->MaxOutstandingR2T);
1257:
1258: DefaultTime2Wait = istgt_get_intval(sp, "DefaultTime2Wait");
1259: if (DefaultTime2Wait < 0) {
1260: DefaultTime2Wait = DEFAULT_DEFAULTTIME2WAIT;
1261: }
1262: istgt->DefaultTime2Wait = DefaultTime2Wait;
1263: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "DefaultTime2Wait %d\n",
1264: istgt->DefaultTime2Wait);
1265:
1266: DefaultTime2Retain = istgt_get_intval(sp, "DefaultTime2Retain");
1267: if (DefaultTime2Retain < 0) {
1268: DefaultTime2Retain = DEFAULT_DEFAULTTIME2RETAIN;
1269: }
1270: istgt->DefaultTime2Retain = DefaultTime2Retain;
1271: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "DefaultTime2Retain %d\n",
1272: istgt->DefaultTime2Retain);
1273:
1274: /* check size limit - RFC3720(12.15, 12.16, 12.17) */
1275: if (istgt->MaxOutstandingR2T > 65535) {
1276: ISTGT_ERRLOG("MaxOutstandingR2T(%d) > 65535\n",
1277: istgt->MaxOutstandingR2T);
1278: return -1;
1279: }
1280: if (istgt->DefaultTime2Wait > 3600) {
1281: ISTGT_ERRLOG("DefaultTime2Wait(%d) > 3600\n",
1282: istgt->DefaultTime2Wait);
1283: return -1;
1284: }
1285: if (istgt->DefaultTime2Retain > 3600) {
1286: ISTGT_ERRLOG("DefaultTime2Retain(%d) > 3600\n",
1287: istgt->DefaultTime2Retain);
1288: return -1;
1289: }
1290:
1291: FirstBurstLength = istgt_get_intval(sp, "FirstBurstLength");
1292: if (FirstBurstLength < 0) {
1293: FirstBurstLength = DEFAULT_FIRSTBURSTLENGTH;
1294: }
1295: istgt->FirstBurstLength = FirstBurstLength;
1296: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "FirstBurstLength %d\n",
1297: istgt->FirstBurstLength);
1298:
1299: MaxBurstLength = istgt_get_intval(sp, "MaxBurstLength");
1300: if (MaxBurstLength < 0) {
1301: MaxBurstLength = DEFAULT_MAXBURSTLENGTH;
1302: }
1303: istgt->MaxBurstLength = MaxBurstLength;
1304: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "MaxBurstLength %d\n",
1305: istgt->MaxBurstLength);
1306:
1307: MaxRecvDataSegmentLength
1308: = istgt_get_intval(sp, "MaxRecvDataSegmentLength");
1309: if (MaxRecvDataSegmentLength < 0) {
1310: MaxRecvDataSegmentLength = DEFAULT_MAXRECVDATASEGMENTLENGTH;
1311: }
1312: istgt->MaxRecvDataSegmentLength = MaxRecvDataSegmentLength;
1313: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "MaxRecvDataSegmentLength %d\n",
1314: istgt->MaxRecvDataSegmentLength);
1315:
1316: /* check size limit (up to 24bits - RFC3720(12.12)) */
1317: if (istgt->MaxBurstLength < 512) {
1318: ISTGT_ERRLOG("MaxBurstLength(%d) < 512\n",
1319: istgt->MaxBurstLength);
1320: return -1;
1321: }
1322: if (istgt->FirstBurstLength < 512) {
1323: ISTGT_ERRLOG("FirstBurstLength(%d) < 512\n",
1324: istgt->FirstBurstLength);
1325: return -1;
1326: }
1327: if (istgt->FirstBurstLength > istgt->MaxBurstLength) {
1328: ISTGT_ERRLOG("FirstBurstLength(%d) > MaxBurstLength(%d)\n",
1329: istgt->FirstBurstLength, istgt->MaxBurstLength);
1330: return -1;
1331: }
1332: if (istgt->MaxBurstLength > 0x00ffffff) {
1333: ISTGT_ERRLOG("MaxBurstLength(%d) > 0x00ffffff\n",
1334: istgt->MaxBurstLength);
1335: return -1;
1336: }
1337: if (istgt->MaxRecvDataSegmentLength < 512) {
1338: ISTGT_ERRLOG("MaxRecvDataSegmentLength(%d) < 512\n",
1339: istgt->MaxRecvDataSegmentLength);
1340: return -1;
1341: }
1342: if (istgt->MaxRecvDataSegmentLength > 0x00ffffff) {
1343: ISTGT_ERRLOG("MaxRecvDataSegmentLength(%d) > 0x00ffffff\n",
1344: istgt->MaxRecvDataSegmentLength);
1345: return -1;
1346: }
1347:
1348: val = istgt_get_val(sp, "InitialR2T");
1349: if (val == NULL) {
1350: InitialR2T = DEFAULT_INITIALR2T;
1351: } else if (strcasecmp(val, "Yes") == 0) {
1352: InitialR2T = 1;
1353: } else if (strcasecmp(val, "No") == 0) {
1354: #if 0
1355: InitialR2T = 0;
1356: #else
1357: ISTGT_ERRLOG("not supported value %s\n", val);
1358: return -1;
1359: #endif
1360: } else {
1361: ISTGT_ERRLOG("unknown value %s\n", val);
1362: return -1;
1363: }
1364: istgt->InitialR2T = InitialR2T;
1365: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "InitialR2T %s\n",
1366: istgt->InitialR2T ? "Yes" : "No");
1367:
1368: val = istgt_get_val(sp, "ImmediateData");
1369: if (val == NULL) {
1370: ImmediateData = DEFAULT_IMMEDIATEDATA;
1371: } else if (strcasecmp(val, "Yes") == 0) {
1372: ImmediateData = 1;
1373: } else if (strcasecmp(val, "No") == 0) {
1374: ImmediateData = 0;
1375: } else {
1376: ISTGT_ERRLOG("unknown value %s\n", val);
1377: return -1;
1378: }
1379: istgt->ImmediateData = ImmediateData;
1380: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "ImmediateData %s\n",
1381: istgt->ImmediateData ? "Yes" : "No");
1382:
1383: val = istgt_get_val(sp, "DataPDUInOrder");
1384: if (val == NULL) {
1385: DataPDUInOrder = DEFAULT_DATAPDUINORDER;
1386: } else if (strcasecmp(val, "Yes") == 0) {
1387: DataPDUInOrder = 1;
1388: } else if (strcasecmp(val, "No") == 0) {
1389: #if 0
1390: DataPDUInOrder = 0;
1391: #else
1392: ISTGT_ERRLOG("not supported value %s\n", val);
1393: return -1;
1394: #endif
1395: } else {
1396: ISTGT_ERRLOG("unknown value %s\n", val);
1397: return -1;
1398: }
1399: istgt->DataPDUInOrder = DataPDUInOrder;
1400: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "DataPDUInOrder %s\n",
1401: istgt->DataPDUInOrder ? "Yes" : "No");
1402:
1403: val = istgt_get_val(sp, "DataSequenceInOrder");
1404: if (val == NULL) {
1405: DataSequenceInOrder = DEFAULT_DATASEQUENCEINORDER;
1406: } else if (strcasecmp(val, "Yes") == 0) {
1407: DataSequenceInOrder = 1;
1408: } else if (strcasecmp(val, "No") == 0) {
1409: #if 0
1410: DataSequenceInOrder = 0;
1411: #else
1412: ISTGT_ERRLOG("not supported value %s\n", val);
1413: return -1;
1414: #endif
1415: } else {
1416: ISTGT_ERRLOG("unknown value %s\n", val);
1417: return -1;
1418: }
1419: istgt->DataSequenceInOrder = DataSequenceInOrder;
1420: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "DataSequenceInOrder %s\n",
1421: istgt->DataSequenceInOrder ? "Yes" : "No");
1422:
1423: ErrorRecoveryLevel = istgt_get_intval(sp, "ErrorRecoveryLevel");
1424: if (ErrorRecoveryLevel < 0) {
1425: ErrorRecoveryLevel = DEFAULT_ERRORRECOVERYLEVEL;
1426: } else if (ErrorRecoveryLevel == 0) {
1427: ErrorRecoveryLevel = 0;
1428: } else if (ErrorRecoveryLevel == 1) {
1429: #if 0
1430: ErrorRecoveryLevel = 1;
1431: #else
1432: ISTGT_ERRLOG("not supported value %d\n", ErrorRecoveryLevel);
1433: return -1;
1434: #endif
1435: } else if (ErrorRecoveryLevel == 2) {
1436: #if 0
1437: ErrorRecoveryLevel = 2;
1438: #else
1439: ISTGT_ERRLOG("not supported value %d\n", ErrorRecoveryLevel);
1440: return -1;
1441: #endif
1442: } else {
1443: ISTGT_ERRLOG("not supported value %d\n", ErrorRecoveryLevel);
1444: return -1;
1445: }
1446: istgt->ErrorRecoveryLevel = ErrorRecoveryLevel;
1447: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "ErrorRecoveryLevel %d\n",
1448: istgt->ErrorRecoveryLevel);
1449:
1450: timeout = istgt_get_intval(sp, "Timeout");
1451: if (timeout < 0) {
1452: timeout = DEFAULT_TIMEOUT;
1453: }
1454: istgt->timeout = timeout;
1455: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Timeout %d\n",
1456: istgt->timeout);
1457:
1458: nopininterval = istgt_get_intval(sp, "NopInInterval");
1459: if (nopininterval < 0) {
1460: nopininterval = DEFAULT_NOPININTERVAL;
1461: }
1462: istgt->nopininterval = nopininterval;
1463: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "NopInInterval %d\n",
1464: istgt->nopininterval);
1465:
1466: maxr2t = istgt_get_intval(sp, "MaxR2T");
1467: if (maxr2t < 0) {
1468: maxr2t = DEFAULT_MAXR2T;
1469: }
1470: if (maxr2t > MAX_R2T) {
1471: ISTGT_ERRLOG("MaxR2T(%d) > %d\n",
1472: maxr2t, MAX_R2T);
1473: return -1;
1474: }
1475: istgt->maxr2t = maxr2t;
1476: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "MaxR2T %d\n",
1477: istgt->maxr2t);
1478:
1479: val = istgt_get_val(sp, "DiscoveryAuthMethod");
1480: if (val == NULL) {
1481: istgt->no_discovery_auth = 0;
1482: istgt->req_discovery_auth = 0;
1483: istgt->req_discovery_auth_mutual = 0;
1484: } else {
1485: istgt->no_discovery_auth = 0;
1486: for (i = 0; ; i++) {
1487: val = istgt_get_nmval(sp, "DiscoveryAuthMethod", 0, i);
1488: if (val == NULL)
1489: break;
1490: if (strcasecmp(val, "CHAP") == 0) {
1491: istgt->req_discovery_auth = 1;
1492: } else if (strcasecmp(val, "Mutual") == 0) {
1493: istgt->req_discovery_auth_mutual = 1;
1494: } else if (strcasecmp(val, "Auto") == 0) {
1495: istgt->req_discovery_auth = 0;
1496: istgt->req_discovery_auth_mutual = 0;
1497: } else if (strcasecmp(val, "None") == 0) {
1498: istgt->no_discovery_auth = 1;
1499: istgt->req_discovery_auth = 0;
1500: istgt->req_discovery_auth_mutual = 0;
1501: } else {
1502: ISTGT_ERRLOG("unknown auth\n");
1503: return -1;
1504: }
1505: }
1506: if (istgt->req_discovery_auth_mutual && !istgt->req_discovery_auth) {
1507: ISTGT_ERRLOG("Mutual but not CHAP\n");
1508: return -1;
1509: }
1510: }
1511: if (istgt->no_discovery_auth != 0) {
1512: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
1513: "DiscoveryAuthMethod None\n");
1514: } else if (istgt->req_discovery_auth == 0) {
1515: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
1516: "DiscoveryAuthMethod Auto\n");
1517: } else {
1518: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
1519: "DiscoveryAuthMethod %s %s\n",
1520: istgt->req_discovery_auth ? "CHAP" : "",
1521: istgt->req_discovery_auth_mutual ? "Mutual" : "");
1522: }
1523:
1524: val = istgt_get_val(sp, "DiscoveryAuthGroup");
1525: if (val == NULL) {
1526: istgt->discovery_auth_group = 0;
1527: } else {
1528: ag_tag = val;
1529: if (strcasecmp(ag_tag, "None") == 0) {
1530: ag_tag_i = 0;
1531: } else {
1532: if (strncasecmp(ag_tag, "AuthGroup",
1533: strlen("AuthGroup")) != 0
1534: || sscanf(ag_tag, "%*[^0-9]%d", &ag_tag_i) != 1) {
1535: ISTGT_ERRLOG("auth group error\n");
1536: return -1;
1537: }
1538: if (ag_tag_i == 0) {
1539: ISTGT_ERRLOG("invalid auth group %d\n",
1540: ag_tag_i);
1541: return -1;
1542: }
1543: }
1544: istgt->discovery_auth_group = ag_tag_i;
1545: }
1546: if (istgt->discovery_auth_group == 0) {
1547: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
1548: "DiscoveryAuthGroup None\n");
1549: } else {
1550: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
1551: "DiscoveryAuthGroup AuthGroup%d\n",
1552: istgt->discovery_auth_group);
1553: }
1554:
1.1.1.2 ! misho 1555: rc = istgt_uctl_init(istgt);
1.1 misho 1556: if (rc < 0) {
1.1.1.2 ! misho 1557: ISTGT_ERRLOG("istgt_uctl_init() failed\n");
1.1 misho 1558: return -1;
1559: }
1560: rc = istgt_build_uctl_portal(istgt);
1561: if (rc < 0) {
1562: ISTGT_ERRLOG("istgt_build_uctl_portal() failed\n");
1563: return -1;
1564: }
1.1.1.2 ! misho 1565: rc = istgt_build_portal_group_array(istgt);
1.1 misho 1566: if (rc < 0) {
1567: ISTGT_ERRLOG("istgt_build_portal_array() failed\n");
1568: return -1;
1569: }
1570: rc = istgt_build_initiator_group_array(istgt);
1571: if (rc < 0) {
1572: ISTGT_ERRLOG("build_initiator_group_array() failed\n");
1573: return -1;
1574: }
1575:
1576: rc = pthread_attr_init(&istgt->attr);
1577: if (rc != 0) {
1578: ISTGT_ERRLOG("pthread_attr_init() failed\n");
1579: return -1;
1580: }
1581: rc = pthread_attr_getstacksize(&istgt->attr, &stacksize);
1582: if (rc != 0) {
1583: ISTGT_ERRLOG("pthread_attr_getstacksize() failed\n");
1584: return -1;
1585: }
1586: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "current thread stack = %zd\n", stacksize);
1587: if (stacksize < ISTGT_STACKSIZE) {
1588: stacksize = ISTGT_STACKSIZE;
1589: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "new thread stack = %zd\n", stacksize);
1590: rc = pthread_attr_setstacksize(&istgt->attr, stacksize);
1591: if (rc != 0) {
1592: ISTGT_ERRLOG("pthread_attr_setstacksize() failed\n");
1593: return -1;
1594: }
1595: }
1596:
1.1.1.2 ! misho 1597: rc = pthread_mutexattr_init(&istgt->mutex_attr);
! 1598: if (rc != 0) {
! 1599: ISTGT_ERRLOG("mutexattr_init() failed\n");
! 1600: return -1;
! 1601: }
! 1602: #ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
! 1603: rc = pthread_mutexattr_settype(&istgt->mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
! 1604: #else
! 1605: rc = pthread_mutexattr_settype(&istgt->mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
! 1606: #endif
! 1607: if (rc != 0) {
! 1608: ISTGT_ERRLOG("mutexattr_settype() failed\n");
! 1609: return -1;
! 1610: }
1.1 misho 1611: rc = pthread_mutex_init(&istgt->mutex, NULL);
1612: if (rc != 0) {
1613: ISTGT_ERRLOG("mutex_init() failed\n");
1614: return -1;
1615: }
1.1.1.2 ! misho 1616: rc = pthread_mutex_init(&istgt->state_mutex, &istgt->mutex_attr);
! 1617: if (rc != 0) {
! 1618: ISTGT_ERRLOG("mutex_init() failed\n");
! 1619: return -1;
! 1620: }
! 1621: rc = pthread_mutex_init(&istgt->reload_mutex, &istgt->mutex_attr);
! 1622: if (rc != 0) {
! 1623: ISTGT_ERRLOG("mutex_init() failed\n");
! 1624: return -1;
! 1625: }
! 1626: rc = pthread_cond_init(&istgt->reload_cond, NULL);
! 1627: if (rc != 0) {
! 1628: ISTGT_ERRLOG("cond_init() failed\n");
! 1629: return -1;
! 1630: }
! 1631:
! 1632: rc = pipe(istgt->sig_pipe);
! 1633: if (rc != 0) {
! 1634: ISTGT_ERRLOG("pipe() failed\n");
! 1635: istgt->sig_pipe[0] = -1;
! 1636: istgt->sig_pipe[1] = -1;
! 1637: return -1;
! 1638: }
! 1639:
! 1640: /* XXX TODO: add initializer */
! 1641:
! 1642: istgt_set_state(istgt, ISTGT_STATE_INITIALIZED);
! 1643:
! 1644: return 0;
! 1645: }
! 1646:
! 1647: static void
! 1648: istgt_shutdown(ISTGT_Ptr istgt)
! 1649: {
! 1650: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_shutdown\n");
! 1651:
! 1652: istgt_destory_initiator_group_array(istgt);
! 1653: istgt_destroy_portal_group_array(istgt);
! 1654: istgt_destroy_uctl_portal(istgt);
! 1655: istgt_uctl_shutdown(istgt);
! 1656: istgt_remove_pidfile(istgt);
! 1657: xfree(istgt->pidfile);
! 1658: xfree(istgt->authfile);
! 1659: #if 0
! 1660: xfree(istgt->mediafile);
! 1661: xfree(istgt->livefile);
! 1662: #endif
! 1663: xfree(istgt->mediadirectory);
! 1664: xfree(istgt->nodebase);
! 1665:
! 1666: if (istgt->sig_pipe[0] != -1)
! 1667: close(istgt->sig_pipe[0]);
! 1668: if (istgt->sig_pipe[1] != -1)
! 1669: close(istgt->sig_pipe[1]);
! 1670:
! 1671: (void) pthread_cond_destroy(&istgt->reload_cond);
! 1672: (void) pthread_mutex_destroy(&istgt->reload_mutex);
! 1673: (void) pthread_mutex_destroy(&istgt->state_mutex);
! 1674: (void) pthread_mutex_destroy(&istgt->mutex);
! 1675: (void) pthread_attr_destroy(&istgt->attr);
! 1676: }
! 1677:
! 1678: static int
! 1679: istgt_pg_exist_num(CONFIG *config, int num)
! 1680: {
! 1681: CF_SECTION *sp;
! 1682:
! 1683: sp = config->section;
! 1684: while (sp != NULL) {
! 1685: if (sp->type == ST_PORTALGROUP) {
! 1686: if (sp->num == num) {
! 1687: return 1;
! 1688: }
! 1689: }
! 1690: sp = sp->next;
! 1691: }
! 1692: return -1;
! 1693: }
! 1694:
! 1695: static PORTAL_GROUP *
! 1696: istgt_get_tag_portal(ISTGT_Ptr istgt, int tag)
! 1697: {
! 1698: int i;
! 1699:
! 1700: if (tag == 0)
! 1701: return NULL;
! 1702: MTX_LOCK(&istgt->mutex);
! 1703: for (i = 0; i < istgt->nportal_group; i++) {
! 1704: if (istgt->portal_group[i].tag == tag) {
! 1705: MTX_UNLOCK(&istgt->mutex);
! 1706: return &istgt->portal_group[i];
! 1707: }
! 1708: }
! 1709: MTX_UNLOCK(&istgt->mutex);
! 1710: return NULL;
! 1711: }
! 1712:
! 1713: #if 0
! 1714: static int
! 1715: istgt_get_num_of_portals(CF_SECTION *sp)
! 1716: {
! 1717: char *label, *portal;
! 1718: int portals;
! 1719: int rc;
! 1720: int i;
! 1721:
! 1722: for (i = 0; ; i++) {
! 1723: label = istgt_get_nmval(sp, "Portal", i, 0);
! 1724: portal = istgt_get_nmval(sp, "Portal", i, 1);
! 1725: if (label == NULL || portal == NULL)
! 1726: break;
! 1727: rc = istgt_parse_portal(portal, NULL, NULL);
! 1728: if (rc < 0) {
! 1729: ISTGT_ERRLOG("parse portal error (%s)\n", portal);
! 1730: return -1;
! 1731: }
! 1732: }
! 1733: portals = i;
! 1734: if (portals > MAX_PORTAL) {
! 1735: ISTGT_ERRLOG("%d > MAX_PORTAL\n", portals);
! 1736: return -1;
! 1737: }
! 1738: return portals;
! 1739: }
! 1740: #endif
! 1741:
! 1742: #define RELOAD_CMD_LENGTH 5
! 1743: static int
! 1744: istgt_pg_reload_delete(ISTGT_Ptr istgt)
! 1745: {
! 1746: char tmp[RELOAD_CMD_LENGTH];
! 1747: int rc;
! 1748:
! 1749: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_pg_reload_delete\n");
! 1750:
! 1751: istgt->pg_reload = 0;
! 1752: /* request delete */
! 1753: tmp[0] = 'D';
! 1754: DSET32(&tmp[1], 0);
! 1755: rc = write(istgt->sig_pipe[1], tmp, RELOAD_CMD_LENGTH);
! 1756: if (rc < 0 || rc != RELOAD_CMD_LENGTH) {
! 1757: ISTGT_ERRLOG("write() failed\n");
! 1758: return -1;
! 1759: }
! 1760: /* wait for completion */
! 1761: MTX_LOCK(&istgt->reload_mutex);
! 1762: while (istgt->pg_reload == 0) {
! 1763: pthread_cond_wait(&istgt->reload_cond, &istgt->reload_mutex);
! 1764: }
! 1765: rc = istgt->pg_reload;
! 1766: MTX_UNLOCK(&istgt->reload_mutex);
! 1767: if (rc < 0) {
! 1768: if (istgt_get_state(istgt) != ISTGT_STATE_RUNNING) {
! 1769: ISTGT_WARNLOG("pg_reload abort\n");
! 1770: return -1;
! 1771: }
! 1772: }
! 1773: return 0;
! 1774: }
! 1775:
! 1776: static int
! 1777: istgt_pg_reload_update(ISTGT_Ptr istgt)
! 1778: {
! 1779: char tmp[RELOAD_CMD_LENGTH];
! 1780: int rc;
! 1781:
! 1782: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_pg_reload_update\n");
! 1783:
! 1784: istgt->pg_reload = 0;
! 1785: /* request update */
! 1786: tmp[0] = 'U';
! 1787: DSET32(&tmp[1], 0);
! 1788: rc = write(istgt->sig_pipe[1], tmp, RELOAD_CMD_LENGTH);
! 1789: if (rc < 0 || rc != RELOAD_CMD_LENGTH) {
! 1790: ISTGT_ERRLOG("write() failed\n");
! 1791: return -1;
! 1792: }
! 1793: /* wait for completion */
! 1794: MTX_LOCK(&istgt->reload_mutex);
! 1795: while (istgt->pg_reload == 0) {
! 1796: pthread_cond_wait(&istgt->reload_cond, &istgt->reload_mutex);
! 1797: }
! 1798: rc = istgt->pg_reload;
! 1799: MTX_UNLOCK(&istgt->reload_mutex);
! 1800: if (rc < 0) {
! 1801: if (istgt_get_state(istgt) != ISTGT_STATE_RUNNING) {
! 1802: ISTGT_WARNLOG("pg_reload abort\n");
! 1803: return -1;
! 1804: }
! 1805: }
! 1806: return 0;
! 1807: }
! 1808:
! 1809: static int
! 1810: istgt_ig_exist_num(CONFIG *config, int num)
! 1811: {
! 1812: CF_SECTION *sp;
! 1813:
! 1814: sp = config->section;
! 1815: while (sp != NULL) {
! 1816: if (sp->type == ST_INITIATORGROUP) {
! 1817: if (sp->num == num) {
! 1818: return 1;
! 1819: }
! 1820: }
! 1821: sp = sp->next;
! 1822: }
! 1823: return -1;
! 1824: }
! 1825:
! 1826: static int
! 1827: istgt_ig_reload_delete(ISTGT_Ptr istgt)
! 1828: {
! 1829: INITIATOR_GROUP *igp;
! 1830: int rc;
! 1831: int i, j;
! 1832:
! 1833: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_ig_reload_delete\n");
! 1834: MTX_LOCK(&istgt->mutex);
! 1835: for (i = 0; i < istgt->ninitiator_group; i++) {
! 1836: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "IG reload idx=%d, (%d)\n",
! 1837: i, istgt->ninitiator_group);
! 1838: igp = &istgt->initiator_group[i];
! 1839: rc = istgt_ig_exist_num(istgt->config, igp->tag);
! 1840: if (rc < 0) {
! 1841: if (igp->ref != 0) {
! 1842: ISTGT_ERRLOG("delete request for referenced IG%d\n",
! 1843: igp->tag);
! 1844: } else {
! 1845: ISTGT_NOTICELOG("delete IG%d\n", igp->tag);
! 1846: /* free old IG */
! 1847: for (j = 0; j < istgt->initiator_group[i].ninitiators; j++) {
! 1848: xfree(istgt->initiator_group[i].initiators[j]);
! 1849: }
! 1850: xfree(istgt->initiator_group[i].initiators);
! 1851: for (j = 0; j < istgt->initiator_group[i].nnetmasks; j++) {
! 1852: xfree(istgt->initiator_group[i].netmasks[j]);
! 1853: }
! 1854: xfree(istgt->initiator_group[i].netmasks);
! 1855:
! 1856: /* move from beyond the IG */
! 1857: for (j = i; j < istgt->ninitiator_group - 1; j++) {
! 1858: istgt->initiator_group[j].ninitiators
! 1859: = istgt->initiator_group[j+1].ninitiators;
! 1860: istgt->initiator_group[j].initiators
! 1861: = istgt->initiator_group[j+1].initiators;
! 1862: istgt->initiator_group[j].nnetmasks
! 1863: = istgt->initiator_group[j+1].nnetmasks;
! 1864: istgt->initiator_group[j].netmasks
! 1865: = istgt->initiator_group[j+1].netmasks;
! 1866: istgt->initiator_group[j].ref
! 1867: = istgt->initiator_group[j+1].ref;
! 1868: istgt->initiator_group[j].idx
! 1869: = istgt->initiator_group[j+1].idx;
! 1870: istgt->initiator_group[j].tag
! 1871: = istgt->initiator_group[j+1].tag;
! 1872: }
! 1873: istgt->ninitiator_group--;
! 1874: }
! 1875: }
! 1876: }
! 1877: MTX_UNLOCK(&istgt->mutex);
! 1878: return 0;
! 1879: }
! 1880:
! 1881: static int
! 1882: istgt_ig_reload_update(ISTGT_Ptr istgt)
! 1883: {
! 1884: CF_SECTION *sp;
! 1885: int rc;
! 1886: int i;
! 1887:
! 1888: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_ig_reload_update\n");
! 1889: sp = istgt->config->section;
! 1890: while (sp != NULL) {
! 1891: if (sp->type == ST_INITIATORGROUP) {
! 1892: if (sp->num == 0) {
! 1893: ISTGT_ERRLOG("Group 0 is invalid\n");
! 1894: goto skip_ig;
! 1895: }
! 1896: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "IG reload tag=%d\n", sp->num);
! 1897: #if 0
! 1898: rc = istgt_ig_exist_num(istgt->config_old, sp->num);
! 1899: #else
! 1900: rc = -1;
! 1901: MTX_LOCK(&istgt->mutex);
! 1902: for (i = 0; i < istgt->ninitiator_group; i++) {
! 1903: if (istgt->initiator_group[i].tag == sp->num) {
! 1904: rc = 1;
! 1905: break;
! 1906: }
! 1907: }
! 1908: MTX_UNLOCK(&istgt->mutex);
! 1909: #endif
! 1910: if (rc < 0) {
! 1911: rc = istgt_add_initiator_group(istgt, sp);
! 1912: if (rc < 0) {
! 1913: ISTGT_ERRLOG("add_initiator_group() failed\n");
! 1914: goto skip_ig;
! 1915: }
! 1916: ISTGT_NOTICELOG("add IG%d\n", sp->num);
! 1917: } else {
! 1918: rc = istgt_update_initiator_group(istgt, sp);
! 1919: if (rc < 0) {
! 1920: ISTGT_ERRLOG("update_initiator_group() failed\n");
! 1921: goto skip_ig;
! 1922: } else if (rc == 0) {
! 1923: // not modified
! 1924: } else if (rc > 0) {
! 1925: ISTGT_NOTICELOG("update IG%d\n", sp->num);
! 1926: }
! 1927: }
! 1928: }
! 1929: skip_ig:
! 1930: sp = sp->next;
! 1931: }
! 1932: return 0;
! 1933: }
! 1934:
! 1935: static int
! 1936: istgt_reload(ISTGT_Ptr istgt)
! 1937: {
! 1938: CONFIG *config_new, *config_old;
! 1939: char *config_file;
! 1940: int rc;
! 1941:
! 1942: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_reload\n");
! 1943: /* prepare config structure */
! 1944: config_new = istgt_allocate_config();
! 1945: config_old = istgt->config;
! 1946: config_file = config_old->file;
! 1947: rc = istgt_read_config(config_new, config_file);
! 1948: if (rc < 0) {
! 1949: ISTGT_ERRLOG("config error\n");
! 1950: return -1;
! 1951: }
! 1952: if (config_new->section == NULL) {
! 1953: ISTGT_ERRLOG("empty config\n");
! 1954: istgt_free_config(config_new);
! 1955: return -1;
! 1956: }
! 1957: istgt->config = config_new;
! 1958: istgt->config_old = config_old;
! 1959: istgt->generation++;
! 1960:
! 1961: /* reload sub groups */
! 1962: ISTGT_NOTICELOG("reload configuration #%"PRIu32"\n", istgt->generation);
! 1963: rc = istgt_lu_reload_delete(istgt);
! 1964: if (rc < 0) {
! 1965: ISTGT_ERRLOG("LU reload del error\n");
! 1966: return -1;
! 1967: }
! 1968: rc = istgt_ig_reload_delete(istgt);
! 1969: if (rc < 0) {
! 1970: ISTGT_ERRLOG("IG reload del error\n");
! 1971: return -1;
! 1972: }
! 1973: rc = istgt_pg_reload_delete(istgt);
! 1974: if (rc < 0) {
! 1975: ISTGT_ERRLOG("PG reload del error\n");
! 1976: return -1;
! 1977: }
! 1978:
! 1979: rc = istgt_pg_reload_update(istgt);
! 1980: if (rc < 0) {
! 1981: ISTGT_ERRLOG("PG reload add error\n");
! 1982: return -1;
! 1983: }
! 1984: rc = istgt_ig_reload_update(istgt);
! 1985: if (rc < 0) {
! 1986: ISTGT_ERRLOG("IG reload add error\n");
! 1987: return -1;
! 1988: }
! 1989: rc = istgt_lu_reload_update(istgt);
! 1990: if (rc < 0) {
! 1991: ISTGT_ERRLOG("LU reload add error\n");
! 1992: return -1;
! 1993: }
! 1994:
! 1995: istgt->config_old = NULL;
! 1996: istgt_free_config(config_old);
! 1997: return 0;
! 1998: }
! 1999:
! 2000: static int
! 2001: istgt_stop_loop(ISTGT_Ptr istgt)
! 2002: {
! 2003: char tmp[RELOAD_CMD_LENGTH];
! 2004: int rc;
! 2005:
! 2006: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_stop_loop\n");
! 2007: tmp[0] = 'E';
! 2008: DSET32(&tmp[1], 0);
! 2009: rc = write(istgt->sig_pipe[1], tmp, RELOAD_CMD_LENGTH);
! 2010: if (rc < 0 || rc != RELOAD_CMD_LENGTH) {
! 2011: ISTGT_ERRLOG("write() failed\n");
! 2012: /* ignore error */
! 2013: }
! 2014: return 0;
! 2015: }
! 2016:
! 2017:
! 2018: static void
! 2019: istgt_sigint(int signo __attribute__((__unused__)))
! 2020: {
! 2021: }
! 2022:
! 2023: static void
! 2024: istgt_sigterm(int signo __attribute__((__unused__)))
! 2025: {
! 2026: }
! 2027:
! 2028: static void
! 2029: istgt_sighup(int signo __attribute__((__unused__)))
! 2030: {
! 2031: }
! 2032:
! 2033: #ifdef SIGINFO
! 2034: static void
! 2035: istgt_siginfo(int signo __attribute__((__unused__)))
1.1 misho 2036: {
2037: /* nothing */
2038: }
2039: #endif
2040:
2041: static void
1.1.1.2 ! misho 2042: istgt_sigwakeup(int signo __attribute__((__unused__)))
1.1 misho 2043: {
2044: }
2045:
2046: #ifdef SIGIO
2047: static void
1.1.1.2 ! misho 2048: istgt_sigio(int signo __attribute__((__unused__)))
1.1 misho 2049: {
2050: }
2051: #endif
2052:
2053: static void *
2054: istgt_sighandler(void *arg)
2055: {
2056: ISTGT_Ptr istgt = (ISTGT_Ptr) arg;
2057: sigset_t signew;
2058: int signo;
2059:
2060: sigemptyset(&signew);
2061: sigaddset(&signew, SIGINT);
2062: sigaddset(&signew, SIGTERM);
2063: sigaddset(&signew, SIGQUIT);
2064: sigaddset(&signew, SIGHUP);
2065: #ifdef SIGINFO
2066: sigaddset(&signew, SIGINFO);
2067: #endif
2068: sigaddset(&signew, SIGUSR1);
2069: sigaddset(&signew, SIGUSR2);
2070: #ifdef SIGIO
2071: sigaddset(&signew, SIGIO);
2072: #endif
2073:
2074: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "loop start\n");
2075: while (1) {
2076: if (istgt_get_state(istgt) == ISTGT_STATE_EXITING
2077: || istgt_get_state(istgt) == ISTGT_STATE_SHUTDOWN) {
2078: break;
2079: }
2080: sigwait(&signew, &signo);
2081: switch (signo) {
2082: case SIGINT:
2083: printf("SIGINT catch\n");
1.1.1.2 ! misho 2084: istgt_stop_loop(istgt);
1.1 misho 2085: istgt_set_state(istgt, ISTGT_STATE_EXITING);
2086: istgt_lu_set_all_state(istgt, ISTGT_STATE_EXITING);
2087: break;
2088: case SIGTERM:
2089: printf("SIGTERM catch\n");
1.1.1.2 ! misho 2090: istgt_stop_loop(istgt);
1.1 misho 2091: istgt_set_state(istgt, ISTGT_STATE_EXITING);
2092: istgt_lu_set_all_state(istgt, ISTGT_STATE_EXITING);
2093: break;
2094: case SIGQUIT:
2095: printf("SIGQUIT catch\n");
2096: exit(EXIT_SUCCESS);
2097: break;
2098: case SIGHUP:
2099: printf("SIGHUP catch\n");
1.1.1.2 ! misho 2100: istgt_reload(istgt);
1.1 misho 2101: break;
2102: #ifdef SIGINFO
2103: case SIGINFO:
2104: printf("SIGINFO catch\n");
2105: istgt_set_trace_flag(ISTGT_TRACE_ISCSI);
2106: break;
2107: #endif
2108: case SIGUSR1:
2109: printf("SIGUSR1 catch\n");
2110: istgt_set_trace_flag(ISTGT_TRACE_NONE);
2111: break;
2112: case SIGUSR2:
2113: printf("SIGUSR2 catch\n");
2114: //istgt_set_trace_flag(ISTGT_TRACE_SCSI);
2115: istgt_set_trace_flag(ISTGT_TRACE_ALL);
2116: break;
2117: #ifdef SIGIO
2118: case SIGIO:
2119: //printf("SIGIO catch\n");
2120: break;
2121: #endif
2122: default:
2123: break;
2124: }
2125: }
2126: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "loop ended\n");
2127:
2128: return NULL;
2129: }
2130:
1.1.1.2 ! misho 2131: static PORTAL *
! 2132: istgt_get_sock_portal(ISTGT_Ptr istgt, int sock)
! 2133: {
! 2134: int i, j;
! 2135:
! 2136: if (sock < 0)
! 2137: return NULL;
! 2138: MTX_LOCK(&istgt->mutex);
! 2139: for (i = 0; i < istgt->nportal_group; i++) {
! 2140: for (j = 0; j < istgt->portal_group[i].nportals; j++) {
! 2141: if (istgt->portal_group[i].portals[j]->sock == sock) {
! 2142: MTX_UNLOCK(&istgt->mutex);
! 2143: return istgt->portal_group[i].portals[j];
! 2144: }
! 2145: }
! 2146: }
! 2147: MTX_UNLOCK(&istgt->mutex);
! 2148: return NULL;
! 2149: }
! 2150:
! 2151: static int
! 2152: istgt_pg_delete(ISTGT_Ptr istgt)
! 2153: {
! 2154: PORTAL_GROUP *pgp;
! 2155: int rc;
! 2156: int i;
! 2157:
! 2158: MTX_LOCK(&istgt->mutex);
! 2159: for (i = 0; i < istgt->nportal_group; i++) {
! 2160: pgp = &istgt->portal_group[i];
! 2161: if (pgp->tag == 0)
! 2162: continue;
! 2163: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "PG reload idx=%d, tag=%d, (%d)\n",
! 2164: i, pgp->tag, istgt->nportal_group);
! 2165: rc = istgt_pg_exist_num(istgt->config, pgp->tag);
! 2166: if (rc < 0) {
! 2167: if (pgp->ref != 0) {
! 2168: ISTGT_ERRLOG("delete request for referenced PG%d\n",
! 2169: pgp->tag);
! 2170: } else {
! 2171: ISTGT_NOTICELOG("delete PG%d\n", pgp->tag);
! 2172: pgp->tag = 0;
! 2173: (void) istgt_close_portal_group(pgp);
! 2174: }
! 2175: }
! 2176: }
! 2177: MTX_UNLOCK(&istgt->mutex);
! 2178: return 0;
! 2179: }
! 2180:
! 2181: static int
! 2182: istgt_pg_update(ISTGT_Ptr istgt)
! 2183: {
! 2184: PORTAL_GROUP *pgp;
! 2185: CF_SECTION *sp;
! 2186: int pgp_idx;
! 2187: int rc;
! 2188: int i;
! 2189:
! 2190: sp = istgt->config->section;
! 2191: while (sp != NULL) {
! 2192: if (sp->type == ST_PORTALGROUP) {
! 2193: if (sp->num == 0) {
! 2194: ISTGT_ERRLOG("Group 0 is invalid\n");
! 2195: goto skip_pg;
! 2196: }
! 2197: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "PG reload tag=%d\n", sp->num);
! 2198: #if 0
! 2199: rc = istgt_pg_exist_num(istgt->config_old, sp->num);
! 2200: #else
! 2201: rc = -1;
! 2202: MTX_LOCK(&istgt->mutex);
! 2203: for (i = 0; i < istgt->nportal_group; i++) {
! 2204: if (istgt->portal_group[i].tag == sp->num) {
! 2205: rc = 1;
! 2206: break;
! 2207: }
! 2208: }
! 2209: MTX_UNLOCK(&istgt->mutex);
! 2210: #endif
! 2211: if (rc < 0) {
! 2212: rc = istgt_add_portal_group(istgt, sp, &pgp_idx);
! 2213: if (rc < 0) {
! 2214: ISTGT_ERRLOG("add_portal_group() failed\n");
! 2215: goto skip_pg;
! 2216: }
! 2217: MTX_LOCK(&istgt->mutex);
! 2218: pgp = &istgt->portal_group[pgp_idx];
! 2219: (void) istgt_open_portal_group(pgp);
! 2220: MTX_UNLOCK(&istgt->mutex);
! 2221: ISTGT_NOTICELOG("add PG%d\n", sp->num);
! 2222: } else {
! 2223: //portals = istgt_get_num_of_portals(sp);
! 2224: pgp = istgt_get_tag_portal(istgt, sp->num);
! 2225: if (istgt_pg_match_all(pgp, sp)) {
! 2226: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
! 2227: "skip for PG%d\n", sp->num);
! 2228: } else if (pgp->ref != 0) {
! 2229: ISTGT_ERRLOG("update request for referenced PG%d\n",
! 2230: pgp->tag);
! 2231: } else {
! 2232: /* delete old sock */
! 2233: MTX_LOCK(&istgt->mutex);
! 2234: pgp_idx = pgp->idx;
! 2235: (void) istgt_close_portal_group(pgp);
! 2236: MTX_UNLOCK(&istgt->mutex);
! 2237: rc = istgt_update_portal_group(istgt, sp, &pgp_idx);
! 2238: if (rc < 0) {
! 2239: ISTGT_ERRLOG("update_portal_group() failed\n");
! 2240: goto skip_pg;
! 2241: } else if (rc == 0) {
! 2242: // not modified
! 2243: } else if (rc > 0) {
! 2244: /* add new sock */
! 2245: MTX_LOCK(&istgt->mutex);
! 2246: pgp = &istgt->portal_group[pgp_idx];
! 2247: (void) istgt_open_portal_group(pgp);
! 2248: MTX_UNLOCK(&istgt->mutex);
! 2249: ISTGT_NOTICELOG("update PG%d\n", sp->num);
! 2250: }
! 2251: }
! 2252: }
! 2253: }
! 2254: skip_pg:
! 2255: sp = sp->next;
! 2256: }
! 2257: return 0;
! 2258: }
! 2259:
1.1 misho 2260: static int
2261: istgt_acceptor(ISTGT_Ptr istgt)
2262: {
1.1.1.2 ! misho 2263: PORTAL *pp;
1.1 misho 2264: #ifdef ISTGT_USE_KQUEUE
2265: int kq;
2266: struct kevent kev;
2267: struct timespec kev_timeout;
1.1.1.2 ! misho 2268: int kqsocks[MAX_PORTAL_GROUP + MAX_UCPORTAL];
1.1 misho 2269: #else
1.1.1.2 ! misho 2270: struct pollfd fds[MAX_PORTAL_GROUP + MAX_UCPORTAL];
1.1 misho 2271: #endif /* ISTGT_USE_KQUEUE */
2272: struct sockaddr_storage sa;
2273: socklen_t salen;
2274: int sock;
2275: int rc, n;
2276: int ucidx;
2277: int nidx;
1.1.1.2 ! misho 2278: int i, j;
1.1 misho 2279:
2280: if (istgt_get_state(istgt) != ISTGT_STATE_INITIALIZED) {
2281: ISTGT_ERRLOG("not initialized\n");
2282: return -1;
2283: }
2284: /* now running main thread */
2285: istgt_set_state(istgt, ISTGT_STATE_RUNNING);
2286:
1.1.1.2 ! misho 2287: reload:
! 2288: nidx = 0;
1.1 misho 2289: #ifdef ISTGT_USE_KQUEUE
2290: kq = kqueue();
2291: if (kq == -1) {
2292: ISTGT_ERRLOG("kqueue() failed\n");
2293: return -1;
2294: }
1.1.1.2 ! misho 2295: for (i = 0; i < (int)(sizeof kqsocks / sizeof *kqsocks); i++) {
! 2296: kqsocks[i] = -1;
! 2297: }
! 2298: MTX_LOCK(&istgt->mutex);
! 2299: for (i = 0; i < istgt->nportal_group; i++) {
! 2300: for (j = 0; j < istgt->portal_group[i].nportals; j++) {
! 2301: if (istgt->portal_group[i].portals[j]->sock >= 0) {
! 2302: ISTGT_EV_SET(&kev, istgt->portal_group[i].portals[j]->sock,
! 2303: EVFILT_READ, EV_ADD, 0, 0, NULL);
! 2304: rc = kevent(kq, &kev, 1, NULL, 0, NULL);
! 2305: if (rc == -1) {
! 2306: MTX_UNLOCK(&istgt->mutex);
! 2307: ISTGT_ERRLOG("kevent() failed\n");
! 2308: close(kq);
! 2309: return -1;
! 2310: }
! 2311: kqsocks[nidx] = istgt->portal_group[i].portals[j]->sock;
! 2312: nidx++;
! 2313: }
1.1 misho 2314: }
2315: }
1.1.1.2 ! misho 2316: MTX_UNLOCK(&istgt->mutex);
! 2317: ucidx = nidx;
1.1 misho 2318: for (i = 0; i < istgt->nuctl_portal; i++) {
1.1.1.2 ! misho 2319: ISTGT_EV_SET(&kev, istgt->uctl_portal[i].sock,
1.1 misho 2320: EVFILT_READ, EV_ADD, 0, 0, NULL);
2321: rc = kevent(kq, &kev, 1, NULL, 0, NULL);
2322: if (rc == -1) {
2323: ISTGT_ERRLOG("kevent() failed\n");
2324: close(kq);
2325: return -1;
2326: }
1.1.1.2 ! misho 2327: kqsocks[nidx] = istgt->uctl_portal[i].sock;
! 2328: nidx++;
1.1 misho 2329: }
1.1.1.2 ! misho 2330: ISTGT_EV_SET(&kev, istgt->sig_pipe[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
1.1 misho 2331: rc = kevent(kq, &kev, 1, NULL, 0, NULL);
2332: if (rc == -1) {
2333: ISTGT_ERRLOG("kevent() failed\n");
2334: close(kq);
2335: return -1;
2336: }
1.1.1.2 ! misho 2337: kqsocks[nidx] = istgt->sig_pipe[0];
! 2338: nidx++;
! 2339:
! 2340: if (!istgt->daemon) {
! 2341: ISTGT_EV_SET(&kev, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
! 2342: rc = kevent(kq, &kev, 1, NULL, 0, NULL);
! 2343: if (rc == -1) {
! 2344: ISTGT_ERRLOG("kevent() failed\n");
! 2345: close(kq);
! 2346: return -1;
! 2347: }
! 2348: ISTGT_EV_SET(&kev, SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
! 2349: rc = kevent(kq, &kev, 1, NULL, 0, NULL);
! 2350: if (rc == -1) {
! 2351: ISTGT_ERRLOG("kevent() failed\n");
! 2352: close(kq);
! 2353: return -1;
! 2354: }
1.1 misho 2355: }
2356: #else
2357: memset(&fds, 0, sizeof fds);
1.1.1.2 ! misho 2358: MTX_LOCK(&istgt->mutex);
! 2359: for (i = 0; i < istgt->nportal_group; i++) {
! 2360: for (j = 0; j < istgt->portal_group[i].nportals; j++) {
! 2361: if (istgt->portal_group[i].portals[j]->sock >= 0) {
! 2362: fds[i].fd = istgt->portal_group[i].portals[j]->sock;
! 2363: fds[i].events = POLLIN;
! 2364: nidx++;
! 2365: }
! 2366: }
1.1 misho 2367: }
1.1.1.2 ! misho 2368: MTX_UNLOCK(&istgt->mutex);
! 2369: ucidx = nidx;
1.1 misho 2370: for (i = 0; i < istgt->nuctl_portal; i++) {
2371: fds[ucidx + i].fd = istgt->uctl_portal[i].sock;
2372: fds[ucidx + i].events = POLLIN;
1.1.1.2 ! misho 2373: nidx++;
1.1 misho 2374: }
1.1.1.2 ! misho 2375: fds[nidx].fd = istgt->sig_pipe[0];
! 2376: fds[nidx].events = POLLIN;
! 2377: nidx++;
1.1 misho 2378: #endif /* ISTGT_USE_KQUEUE */
2379:
2380: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "loop start\n");
2381: while (1) {
2382: if (istgt_get_state(istgt) != ISTGT_STATE_RUNNING) {
2383: break;
2384: }
2385: #ifdef ISTGT_USE_KQUEUE
2386: //ISTGT_TRACELOG(ISTGT_TRACE_NET, "kevent %d\n", nidx);
2387: kev_timeout.tv_sec = 10;
2388: kev_timeout.tv_nsec = 0;
2389: rc = kevent(kq, NULL, 0, &kev, 1, &kev_timeout);
2390: if (rc == -1 && errno == EINTR) {
2391: continue;
2392: }
2393: if (rc == -1) {
2394: ISTGT_ERRLOG("kevent() failed\n");
2395: break;
2396: }
2397: if (rc == 0) {
2398: /* idle timeout */
1.1.1.2 ! misho 2399: //ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "kevent TIMEOUT\n");
1.1 misho 2400: continue;
2401: }
2402: if (kev.filter == EVFILT_SIGNAL) {
2403: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "kevent SIGNAL\n");
2404: if (kev.ident == SIGINT || kev.ident == SIGTERM) {
2405: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
2406: "kevent SIGNAL SIGINT/SIGTERM\n");
2407: break;
2408: }
2409: continue;
2410: }
2411: #else
2412: //ISTGT_TRACELOG(ISTGT_TRACE_NET, "poll %d\n", nidx);
2413: rc = poll(fds, nidx, POLLWAIT);
2414: if (rc == -1 && errno == EINTR) {
2415: continue;
2416: }
2417: if (rc == -1) {
2418: ISTGT_ERRLOG("poll() failed\n");
2419: break;
2420: }
2421: if (rc == 0) {
2422: /* no fds */
1.1.1.2 ! misho 2423: //ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "poll TIMEOUT\n");
1.1 misho 2424: continue;
2425: }
2426: #endif /* ISTGT_USE_KQUEUE */
2427:
2428: n = rc;
1.1.1.2 ! misho 2429: for (i = 0; n != 0 && i < ucidx; i++) {
1.1 misho 2430: #ifdef ISTGT_USE_KQUEUE
1.1.1.2 ! misho 2431: if (kev.ident == (uintptr_t)kqsocks[i]) {
1.1 misho 2432: if (kev.flags) {
2433: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
2434: "flags %x\n",
2435: kev.flags);
2436: }
2437: #else
2438: if (fds[i].revents) {
2439: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
2440: "events %x\n",
2441: fds[i].revents);
2442: }
2443: if (fds[i].revents & POLLIN) {
2444: #endif /* ISTGT_USE_KQUEUE */
2445: n--;
2446: memset(&sa, 0, sizeof(sa));
2447: salen = sizeof(sa);
2448: #ifdef ISTGT_USE_KQUEUE
1.1.1.2 ! misho 2449: ISTGT_TRACELOG(ISTGT_TRACE_NET, "accept %ld\n",
! 2450: (unsigned long)kev.ident);
! 2451: pp = istgt_get_sock_portal(istgt, kev.ident);
1.1 misho 2452: rc = accept(kev.ident, (struct sockaddr *) &sa, &salen);
2453: #else
2454: ISTGT_TRACELOG(ISTGT_TRACE_NET, "accept %d\n",
2455: fds[i].fd);
1.1.1.2 ! misho 2456: pp = istgt_get_sock_portal(istgt, fds[i].fd);
1.1 misho 2457: rc = accept(fds[i].fd, (struct sockaddr *) &sa, &salen);
2458: #endif /* ISTGT_USE_KQUEUE */
2459: if (rc < 0) {
2460: ISTGT_ERRLOG("accept error: %d\n", rc);
2461: continue;
2462: }
2463: sock = rc;
2464: #if 0
2465: rc = fcntl(sock, F_GETFL, 0);
2466: if (rc == -1) {
2467: ISTGT_ERRLOG("fcntl() failed\n");
2468: continue;
2469: }
2470: rc = fcntl(sock, F_SETFL, (rc | O_NONBLOCK));
2471: if (rc == -1) {
2472: ISTGT_ERRLOG("fcntl() failed\n");
2473: continue;
2474: }
2475: #endif
1.1.1.2 ! misho 2476: rc = istgt_create_conn(istgt, pp, sock,
1.1 misho 2477: (struct sockaddr *) &sa, salen);
2478: if (rc < 0) {
2479: close(sock);
2480: ISTGT_ERRLOG("istgt_create_conn() failed\n");
2481: continue;
2482: }
2483: }
2484: }
2485:
2486: /* check for control */
2487: for (i = 0; n != 0 && i < istgt->nuctl_portal; i++) {
2488: #ifdef ISTGT_USE_KQUEUE
1.1.1.2 ! misho 2489: if (kev.ident == (uintptr_t)istgt->uctl_portal[i].sock) {
1.1 misho 2490: if (kev.flags) {
2491: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
2492: "flags %x\n",
2493: kev.flags);
2494: }
2495: #else
2496: if (fds[ucidx + i].revents) {
2497: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
2498: "events %x\n",
2499: fds[ucidx + i].revents);
2500: }
2501: if (fds[ucidx + i].revents & POLLIN) {
2502: #endif /* ISTGT_USE_KQUEUE */
2503: n--;
2504: memset(&sa, 0, sizeof(sa));
2505: salen = sizeof(sa);
2506: #ifdef ISTGT_USE_KQUEUE
2507: ISTGT_TRACELOG(ISTGT_TRACE_NET,
1.1.1.2 ! misho 2508: "accept %ld\n", (unsigned long)kev.ident);
1.1 misho 2509: rc = accept(kev.ident,
2510: (struct sockaddr *) &sa, &salen);
2511: #else
2512: ISTGT_TRACELOG(ISTGT_TRACE_NET,
2513: "accept %d\n", fds[ucidx + i].fd);
2514: rc = accept(fds[ucidx + i].fd,
2515: (struct sockaddr *) &sa, &salen);
2516: #endif /* ISTGT_USE_KQUEUE */
2517: if (rc < 0) {
2518: ISTGT_ERRLOG("accept error: %d\n", rc);
2519: continue;
2520: }
2521: sock = rc;
2522: rc = istgt_create_uctl(istgt,
2523: &istgt->uctl_portal[i], sock,
2524: (struct sockaddr *) &sa, salen);
2525: if (rc < 0) {
2526: close(sock);
2527: ISTGT_ERRLOG("istgt_create_uctl() failed\n");
2528: continue;
2529: }
2530: }
2531: }
1.1.1.2 ! misho 2532:
! 2533: /* check for signal thread */
! 2534: #ifdef ISTGT_USE_KQUEUE
! 2535: if (kev.ident == (uintptr_t)istgt->sig_pipe[0]) {
! 2536: if (kev.flags & (EV_EOF|EV_ERROR)) {
! 2537: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
! 2538: "kevent EOF/ERROR\n");
! 2539: break;
! 2540: }
! 2541: #else
! 2542: if (fds[nidx - 1].revents & POLLHUP) {
! 2543: break;
! 2544: }
! 2545: if (fds[nidx - 1].revents & POLLIN) {
! 2546: #endif /* ISTGT_USE_KQUEUE */
! 2547: char tmp[RELOAD_CMD_LENGTH];
! 2548: //int pgp_idx;
! 2549: int rc2;
! 2550:
! 2551: rc = read(istgt->sig_pipe[0], tmp, RELOAD_CMD_LENGTH);
! 2552: if (rc < 0 || rc == 0 || rc != RELOAD_CMD_LENGTH) {
! 2553: ISTGT_ERRLOG("read() failed\n");
! 2554: break;
! 2555: }
! 2556: //pgp_idx = (int)DGET32(&tmp[1]);
! 2557:
! 2558: if (tmp[0] == 'E') {
! 2559: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG,
! 2560: "exit request (main loop)\n");
! 2561: break;
! 2562: }
! 2563: if (tmp[0] == 'D') {
! 2564: rc = istgt_pg_delete(istgt);
! 2565: MTX_LOCK(&istgt->reload_mutex);
! 2566: istgt->pg_reload = rc < 0 ? -1 : 1;
! 2567: rc2 = pthread_cond_broadcast(&istgt->reload_cond);
! 2568: if (rc2 != 0) {
! 2569: ISTGT_ERRLOG("cond_broadcast() failed\n");
! 2570: }
! 2571: MTX_UNLOCK(&istgt->reload_mutex);
! 2572: if (rc < 0) {
! 2573: ISTGT_ERRLOG("pg_delete() failed\n");
! 2574: //break;
! 2575: }
! 2576: }
! 2577: if (tmp[0] == 'U') {
! 2578: rc = istgt_pg_update(istgt);
! 2579: MTX_LOCK(&istgt->reload_mutex);
! 2580: istgt->pg_reload = rc < 0 ? -1 : 1;
! 2581: rc2 = pthread_cond_broadcast(&istgt->reload_cond);
! 2582: if (rc2 != 0) {
! 2583: ISTGT_ERRLOG("cond_broadcast() failed\n");
! 2584: }
! 2585: MTX_UNLOCK(&istgt->reload_mutex);
! 2586: if (rc < 0) {
! 2587: ISTGT_ERRLOG("pg_update() failed\n");
! 2588: //break;
! 2589: }
! 2590: }
! 2591: #ifdef ISTGT_USE_KQUEUE
! 2592: close(kq);
! 2593: #endif /* ISTGT_USE_KQUEUE */
! 2594: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "reload accept loop\n");
! 2595: goto reload;
! 2596: }
1.1 misho 2597: }
2598: #ifdef ISTGT_USE_KQUEUE
2599: close(kq);
2600: #endif /* ISTGT_USE_KQUEUE */
2601: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "loop ended\n");
2602: istgt_set_state(istgt, ISTGT_STATE_EXITING);
1.1.1.2 ! misho 2603: istgt_lu_set_all_state(istgt, ISTGT_STATE_EXITING);
1.1 misho 2604:
2605: return 0;
2606: }
2607:
2608: static void
2609: usage(void)
2610: {
2611: printf("istgt [options]\n");
2612: printf("options:\n");
2613: printf(" -c config config file (default %s)\n", DEFAULT_CONFIG);
2614: printf(" -p pidfile use specific file\n");
2615: printf(" -l facility use specific syslog facility (default %s)\n",
2616: DEFAULT_LOG_FACILITY);
2617: printf(" -m mode operational mode (default %d, 0=traditional, "
2618: "1=normal, 2=experimental)\n", DEFAULT_ISTGT_SWMODE);
2619: printf(" -t flag trace flag (all, net, iscsi, scsi, lu)\n");
2620: printf(" -q quiet warnings\n");
2621: printf(" -D don't detach from tty\n");
2622: printf(" -H show this usage\n");
2623: printf(" -V show version\n");
2624: }
2625:
2626: int
2627: main(int argc, char **argv)
2628: {
2629: ISTGT_Ptr istgt;
2630: const char *config_file = DEFAULT_CONFIG;
2631: const char *pidfile = NULL;
2632: const char *logfacility = NULL;
2633: const char *logpriority = NULL;
2634: CONFIG *config;
2635: pthread_t sigthread;
1.1.1.2 ! misho 2636: struct sigaction sigact, sigoldact_pipe, sigoldact_int, sigoldact_term;
! 2637: struct sigaction sigoldact_hup, sigoldact_info;
1.1 misho 2638: struct sigaction sigoldact_wakeup, sigoldact_io;
2639: sigset_t signew, sigold;
2640: int retry = 10;
2641: int detach = 1;
2642: int swmode;
2643: int ch;
2644: int rc;
2645:
2646: if (sizeof (ISCSI_BHS) != ISCSI_BHS_LEN) {
2647: fprintf(stderr, "Internal Error\n");
2648: exit(EXIT_FAILURE);
2649: }
2650:
2651: memset(&g_istgt, 0, sizeof g_istgt);
2652: istgt = &g_istgt;
1.1.1.2 ! misho 2653: istgt->state = ISTGT_STATE_INVALID;
1.1 misho 2654: istgt->swmode = DEFAULT_ISTGT_SWMODE;
1.1.1.2 ! misho 2655: istgt->sig_pipe[0] = istgt->sig_pipe[1] = -1;
! 2656: istgt->daemon = 0;
! 2657: istgt->generation = 0;
1.1 misho 2658:
2659: while ((ch = getopt(argc, argv, "c:p:l:m:t:qDHV")) != -1) {
2660: switch (ch) {
2661: case 'c':
2662: config_file = optarg;
2663: break;
2664: case 'p':
2665: pidfile = optarg;
2666: break;
2667: case 'l':
2668: logfacility = optarg;
2669: break;
2670: case 'm':
2671: swmode = strtol(optarg, NULL, 10);
2672: if (swmode == ISTGT_SWMODE_TRADITIONAL
2673: || swmode == ISTGT_SWMODE_NORMAL
2674: || swmode == ISTGT_SWMODE_EXPERIMENTAL) {
2675: istgt->swmode = swmode;
2676: } else {
2677: fprintf(stderr, "unknown mode %x\n", swmode);
2678: usage();
2679: exit(EXIT_FAILURE);
2680: }
2681: break;
2682: case 't':
2683: if (strcasecmp(optarg, "NET") == 0) {
2684: istgt_set_trace_flag(ISTGT_TRACE_NET);
2685: } else if (strcasecmp(optarg, "ISCSI") == 0) {
2686: istgt_set_trace_flag(ISTGT_TRACE_ISCSI);
2687: } else if (strcasecmp(optarg, "SCSI") == 0) {
2688: istgt_set_trace_flag(ISTGT_TRACE_SCSI);
2689: } else if (strcasecmp(optarg, "LU") == 0) {
2690: istgt_set_trace_flag(ISTGT_TRACE_LU);
2691: } else if (strcasecmp(optarg, "ALL") == 0) {
2692: istgt_set_trace_flag(ISTGT_TRACE_ALL);
2693: } else if (strcasecmp(optarg, "NONE") == 0) {
2694: istgt_set_trace_flag(ISTGT_TRACE_NONE);
2695: } else {
2696: fprintf(stderr, "unknown flag\n");
2697: usage();
2698: exit(EXIT_FAILURE);
2699: }
2700: break;
2701: case 'q':
2702: g_warn_flag = 0;
2703: break;
2704: case 'D':
2705: detach = 0;
2706: break;
2707: case 'V':
2708: printf("istgt version %s\n", ISTGT_VERSION);
2709: printf("istgt extra version %s\n", ISTGT_EXTRA_VERSION);
2710: exit(EXIT_SUCCESS);
2711: case 'H':
2712: default:
2713: usage();
2714: exit(EXIT_SUCCESS);
2715: }
2716: }
2717:
2718: /* read config files */
2719: config = istgt_allocate_config();
2720: rc = istgt_read_config(config, config_file);
2721: if (rc < 0) {
2722: fprintf(stderr, "config error\n");
2723: exit(EXIT_FAILURE);
2724: }
2725: if (config->section == NULL) {
2726: fprintf(stderr, "empty config\n");
2727: istgt_free_config(config);
2728: exit(EXIT_FAILURE);
2729: }
2730: istgt->config = config;
1.1.1.2 ! misho 2731: istgt->config_old = NULL;
1.1 misho 2732: //istgt_print_config(config);
2733:
2734: /* open log files */
2735: if (logfacility == NULL) {
2736: logfacility = istgt_get_log_facility(config);
2737: }
2738: rc = istgt_set_log_facility(logfacility);
2739: if (rc < 0) {
2740: fprintf(stderr, "log facility error\n");
2741: istgt_free_config(config);
2742: exit(EXIT_FAILURE);
2743: }
2744: if (logpriority == NULL) {
2745: logpriority = DEFAULT_LOG_PRIORITY;
2746: }
2747: rc = istgt_set_log_priority(logpriority);
2748: if (rc < 0) {
2749: fprintf(stderr, "log priority error\n");
2750: istgt_free_config(config);
2751: exit(EXIT_FAILURE);
2752: }
2753: istgt_open_log();
2754:
2755: ISTGT_NOTICELOG("istgt version %s (%s)\n", ISTGT_VERSION,
2756: ISTGT_EXTRA_VERSION);
2757: switch (istgt->swmode) {
2758: case ISTGT_SWMODE_TRADITIONAL:
2759: ISTGT_NOTICELOG("traditional mode\n");
2760: break;
2761: case ISTGT_SWMODE_NORMAL:
2762: ISTGT_NOTICELOG("normal mode\n");
2763: break;
2764: case ISTGT_SWMODE_EXPERIMENTAL:
2765: ISTGT_NOTICELOG("experimental mode\n");
2766: break;
2767: default:
2768: break;
2769: }
1.1.1.2 ! misho 2770: #ifdef ISTGT_USE_KQUEUE
! 2771: ISTGT_NOTICELOG("using kqueue\n");
! 2772: #else
! 2773: ISTGT_NOTICELOG("using poll\n");
! 2774: #endif /* ISTGT_USE_KQUEUE */
! 2775: #ifdef USE_ATOMIC
! 2776: ISTGT_NOTICELOG("using host atomic\n");
! 2777: #elif defined (USE_GCC_ATOMIC)
! 2778: ISTGT_NOTICELOG("using gcc atomic\n");
! 2779: #else
! 2780: ISTGT_NOTICELOG("using generic atomic\n");
! 2781: #endif /* USE_ATOMIC */
1.1 misho 2782:
2783: #ifdef ISTGT_USE_CRC32C_TABLE
2784: /* build crc32c table */
2785: istgt_init_crc32c_table();
2786: #endif /* ISTGT_USE_CRC32C_TABLE */
2787:
2788: /* initialize sub modules */
2789: rc = istgt_init(istgt);
2790: if (rc < 0) {
2791: ISTGT_ERRLOG("istgt_init() failed\n");
2792: initialize_error:
2793: istgt_close_log();
2794: istgt_free_config(config);
2795: exit(EXIT_FAILURE);
2796: }
2797: rc = istgt_lu_init(istgt);
2798: if (rc < 0) {
2799: ISTGT_ERRLOG("istgt_lu_init() failed\n");
2800: goto initialize_error;
2801: }
2802: rc = istgt_iscsi_init(istgt);
2803: if (rc < 0) {
2804: ISTGT_ERRLOG("istgt_iscsi_init() failed\n");
2805: goto initialize_error;
2806: }
2807:
2808: /* override by command line */
2809: if (pidfile != NULL) {
2810: xfree(istgt->pidfile);
2811: istgt->pidfile = xstrdup(pidfile);
2812: }
2813:
2814: /* detach from tty and run background */
2815: fflush(stdout);
2816: if (detach) {
1.1.1.2 ! misho 2817: istgt->daemon = 1;
1.1 misho 2818: rc = daemon(0, 0);
2819: if (rc < 0) {
2820: ISTGT_ERRLOG("daemon() failed\n");
2821: goto initialize_error;
2822: }
2823: }
2824:
2825: /* setup signal handler thread */
1.1.1.2 ! misho 2826: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "setup signal handler\n");
1.1 misho 2827: memset(&sigact, 0, sizeof sigact);
2828: memset(&sigoldact_pipe, 0, sizeof sigoldact_pipe);
1.1.1.2 ! misho 2829: memset(&sigoldact_int, 0, sizeof sigoldact_int);
! 2830: memset(&sigoldact_term, 0, sizeof sigoldact_term);
! 2831: memset(&sigoldact_hup, 0, sizeof sigoldact_hup);
1.1 misho 2832: memset(&sigoldact_info, 0, sizeof sigoldact_info);
2833: memset(&sigoldact_wakeup, 0, sizeof sigoldact_wakeup);
2834: memset(&sigoldact_io, 0, sizeof sigoldact_io);
2835: sigact.sa_handler = SIG_IGN;
2836: sigemptyset(&sigact.sa_mask);
2837: rc = sigaction(SIGPIPE, &sigact, &sigoldact_pipe);
2838: if (rc < 0) {
2839: ISTGT_ERRLOG("sigaction(SIGPIPE) failed\n");
2840: goto initialize_error;
2841: }
1.1.1.2 ! misho 2842: sigact.sa_handler = istgt_sigint;
! 2843: sigemptyset(&sigact.sa_mask);
! 2844: rc = sigaction(SIGINT, &sigact, &sigoldact_int);
! 2845: if (rc < 0) {
! 2846: ISTGT_ERRLOG("sigaction(SIGINT) failed\n");
! 2847: goto initialize_error;
! 2848: }
! 2849: sigact.sa_handler = istgt_sigterm;
! 2850: sigemptyset(&sigact.sa_mask);
! 2851: rc = sigaction(SIGTERM, &sigact, &sigoldact_term);
! 2852: if (rc < 0) {
! 2853: ISTGT_ERRLOG("sigaction(SIGTERM) failed\n");
! 2854: goto initialize_error;
! 2855: }
! 2856: sigact.sa_handler = istgt_sighup;
! 2857: sigemptyset(&sigact.sa_mask);
! 2858: rc = sigaction(SIGHUP, &sigact, &sigoldact_hup);
! 2859: if (rc < 0) {
! 2860: ISTGT_ERRLOG("sigaction(SIGHUP) failed\n");
! 2861: goto initialize_error;
! 2862: }
1.1 misho 2863: #ifdef SIGINFO
2864: sigact.sa_handler = istgt_siginfo;
2865: sigemptyset(&sigact.sa_mask);
2866: rc = sigaction(SIGINFO, &sigact, &sigoldact_info);
2867: if (rc < 0) {
2868: ISTGT_ERRLOG("sigaction(SIGINFO) failed\n");
2869: goto initialize_error;
2870: }
2871: #endif
2872: #ifdef ISTGT_USE_SIGRT
2873: if (ISTGT_SIGWAKEUP < SIGRTMIN
1.1.1.2 ! misho 2874: || ISTGT_SIGWAKEUP > SIGRTMAX) {
1.1 misho 2875: ISTGT_ERRLOG("SIGRT error\n");
2876: goto initialize_error;
2877: }
2878: #endif /* ISTGT_USE_SIGRT */
2879: sigact.sa_handler = istgt_sigwakeup;
2880: sigemptyset(&sigact.sa_mask);
2881: rc = sigaction(ISTGT_SIGWAKEUP, &sigact, &sigoldact_wakeup);
2882: if (rc < 0) {
2883: ISTGT_ERRLOG("sigaction(ISTGT_SIGWAKEUP) failed\n");
2884: goto initialize_error;
2885: }
2886: #ifdef SIGIO
2887: sigact.sa_handler = istgt_sigio;
2888: sigemptyset(&sigact.sa_mask);
2889: rc = sigaction(SIGIO, &sigact, &sigoldact_io);
2890: if (rc < 0) {
2891: ISTGT_ERRLOG("sigaction(SIGIO) failed\n");
2892: goto initialize_error;
2893: }
2894: #endif
2895: pthread_sigmask(SIG_SETMASK, NULL, &signew);
2896: sigaddset(&signew, SIGINT);
2897: sigaddset(&signew, SIGTERM);
2898: sigaddset(&signew, SIGQUIT);
2899: sigaddset(&signew, SIGHUP);
2900: #ifdef SIGINFO
2901: sigaddset(&signew, SIGINFO);
2902: #endif
2903: sigaddset(&signew, SIGUSR1);
2904: sigaddset(&signew, SIGUSR2);
2905: #ifdef SIGIO
2906: sigaddset(&signew, SIGIO);
2907: #endif
2908: sigaddset(&signew, ISTGT_SIGWAKEUP);
2909: pthread_sigmask(SIG_SETMASK, &signew, &sigold);
2910: #ifdef ISTGT_STACKSIZE
2911: rc = pthread_create(&sigthread, &istgt->attr, &istgt_sighandler,
1.1.1.2 ! misho 2912: (void *) istgt);
1.1 misho 2913: #else
2914: rc = pthread_create(&sigthread, NULL, &istgt_sighandler,
2915: (void *) istgt);
1.1.1.2 ! misho 2916: #endif
1.1 misho 2917: if (rc != 0) {
2918: ISTGT_ERRLOG("pthread_create() failed\n");
2919: goto initialize_error;
2920: }
2921: #if 0
2922: rc = pthread_detach(sigthread);
2923: if (rc != 0) {
2924: ISTGT_ERRLOG("pthread_detach() failed\n");
2925: goto initialize_error;
2926: }
2927: #endif
2928: #ifdef HAVE_PTHREAD_SET_NAME_NP
2929: pthread_set_name_np(sigthread, "sigthread");
2930: pthread_set_name_np(pthread_self(), "mainthread");
2931: #endif
2932:
2933: /* create LUN threads for command queuing */
2934: rc = istgt_lu_create_threads(istgt);
2935: if (rc < 0) {
2936: ISTGT_ERRLOG("lu_create_threads() failed\n");
2937: goto initialize_error;
2938: }
2939: rc = istgt_lu_set_all_state(istgt, ISTGT_STATE_RUNNING);
2940: if (rc < 0) {
2941: ISTGT_ERRLOG("lu_set_all_state() failed\n");
2942: goto initialize_error;
2943: }
2944:
2945: /* open portals */
2946: rc = istgt_open_uctl_portal(istgt);
2947: if (rc < 0) {
2948: ISTGT_ERRLOG("istgt_open_uctl_portal() failed\n");
2949: goto initialize_error;
2950: }
1.1.1.2 ! misho 2951: rc = istgt_open_all_portals(istgt);
1.1 misho 2952: if (rc < 0) {
1.1.1.2 ! misho 2953: ISTGT_ERRLOG("istgt_open_all_portals() failed\n");
1.1 misho 2954: goto initialize_error;
2955: }
2956:
2957: /* write pid */
2958: rc = istgt_write_pidfile(istgt);
2959: if (rc < 0) {
2960: ISTGT_ERRLOG("istgt_write_pid() failed\n");
2961: goto initialize_error;
2962: }
2963:
2964: /* accept loop */
2965: rc = istgt_acceptor(istgt);
2966: if (rc < 0) {
2967: ISTGT_ERRLOG("istgt_acceptor() failed\n");
1.1.1.2 ! misho 2968: istgt_close_all_portals(istgt);
1.1 misho 2969: istgt_close_uctl_portal(istgt);
2970: istgt_iscsi_shutdown(istgt);
2971: istgt_lu_shutdown(istgt);
1.1.1.2 ! misho 2972: istgt_shutdown(istgt);
1.1 misho 2973: istgt_close_log();
1.1.1.2 ! misho 2974: config = istgt->config;
1.1 misho 2975: istgt->config = NULL;
2976: istgt_free_config(config);
2977: exit(EXIT_FAILURE);
2978: }
2979:
2980: /* wait threads */
1.1.1.2 ! misho 2981: istgt_stop_conns();
1.1 misho 2982: while (retry > 0) {
2983: if (istgt_get_active_conns() == 0) {
2984: break;
2985: }
2986: sleep(1);
2987: retry--;
2988: }
2989: ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "retry=%d\n", retry);
2990:
2991: ISTGT_NOTICELOG("istgt version %s (%s) exiting\n", ISTGT_VERSION,
2992: ISTGT_EXTRA_VERSION);
2993:
1.1.1.2 ! misho 2994: /* stop signal thread */
! 2995: rc = pthread_join(sigthread, NULL);
! 2996: if (rc != 0) {
! 2997: ISTGT_ERRLOG("pthread_join() failed\n");
! 2998: exit (EXIT_FAILURE);
! 2999: }
! 3000:
1.1 misho 3001: /* cleanup */
1.1.1.2 ! misho 3002: istgt_close_all_portals(istgt);
1.1 misho 3003: istgt_close_uctl_portal(istgt);
3004: istgt_iscsi_shutdown(istgt);
3005: istgt_lu_shutdown(istgt);
1.1.1.2 ! misho 3006: istgt_shutdown(istgt);
1.1 misho 3007: istgt_close_log();
1.1.1.2 ! misho 3008: config = istgt->config;
1.1 misho 3009: istgt->config = NULL;
3010: istgt_free_config(config);
1.1.1.2 ! misho 3011: istgt->state = ISTGT_STATE_SHUTDOWN;
1.1 misho 3012:
3013: return 0;
3014: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>