1 /*- 2 * Copyright (c) 2012 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Edward Tomasz Napierala under sponsorship 6 * from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #include <sys/types.h> 33 #include <sys/time.h> 34 #include <sys/socket.h> 35 #include <sys/wait.h> 36 #include <netinet/in.h> 37 #include <assert.h> 38 #include <ctype.h> 39 #include <errno.h> 40 #include <netdb.h> 41 #include <signal.h> 42 #include <stdbool.h> 43 #include <stdio.h> 44 #include <stdint.h> 45 #include <stdlib.h> 46 #include <string.h> 47 #include <unistd.h> 48 49 #include "ctld.h" 50 51 static volatile bool sighup_received = false; 52 static volatile bool sigterm_received = false; 53 static volatile bool sigalrm_received = false; 54 55 static int nchildren = 0; 56 57 static void 58 usage(void) 59 { 60 61 fprintf(stderr, "usage: ctld [-d][-f config-file]\n"); 62 exit(1); 63 } 64 65 char * 66 checked_strdup(const char *s) 67 { 68 char *c; 69 70 c = strdup(s); 71 if (c == NULL) 72 log_err(1, "strdup"); 73 return (c); 74 } 75 76 struct conf * 77 conf_new(void) 78 { 79 struct conf *conf; 80 81 conf = calloc(1, sizeof(*conf)); 82 if (conf == NULL) 83 log_err(1, "calloc"); 84 TAILQ_INIT(&conf->conf_targets); 85 TAILQ_INIT(&conf->conf_auth_groups); 86 TAILQ_INIT(&conf->conf_portal_groups); 87 88 conf->conf_debug = 0; 89 conf->conf_timeout = 60; 90 conf->conf_maxproc = 30; 91 92 return (conf); 93 } 94 95 void 96 conf_delete(struct conf *conf) 97 { 98 struct target *targ, *tmp; 99 struct auth_group *ag, *cagtmp; 100 struct portal_group *pg, *cpgtmp; 101 102 assert(conf->conf_pidfh == NULL); 103 104 TAILQ_FOREACH_SAFE(targ, &conf->conf_targets, t_next, tmp) 105 target_delete(targ); 106 TAILQ_FOREACH_SAFE(ag, &conf->conf_auth_groups, ag_next, cagtmp) 107 auth_group_delete(ag); 108 TAILQ_FOREACH_SAFE(pg, &conf->conf_portal_groups, pg_next, cpgtmp) 109 portal_group_delete(pg); 110 free(conf->conf_pidfile_path); 111 free(conf); 112 } 113 114 static struct auth * 115 auth_new(struct auth_group *ag) 116 { 117 struct auth *auth; 118 119 auth = calloc(1, sizeof(*auth)); 120 if (auth == NULL) 121 log_err(1, "calloc"); 122 auth->a_auth_group = ag; 123 TAILQ_INSERT_TAIL(&ag->ag_auths, auth, a_next); 124 return (auth); 125 } 126 127 static void 128 auth_delete(struct auth *auth) 129 { 130 TAILQ_REMOVE(&auth->a_auth_group->ag_auths, auth, a_next); 131 132 free(auth->a_user); 133 free(auth->a_secret); 134 free(auth->a_mutual_user); 135 free(auth->a_mutual_secret); 136 free(auth); 137 } 138 139 const struct auth * 140 auth_find(struct auth_group *ag, const char *user) 141 { 142 const struct auth *auth; 143 144 TAILQ_FOREACH(auth, &ag->ag_auths, a_next) { 145 if (strcmp(auth->a_user, user) == 0) 146 return (auth); 147 } 148 149 return (NULL); 150 } 151 152 struct auth_group * 153 auth_group_new(struct conf *conf, const char *name) 154 { 155 struct auth_group *ag; 156 157 if (name != NULL) { 158 ag = auth_group_find(conf, name); 159 if (ag != NULL) { 160 log_warnx("duplicated auth-group \"%s\"", name); 161 return (NULL); 162 } 163 } 164 165 ag = calloc(1, sizeof(*ag)); 166 if (ag == NULL) 167 log_err(1, "calloc"); 168 if (name != NULL) 169 ag->ag_name = checked_strdup(name); 170 TAILQ_INIT(&ag->ag_auths); 171 ag->ag_conf = conf; 172 TAILQ_INSERT_TAIL(&conf->conf_auth_groups, ag, ag_next); 173 174 return (ag); 175 } 176 177 void 178 auth_group_delete(struct auth_group *ag) 179 { 180 struct auth *auth, *tmp; 181 182 TAILQ_REMOVE(&ag->ag_conf->conf_auth_groups, ag, ag_next); 183 184 TAILQ_FOREACH_SAFE(auth, &ag->ag_auths, a_next, tmp) 185 auth_delete(auth); 186 free(ag->ag_name); 187 free(ag); 188 } 189 190 struct auth_group * 191 auth_group_find(struct conf *conf, const char *name) 192 { 193 struct auth_group *ag; 194 195 TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) { 196 if (ag->ag_name != NULL && strcmp(ag->ag_name, name) == 0) 197 return (ag); 198 } 199 200 return (NULL); 201 } 202 203 static void 204 auth_check_secret_length(struct auth *auth) 205 { 206 size_t len; 207 208 len = strlen(auth->a_secret); 209 if (len > 16) { 210 if (auth->a_auth_group->ag_name != NULL) 211 log_warnx("secret for user \"%s\", auth-group \"%s\", " 212 "is too long; it should be at most 16 characters " 213 "long", auth->a_user, auth->a_auth_group->ag_name); 214 else 215 log_warnx("secret for user \"%s\", target \"%s\", " 216 "is too long; it should be at most 16 characters " 217 "long", auth->a_user, 218 auth->a_auth_group->ag_target->t_iqn); 219 } 220 if (len < 12) { 221 if (auth->a_auth_group->ag_name != NULL) 222 log_warnx("secret for user \"%s\", auth-group \"%s\", " 223 "is too short; it should be at least 12 characters " 224 "long", auth->a_user, 225 auth->a_auth_group->ag_name); 226 else 227 log_warnx("secret for user \"%s\", target \"%s\", " 228 "is too short; it should be at least 16 characters " 229 "long", auth->a_user, 230 auth->a_auth_group->ag_target->t_iqn); 231 } 232 233 if (auth->a_mutual_secret != NULL) { 234 len = strlen(auth->a_secret); 235 if (len > 16) { 236 if (auth->a_auth_group->ag_name != NULL) 237 log_warnx("mutual secret for user \"%s\", " 238 "auth-group \"%s\", is too long; it should " 239 "be at most 16 characters long", 240 auth->a_user, auth->a_auth_group->ag_name); 241 else 242 log_warnx("mutual secret for user \"%s\", " 243 "target \"%s\", is too long; it should " 244 "be at most 16 characters long", 245 auth->a_user, 246 auth->a_auth_group->ag_target->t_iqn); 247 } 248 if (len < 12) { 249 if (auth->a_auth_group->ag_name != NULL) 250 log_warnx("mutual secret for user \"%s\", " 251 "auth-group \"%s\", is too short; it " 252 "should be at least 12 characters long", 253 auth->a_user, auth->a_auth_group->ag_name); 254 else 255 log_warnx("mutual secret for user \"%s\", " 256 "target \"%s\", is too short; it should be " 257 "at least 16 characters long", 258 auth->a_user, 259 auth->a_auth_group->ag_target->t_iqn); 260 } 261 } 262 } 263 264 const struct auth * 265 auth_new_chap(struct auth_group *ag, const char *user, 266 const char *secret) 267 { 268 struct auth *auth; 269 270 if (ag->ag_type == AG_TYPE_UNKNOWN) 271 ag->ag_type = AG_TYPE_CHAP; 272 if (ag->ag_type != AG_TYPE_CHAP) { 273 if (ag->ag_name != NULL) 274 log_warnx("cannot mix \"chap\" authentication with " 275 "other types for auth-group \"%s\"", ag->ag_name); 276 else 277 log_warnx("cannot mix \"chap\" authentication with " 278 "other types for target \"%s\"", 279 ag->ag_target->t_iqn); 280 return (NULL); 281 } 282 283 auth = auth_new(ag); 284 auth->a_user = checked_strdup(user); 285 auth->a_secret = checked_strdup(secret); 286 287 auth_check_secret_length(auth); 288 289 return (auth); 290 } 291 292 const struct auth * 293 auth_new_chap_mutual(struct auth_group *ag, const char *user, 294 const char *secret, const char *user2, const char *secret2) 295 { 296 struct auth *auth; 297 298 if (ag->ag_type == AG_TYPE_UNKNOWN) 299 ag->ag_type = AG_TYPE_CHAP_MUTUAL; 300 if (ag->ag_type != AG_TYPE_CHAP_MUTUAL) { 301 if (ag->ag_name != NULL) 302 log_warnx("cannot mix \"chap-mutual\" authentication " 303 "with other types for auth-group \"%s\"", 304 ag->ag_name); 305 else 306 log_warnx("cannot mix \"chap-mutual\" authentication " 307 "with other types for target \"%s\"", 308 ag->ag_target->t_iqn); 309 return (NULL); 310 } 311 312 auth = auth_new(ag); 313 auth->a_user = checked_strdup(user); 314 auth->a_secret = checked_strdup(secret); 315 auth->a_mutual_user = checked_strdup(user2); 316 auth->a_mutual_secret = checked_strdup(secret2); 317 318 auth_check_secret_length(auth); 319 320 return (auth); 321 } 322 323 static struct portal * 324 portal_new(struct portal_group *pg) 325 { 326 struct portal *portal; 327 328 portal = calloc(1, sizeof(*portal)); 329 if (portal == NULL) 330 log_err(1, "calloc"); 331 TAILQ_INIT(&portal->p_targets); 332 portal->p_portal_group = pg; 333 TAILQ_INSERT_TAIL(&pg->pg_portals, portal, p_next); 334 return (portal); 335 } 336 337 static void 338 portal_delete(struct portal *portal) 339 { 340 TAILQ_REMOVE(&portal->p_portal_group->pg_portals, portal, p_next); 341 freeaddrinfo(portal->p_ai); 342 free(portal->p_listen); 343 free(portal); 344 } 345 346 struct portal_group * 347 portal_group_new(struct conf *conf, const char *name) 348 { 349 struct portal_group *pg; 350 351 pg = portal_group_find(conf, name); 352 if (pg != NULL) { 353 log_warnx("duplicated portal-group \"%s\"", name); 354 return (NULL); 355 } 356 357 pg = calloc(1, sizeof(*pg)); 358 if (pg == NULL) 359 log_err(1, "calloc"); 360 pg->pg_name = checked_strdup(name); 361 TAILQ_INIT(&pg->pg_portals); 362 pg->pg_conf = conf; 363 conf->conf_last_portal_group_tag++; 364 pg->pg_tag = conf->conf_last_portal_group_tag; 365 TAILQ_INSERT_TAIL(&conf->conf_portal_groups, pg, pg_next); 366 367 return (pg); 368 } 369 370 void 371 portal_group_delete(struct portal_group *pg) 372 { 373 struct portal *portal, *tmp; 374 375 TAILQ_REMOVE(&pg->pg_conf->conf_portal_groups, pg, pg_next); 376 377 TAILQ_FOREACH_SAFE(portal, &pg->pg_portals, p_next, tmp) 378 portal_delete(portal); 379 free(pg->pg_name); 380 free(pg); 381 } 382 383 struct portal_group * 384 portal_group_find(struct conf *conf, const char *name) 385 { 386 struct portal_group *pg; 387 388 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 389 if (strcmp(pg->pg_name, name) == 0) 390 return (pg); 391 } 392 393 return (NULL); 394 } 395 396 int 397 portal_group_add_listen(struct portal_group *pg, const char *value, bool iser) 398 { 399 struct addrinfo hints; 400 struct portal *portal; 401 char *addr, *ch, *arg; 402 const char *port; 403 int error, colons = 0; 404 405 #ifndef ICL_KERNEL_PROXY 406 if (iser) { 407 log_warnx("ctld(8) compiled without ICL_KERNEL_PROXY " 408 "does not support iSER protocol"); 409 return (-1); 410 } 411 #endif 412 413 portal = portal_new(pg); 414 portal->p_listen = checked_strdup(value); 415 portal->p_iser = iser; 416 417 arg = portal->p_listen; 418 if (arg[0] == '\0') { 419 log_warnx("empty listen address"); 420 free(portal->p_listen); 421 free(portal); 422 return (1); 423 } 424 if (arg[0] == '[') { 425 /* 426 * IPv6 address in square brackets, perhaps with port. 427 */ 428 arg++; 429 addr = strsep(&arg, "]"); 430 if (arg == NULL) { 431 log_warnx("invalid listen address %s", 432 portal->p_listen); 433 free(portal->p_listen); 434 free(portal); 435 return (1); 436 } 437 if (arg[0] == '\0') { 438 port = "3260"; 439 } else if (arg[0] == ':') { 440 port = arg + 1; 441 } else { 442 log_warnx("invalid listen address %s", 443 portal->p_listen); 444 free(portal->p_listen); 445 free(portal); 446 return (1); 447 } 448 } else { 449 /* 450 * Either IPv6 address without brackets - and without 451 * a port - or IPv4 address. Just count the colons. 452 */ 453 for (ch = arg; *ch != '\0'; ch++) { 454 if (*ch == ':') 455 colons++; 456 } 457 if (colons > 1) { 458 addr = arg; 459 port = "3260"; 460 } else { 461 addr = strsep(&arg, ":"); 462 if (arg == NULL) 463 port = "3260"; 464 else 465 port = arg; 466 } 467 } 468 469 memset(&hints, 0, sizeof(hints)); 470 hints.ai_family = PF_UNSPEC; 471 hints.ai_socktype = SOCK_STREAM; 472 hints.ai_flags = AI_PASSIVE; 473 474 error = getaddrinfo(addr, port, &hints, &portal->p_ai); 475 if (error != 0) { 476 log_warnx("getaddrinfo for %s failed: %s", 477 portal->p_listen, gai_strerror(error)); 478 free(portal->p_listen); 479 free(portal); 480 return (1); 481 } 482 483 /* 484 * XXX: getaddrinfo(3) may return multiple addresses; we should turn 485 * those into multiple portals. 486 */ 487 488 return (0); 489 } 490 491 static bool 492 valid_hex(const char ch) 493 { 494 switch (ch) { 495 case '0': 496 case '1': 497 case '2': 498 case '3': 499 case '4': 500 case '5': 501 case '6': 502 case '7': 503 case '8': 504 case '9': 505 case 'a': 506 case 'A': 507 case 'b': 508 case 'B': 509 case 'c': 510 case 'C': 511 case 'd': 512 case 'D': 513 case 'e': 514 case 'E': 515 case 'f': 516 case 'F': 517 return (true); 518 default: 519 return (false); 520 } 521 } 522 523 bool 524 valid_iscsi_name(const char *name) 525 { 526 int i; 527 528 if (strlen(name) >= MAX_NAME_LEN) { 529 log_warnx("overlong name for target \"%s\"; max length allowed " 530 "by iSCSI specification is %d characters", 531 name, MAX_NAME_LEN); 532 return (false); 533 } 534 535 /* 536 * In the cases below, we don't return an error, just in case the admin 537 * was right, and we're wrong. 538 */ 539 if (strncasecmp(name, "iqn.", strlen("iqn.")) == 0) { 540 for (i = strlen("iqn."); name[i] != '\0'; i++) { 541 /* 542 * XXX: We should verify UTF-8 normalisation, as defined 543 * by 3.2.6.2: iSCSI Name Encoding. 544 */ 545 if (isalnum(name[i])) 546 continue; 547 if (name[i] == '-' || name[i] == '.' || name[i] == ':') 548 continue; 549 log_warnx("invalid character \"%c\" in target name " 550 "\"%s\"; allowed characters are letters, digits, " 551 "'-', '.', and ':'", name[i], name); 552 break; 553 } 554 /* 555 * XXX: Check more stuff: valid date and a valid reversed domain. 556 */ 557 } else if (strncasecmp(name, "eui.", strlen("eui.")) == 0) { 558 if (strlen(name) != strlen("eui.") + 16) 559 log_warnx("invalid target name \"%s\"; the \"eui.\" " 560 "should be followed by exactly 16 hexadecimal " 561 "digits", name); 562 for (i = strlen("eui."); name[i] != '\0'; i++) { 563 if (!valid_hex(name[i])) { 564 log_warnx("invalid character \"%c\" in target " 565 "name \"%s\"; allowed characters are 1-9 " 566 "and A-F", name[i], name); 567 break; 568 } 569 } 570 } else if (strncasecmp(name, "naa.", strlen("naa.")) == 0) { 571 if (strlen(name) > strlen("naa.") + 32) 572 log_warnx("invalid target name \"%s\"; the \"naa.\" " 573 "should be followed by at most 32 hexadecimal " 574 "digits", name); 575 for (i = strlen("naa."); name[i] != '\0'; i++) { 576 if (!valid_hex(name[i])) { 577 log_warnx("invalid character \"%c\" in target " 578 "name \"%s\"; allowed characters are 1-9 " 579 "and A-F", name[i], name); 580 break; 581 } 582 } 583 } else { 584 log_warnx("invalid target name \"%s\"; should start with " 585 "either \".iqn\", \"eui.\", or \"naa.\"", 586 name); 587 } 588 return (true); 589 } 590 591 struct target * 592 target_new(struct conf *conf, const char *iqn) 593 { 594 struct target *targ; 595 int i, len; 596 597 targ = target_find(conf, iqn); 598 if (targ != NULL) { 599 log_warnx("duplicated target \"%s\"", iqn); 600 return (NULL); 601 } 602 if (valid_iscsi_name(iqn) == false) { 603 log_warnx("target name \"%s\" is invalid", iqn); 604 return (NULL); 605 } 606 targ = calloc(1, sizeof(*targ)); 607 if (targ == NULL) 608 log_err(1, "calloc"); 609 targ->t_iqn = checked_strdup(iqn); 610 611 /* 612 * RFC 3722 requires us to normalize the name to lowercase. 613 */ 614 len = strlen(iqn); 615 for (i = 0; i < len; i++) 616 targ->t_iqn[i] = tolower(targ->t_iqn[i]); 617 618 TAILQ_INIT(&targ->t_luns); 619 targ->t_conf = conf; 620 TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next); 621 622 return (targ); 623 } 624 625 void 626 target_delete(struct target *targ) 627 { 628 struct lun *lun, *tmp; 629 630 TAILQ_REMOVE(&targ->t_conf->conf_targets, targ, t_next); 631 632 TAILQ_FOREACH_SAFE(lun, &targ->t_luns, l_next, tmp) 633 lun_delete(lun); 634 free(targ->t_iqn); 635 free(targ); 636 } 637 638 struct target * 639 target_find(struct conf *conf, const char *iqn) 640 { 641 struct target *targ; 642 643 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 644 if (strcasecmp(targ->t_iqn, iqn) == 0) 645 return (targ); 646 } 647 648 return (NULL); 649 } 650 651 struct lun * 652 lun_new(struct target *targ, int lun_id) 653 { 654 struct lun *lun; 655 656 lun = lun_find(targ, lun_id); 657 if (lun != NULL) { 658 log_warnx("duplicated lun %d for target \"%s\"", 659 lun_id, targ->t_iqn); 660 return (NULL); 661 } 662 663 lun = calloc(1, sizeof(*lun)); 664 if (lun == NULL) 665 log_err(1, "calloc"); 666 lun->l_lun = lun_id; 667 TAILQ_INIT(&lun->l_options); 668 lun->l_target = targ; 669 TAILQ_INSERT_TAIL(&targ->t_luns, lun, l_next); 670 671 return (lun); 672 } 673 674 void 675 lun_delete(struct lun *lun) 676 { 677 struct lun_option *lo, *tmp; 678 679 TAILQ_REMOVE(&lun->l_target->t_luns, lun, l_next); 680 681 TAILQ_FOREACH_SAFE(lo, &lun->l_options, lo_next, tmp) 682 lun_option_delete(lo); 683 free(lun->l_backend); 684 free(lun->l_device_id); 685 free(lun->l_path); 686 free(lun->l_serial); 687 free(lun); 688 } 689 690 struct lun * 691 lun_find(struct target *targ, int lun_id) 692 { 693 struct lun *lun; 694 695 TAILQ_FOREACH(lun, &targ->t_luns, l_next) { 696 if (lun->l_lun == lun_id) 697 return (lun); 698 } 699 700 return (NULL); 701 } 702 703 void 704 lun_set_backend(struct lun *lun, const char *value) 705 { 706 free(lun->l_backend); 707 lun->l_backend = checked_strdup(value); 708 } 709 710 void 711 lun_set_blocksize(struct lun *lun, size_t value) 712 { 713 714 lun->l_blocksize = value; 715 } 716 717 void 718 lun_set_device_id(struct lun *lun, const char *value) 719 { 720 free(lun->l_device_id); 721 lun->l_device_id = checked_strdup(value); 722 } 723 724 void 725 lun_set_path(struct lun *lun, const char *value) 726 { 727 free(lun->l_path); 728 lun->l_path = checked_strdup(value); 729 } 730 731 void 732 lun_set_serial(struct lun *lun, const char *value) 733 { 734 free(lun->l_serial); 735 lun->l_serial = checked_strdup(value); 736 } 737 738 void 739 lun_set_size(struct lun *lun, size_t value) 740 { 741 742 lun->l_size = value; 743 } 744 745 void 746 lun_set_ctl_lun(struct lun *lun, uint32_t value) 747 { 748 749 lun->l_ctl_lun = value; 750 } 751 752 struct lun_option * 753 lun_option_new(struct lun *lun, const char *name, const char *value) 754 { 755 struct lun_option *lo; 756 757 lo = lun_option_find(lun, name); 758 if (lo != NULL) { 759 log_warnx("duplicated lun option %s for lun %d, target \"%s\"", 760 name, lun->l_lun, lun->l_target->t_iqn); 761 return (NULL); 762 } 763 764 lo = calloc(1, sizeof(*lo)); 765 if (lo == NULL) 766 log_err(1, "calloc"); 767 lo->lo_name = checked_strdup(name); 768 lo->lo_value = checked_strdup(value); 769 lo->lo_lun = lun; 770 TAILQ_INSERT_TAIL(&lun->l_options, lo, lo_next); 771 772 return (lo); 773 } 774 775 void 776 lun_option_delete(struct lun_option *lo) 777 { 778 779 TAILQ_REMOVE(&lo->lo_lun->l_options, lo, lo_next); 780 781 free(lo->lo_name); 782 free(lo->lo_value); 783 free(lo); 784 } 785 786 struct lun_option * 787 lun_option_find(struct lun *lun, const char *name) 788 { 789 struct lun_option *lo; 790 791 TAILQ_FOREACH(lo, &lun->l_options, lo_next) { 792 if (strcmp(lo->lo_name, name) == 0) 793 return (lo); 794 } 795 796 return (NULL); 797 } 798 799 void 800 lun_option_set(struct lun_option *lo, const char *value) 801 { 802 803 free(lo->lo_value); 804 lo->lo_value = checked_strdup(value); 805 } 806 807 static struct connection * 808 connection_new(struct portal *portal, int fd, const char *host) 809 { 810 struct connection *conn; 811 812 conn = calloc(1, sizeof(*conn)); 813 if (conn == NULL) 814 log_err(1, "calloc"); 815 conn->conn_portal = portal; 816 conn->conn_socket = fd; 817 conn->conn_initiator_addr = checked_strdup(host); 818 819 /* 820 * Default values, from RFC 3720, section 12. 821 */ 822 conn->conn_max_data_segment_length = 8192; 823 conn->conn_max_burst_length = 262144; 824 conn->conn_immediate_data = true; 825 826 return (conn); 827 } 828 829 #if 0 830 static void 831 conf_print(struct conf *conf) 832 { 833 struct auth_group *ag; 834 struct auth *auth; 835 struct portal_group *pg; 836 struct portal *portal; 837 struct target *targ; 838 struct lun *lun; 839 struct lun_option *lo; 840 841 TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) { 842 fprintf(stderr, "auth-group %s {\n", ag->ag_name); 843 TAILQ_FOREACH(auth, &ag->ag_auths, a_next) 844 fprintf(stderr, "\t chap-mutual %s %s %s %s\n", 845 auth->a_user, auth->a_secret, 846 auth->a_mutual_user, auth->a_mutual_secret); 847 fprintf(stderr, "}\n"); 848 } 849 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 850 fprintf(stderr, "portal-group %s {\n", pg->pg_name); 851 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) 852 fprintf(stderr, "\t listen %s\n", portal->p_listen); 853 fprintf(stderr, "}\n"); 854 } 855 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 856 fprintf(stderr, "target %s {\n", targ->t_iqn); 857 if (targ->t_alias != NULL) 858 fprintf(stderr, "\t alias %s\n", targ->t_alias); 859 TAILQ_FOREACH(lun, &targ->t_luns, l_next) { 860 fprintf(stderr, "\tlun %d {\n", lun->l_lun); 861 fprintf(stderr, "\t\tpath %s\n", lun->l_path); 862 TAILQ_FOREACH(lo, &lun->l_options, lo_next) 863 fprintf(stderr, "\t\toption %s %s\n", 864 lo->lo_name, lo->lo_value); 865 fprintf(stderr, "\t}\n"); 866 } 867 fprintf(stderr, "}\n"); 868 } 869 } 870 #endif 871 872 int 873 conf_verify(struct conf *conf) 874 { 875 struct auth_group *ag; 876 struct portal_group *pg; 877 struct target *targ; 878 struct lun *lun, *lun2; 879 bool found_lun0; 880 881 if (conf->conf_pidfile_path == NULL) 882 conf->conf_pidfile_path = checked_strdup(DEFAULT_PIDFILE); 883 884 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 885 if (targ->t_auth_group == NULL) { 886 log_warnx("missing authentication for target \"%s\"; " 887 "must specify either \"auth-group\", \"chap\", " 888 "or \"chap-mutual\"", targ->t_iqn); 889 return (1); 890 } 891 if (targ->t_portal_group == NULL) { 892 targ->t_portal_group = portal_group_find(conf, 893 "default"); 894 assert(targ->t_portal_group != NULL); 895 } 896 found_lun0 = false; 897 TAILQ_FOREACH(lun, &targ->t_luns, l_next) { 898 if (lun->l_lun == 0) 899 found_lun0 = true; 900 if (lun->l_backend == NULL) 901 lun_set_backend(lun, "block"); 902 if (strcmp(lun->l_backend, "block") == 0 && 903 lun->l_path == NULL) { 904 log_warnx("missing path for lun %d, " 905 "target \"%s\"", lun->l_lun, targ->t_iqn); 906 return (1); 907 } 908 if (strcmp(lun->l_backend, "ramdisk") == 0) { 909 if (lun->l_size == 0) { 910 log_warnx("missing size for " 911 "ramdisk-backed lun %d, " 912 "target \"%s\"", 913 lun->l_lun, targ->t_iqn); 914 return (1); 915 } 916 if (lun->l_path != NULL) { 917 log_warnx("path must not be specified " 918 "for ramdisk-backed lun %d, " 919 "target \"%s\"", 920 lun->l_lun, targ->t_iqn); 921 return (1); 922 } 923 } 924 if (lun->l_lun < 0 || lun->l_lun > 255) { 925 log_warnx("invalid lun number for lun %d, " 926 "target \"%s\"; must be between 0 and 255", 927 lun->l_lun, targ->t_iqn); 928 return (1); 929 } 930 #if 1 /* Should we? */ 931 TAILQ_FOREACH(lun2, &targ->t_luns, l_next) { 932 if (lun == lun2) 933 continue; 934 if (lun->l_path != NULL && 935 lun2->l_path != NULL && 936 strcmp(lun->l_path, lun2->l_path) == 0) 937 log_debugx("WARNING: duplicate path " 938 "for lun %d, target \"%s\"", 939 lun->l_lun, targ->t_iqn); 940 } 941 #endif 942 if (lun->l_blocksize == 0) { 943 lun_set_blocksize(lun, DEFAULT_BLOCKSIZE); 944 } else if (lun->l_blocksize <= 0) { 945 log_warnx("invalid blocksize for lun %d, " 946 "target \"%s\"; must be larger than 0", 947 lun->l_lun, targ->t_iqn); 948 return (1); 949 } 950 if (lun->l_size != 0 && 951 lun->l_size % lun->l_blocksize != 0) { 952 log_warnx("invalid size for lun %d, target " 953 "\"%s\"; must be multiple of blocksize", 954 lun->l_lun, targ->t_iqn); 955 return (1); 956 } 957 } 958 if (!found_lun0) { 959 log_warnx("mandatory LUN 0 not configured " 960 "for target \"%s\"", targ->t_iqn); 961 return (1); 962 } 963 } 964 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 965 assert(pg->pg_name != NULL); 966 if (pg->pg_discovery_auth_group == NULL) { 967 pg->pg_discovery_auth_group = 968 auth_group_find(conf, "no-access"); 969 assert(pg->pg_discovery_auth_group != NULL); 970 } 971 972 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 973 if (targ->t_portal_group == pg) 974 break; 975 } 976 if (targ == NULL) { 977 if (strcmp(pg->pg_name, "default") != 0) 978 log_warnx("portal-group \"%s\" not assigned " 979 "to any target", pg->pg_name); 980 pg->pg_unassigned = true; 981 } else 982 pg->pg_unassigned = false; 983 } 984 TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) { 985 if (ag->ag_name == NULL) 986 assert(ag->ag_target != NULL); 987 else 988 assert(ag->ag_target == NULL); 989 990 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 991 if (targ->t_auth_group == ag) 992 break; 993 } 994 if (targ == NULL && ag->ag_name != NULL && 995 strcmp(ag->ag_name, "no-authentication") != 0 && 996 strcmp(ag->ag_name, "no-access") != 0) { 997 log_warnx("auth-group \"%s\" not assigned " 998 "to any target", ag->ag_name); 999 } 1000 } 1001 1002 return (0); 1003 } 1004 1005 static int 1006 conf_apply(struct conf *oldconf, struct conf *newconf) 1007 { 1008 struct target *oldtarg, *newtarg, *tmptarg; 1009 struct lun *oldlun, *newlun, *tmplun; 1010 struct portal_group *oldpg, *newpg; 1011 struct portal *oldp, *newp; 1012 pid_t otherpid; 1013 int changed, cumulated_error = 0, error; 1014 #ifndef ICL_KERNEL_PROXY 1015 int one = 1; 1016 #endif 1017 1018 if (oldconf->conf_debug != newconf->conf_debug) { 1019 log_debugx("changing debug level to %d", newconf->conf_debug); 1020 log_init(newconf->conf_debug); 1021 } 1022 1023 if (oldconf->conf_pidfh != NULL) { 1024 assert(oldconf->conf_pidfile_path != NULL); 1025 if (newconf->conf_pidfile_path != NULL && 1026 strcmp(oldconf->conf_pidfile_path, 1027 newconf->conf_pidfile_path) == 0) { 1028 newconf->conf_pidfh = oldconf->conf_pidfh; 1029 oldconf->conf_pidfh = NULL; 1030 } else { 1031 log_debugx("removing pidfile %s", 1032 oldconf->conf_pidfile_path); 1033 pidfile_remove(oldconf->conf_pidfh); 1034 oldconf->conf_pidfh = NULL; 1035 } 1036 } 1037 1038 if (newconf->conf_pidfh == NULL && newconf->conf_pidfile_path != NULL) { 1039 log_debugx("opening pidfile %s", newconf->conf_pidfile_path); 1040 newconf->conf_pidfh = 1041 pidfile_open(newconf->conf_pidfile_path, 0600, &otherpid); 1042 if (newconf->conf_pidfh == NULL) { 1043 if (errno == EEXIST) 1044 log_errx(1, "daemon already running, pid: %jd.", 1045 (intmax_t)otherpid); 1046 log_err(1, "cannot open or create pidfile \"%s\"", 1047 newconf->conf_pidfile_path); 1048 } 1049 } 1050 1051 TAILQ_FOREACH_SAFE(oldtarg, &oldconf->conf_targets, t_next, tmptarg) { 1052 /* 1053 * First, remove any targets present in the old configuration 1054 * and missing in the new one. 1055 */ 1056 newtarg = target_find(newconf, oldtarg->t_iqn); 1057 if (newtarg == NULL) { 1058 TAILQ_FOREACH_SAFE(oldlun, &oldtarg->t_luns, l_next, 1059 tmplun) { 1060 log_debugx("target %s not found in the " 1061 "configuration file; removing its lun %d, " 1062 "backed by CTL lun %d", 1063 oldtarg->t_iqn, oldlun->l_lun, 1064 oldlun->l_ctl_lun); 1065 error = kernel_lun_remove(oldlun); 1066 if (error != 0) { 1067 log_warnx("failed to remove lun %d, " 1068 "target %s, CTL lun %d", 1069 oldlun->l_lun, oldtarg->t_iqn, 1070 oldlun->l_ctl_lun); 1071 cumulated_error++; 1072 } 1073 lun_delete(oldlun); 1074 } 1075 target_delete(oldtarg); 1076 continue; 1077 } 1078 1079 /* 1080 * Second, remove any LUNs present in the old target 1081 * and missing in the new one. 1082 */ 1083 TAILQ_FOREACH_SAFE(oldlun, &oldtarg->t_luns, l_next, tmplun) { 1084 newlun = lun_find(newtarg, oldlun->l_lun); 1085 if (newlun == NULL) { 1086 log_debugx("lun %d, target %s, CTL lun %d " 1087 "not found in the configuration file; " 1088 "removing", oldlun->l_lun, oldtarg->t_iqn, 1089 oldlun->l_ctl_lun); 1090 error = kernel_lun_remove(oldlun); 1091 if (error != 0) { 1092 log_warnx("failed to remove lun %d, " 1093 "target %s, CTL lun %d", 1094 oldlun->l_lun, oldtarg->t_iqn, 1095 oldlun->l_ctl_lun); 1096 cumulated_error++; 1097 } 1098 lun_delete(oldlun); 1099 continue; 1100 } 1101 1102 /* 1103 * Also remove the LUNs changed by more than size. 1104 */ 1105 changed = 0; 1106 assert(oldlun->l_backend != NULL); 1107 assert(newlun->l_backend != NULL); 1108 if (strcmp(newlun->l_backend, oldlun->l_backend) != 0) { 1109 log_debugx("backend for lun %d, target %s, " 1110 "CTL lun %d changed; removing", 1111 oldlun->l_lun, oldtarg->t_iqn, 1112 oldlun->l_ctl_lun); 1113 changed = 1; 1114 } 1115 if (oldlun->l_blocksize != newlun->l_blocksize) { 1116 log_debugx("blocksize for lun %d, target %s, " 1117 "CTL lun %d changed; removing", 1118 oldlun->l_lun, oldtarg->t_iqn, 1119 oldlun->l_ctl_lun); 1120 changed = 1; 1121 } 1122 if (newlun->l_device_id != NULL && 1123 (oldlun->l_device_id == NULL || 1124 strcmp(oldlun->l_device_id, newlun->l_device_id) != 1125 0)) { 1126 log_debugx("device-id for lun %d, target %s, " 1127 "CTL lun %d changed; removing", 1128 oldlun->l_lun, oldtarg->t_iqn, 1129 oldlun->l_ctl_lun); 1130 changed = 1; 1131 } 1132 if (newlun->l_path != NULL && 1133 (oldlun->l_path == NULL || 1134 strcmp(oldlun->l_path, newlun->l_path) != 0)) { 1135 log_debugx("path for lun %d, target %s, " 1136 "CTL lun %d, changed; removing", 1137 oldlun->l_lun, oldtarg->t_iqn, 1138 oldlun->l_ctl_lun); 1139 changed = 1; 1140 } 1141 if (newlun->l_serial != NULL && 1142 (oldlun->l_serial == NULL || 1143 strcmp(oldlun->l_serial, newlun->l_serial) != 0)) { 1144 log_debugx("serial for lun %d, target %s, " 1145 "CTL lun %d changed; removing", 1146 oldlun->l_lun, oldtarg->t_iqn, 1147 oldlun->l_ctl_lun); 1148 changed = 1; 1149 } 1150 if (changed) { 1151 error = kernel_lun_remove(oldlun); 1152 if (error != 0) { 1153 log_warnx("failed to remove lun %d, " 1154 "target %s, CTL lun %d", 1155 oldlun->l_lun, oldtarg->t_iqn, 1156 oldlun->l_ctl_lun); 1157 cumulated_error++; 1158 } 1159 lun_delete(oldlun); 1160 continue; 1161 } 1162 1163 lun_set_ctl_lun(newlun, oldlun->l_ctl_lun); 1164 } 1165 } 1166 1167 /* 1168 * Now add new targets or modify existing ones. 1169 */ 1170 TAILQ_FOREACH(newtarg, &newconf->conf_targets, t_next) { 1171 oldtarg = target_find(oldconf, newtarg->t_iqn); 1172 1173 TAILQ_FOREACH(newlun, &newtarg->t_luns, l_next) { 1174 if (oldtarg != NULL) { 1175 oldlun = lun_find(oldtarg, newlun->l_lun); 1176 if (oldlun != NULL) { 1177 if (newlun->l_size != oldlun->l_size) { 1178 log_debugx("resizing lun %d, " 1179 "target %s, CTL lun %d", 1180 newlun->l_lun, 1181 newtarg->t_iqn, 1182 newlun->l_ctl_lun); 1183 error = 1184 kernel_lun_resize(newlun); 1185 if (error != 0) { 1186 log_warnx("failed to " 1187 "resize lun %d, " 1188 "target %s, " 1189 "CTL lun %d", 1190 newlun->l_lun, 1191 newtarg->t_iqn, 1192 newlun->l_lun); 1193 cumulated_error++; 1194 } 1195 } 1196 continue; 1197 } 1198 } 1199 log_debugx("adding lun %d, target %s", 1200 newlun->l_lun, newtarg->t_iqn); 1201 error = kernel_lun_add(newlun); 1202 if (error != 0) { 1203 log_warnx("failed to add lun %d, target %s", 1204 newlun->l_lun, newtarg->t_iqn); 1205 cumulated_error++; 1206 } 1207 } 1208 } 1209 1210 /* 1211 * Go through the new portals, opening the sockets as neccessary. 1212 */ 1213 TAILQ_FOREACH(newpg, &newconf->conf_portal_groups, pg_next) { 1214 if (newpg->pg_unassigned) { 1215 log_debugx("not listening on portal-group \"%s\", " 1216 "not assigned to any target", 1217 newpg->pg_name); 1218 continue; 1219 } 1220 TAILQ_FOREACH(newp, &newpg->pg_portals, p_next) { 1221 /* 1222 * Try to find already open portal and reuse 1223 * the listening socket. We don't care about 1224 * what portal or portal group that was, what 1225 * matters is the listening address. 1226 */ 1227 TAILQ_FOREACH(oldpg, &oldconf->conf_portal_groups, 1228 pg_next) { 1229 TAILQ_FOREACH(oldp, &oldpg->pg_portals, 1230 p_next) { 1231 if (strcmp(newp->p_listen, 1232 oldp->p_listen) == 0 && 1233 oldp->p_socket > 0) { 1234 newp->p_socket = 1235 oldp->p_socket; 1236 oldp->p_socket = 0; 1237 break; 1238 } 1239 } 1240 } 1241 if (newp->p_socket > 0) { 1242 /* 1243 * We're done with this portal. 1244 */ 1245 continue; 1246 } 1247 1248 #ifdef ICL_KERNEL_PROXY 1249 log_debugx("listening on %s, portal-group \"%s\" using ICL proxy", 1250 newp->p_listen, newpg->pg_name); 1251 kernel_listen(newp->p_ai, newp->p_iser); 1252 #else 1253 assert(newp->p_iser == false); 1254 1255 log_debugx("listening on %s, portal-group \"%s\"", 1256 newp->p_listen, newpg->pg_name); 1257 newp->p_socket = socket(newp->p_ai->ai_family, 1258 newp->p_ai->ai_socktype, 1259 newp->p_ai->ai_protocol); 1260 if (newp->p_socket < 0) { 1261 log_warn("socket(2) failed for %s", 1262 newp->p_listen); 1263 cumulated_error++; 1264 continue; 1265 } 1266 error = setsockopt(newp->p_socket, SOL_SOCKET, 1267 SO_REUSEADDR, &one, sizeof(one)); 1268 if (error != 0) { 1269 log_warn("setsockopt(SO_REUSEADDR) failed " 1270 "for %s", newp->p_listen); 1271 close(newp->p_socket); 1272 newp->p_socket = 0; 1273 cumulated_error++; 1274 continue; 1275 } 1276 error = bind(newp->p_socket, newp->p_ai->ai_addr, 1277 newp->p_ai->ai_addrlen); 1278 if (error != 0) { 1279 log_warn("bind(2) failed for %s", 1280 newp->p_listen); 1281 close(newp->p_socket); 1282 newp->p_socket = 0; 1283 cumulated_error++; 1284 continue; 1285 } 1286 error = listen(newp->p_socket, -1); 1287 if (error != 0) { 1288 log_warn("listen(2) failed for %s", 1289 newp->p_listen); 1290 close(newp->p_socket); 1291 newp->p_socket = 0; 1292 cumulated_error++; 1293 continue; 1294 } 1295 #endif /* !ICL_KERNEL_PROXY */ 1296 } 1297 } 1298 1299 /* 1300 * Go through the no longer used sockets, closing them. 1301 */ 1302 TAILQ_FOREACH(oldpg, &oldconf->conf_portal_groups, pg_next) { 1303 TAILQ_FOREACH(oldp, &oldpg->pg_portals, p_next) { 1304 if (oldp->p_socket <= 0) 1305 continue; 1306 log_debugx("closing socket for %s, portal-group \"%s\"", 1307 oldp->p_listen, oldpg->pg_name); 1308 close(oldp->p_socket); 1309 oldp->p_socket = 0; 1310 } 1311 } 1312 1313 return (cumulated_error); 1314 } 1315 1316 bool 1317 timed_out(void) 1318 { 1319 1320 return (sigalrm_received); 1321 } 1322 1323 static void 1324 sigalrm_handler(int dummy __unused) 1325 { 1326 /* 1327 * It would be easiest to just log an error and exit. We can't 1328 * do this, though, because log_errx() is not signal safe, since 1329 * it calls syslog(3). Instead, set a flag checked by pdu_send() 1330 * and pdu_receive(), to call log_errx() there. Should they fail 1331 * to notice, we'll exit here one second later. 1332 */ 1333 if (sigalrm_received) { 1334 /* 1335 * Oh well. Just give up and quit. 1336 */ 1337 _exit(2); 1338 } 1339 1340 sigalrm_received = true; 1341 } 1342 1343 static void 1344 set_timeout(const struct conf *conf) 1345 { 1346 struct sigaction sa; 1347 struct itimerval itv; 1348 int error; 1349 1350 if (conf->conf_timeout <= 0) { 1351 log_debugx("session timeout disabled"); 1352 return; 1353 } 1354 1355 bzero(&sa, sizeof(sa)); 1356 sa.sa_handler = sigalrm_handler; 1357 sigfillset(&sa.sa_mask); 1358 error = sigaction(SIGALRM, &sa, NULL); 1359 if (error != 0) 1360 log_err(1, "sigaction"); 1361 1362 /* 1363 * First SIGALRM will arive after conf_timeout seconds. 1364 * If we do nothing, another one will arrive a second later. 1365 */ 1366 bzero(&itv, sizeof(itv)); 1367 itv.it_interval.tv_sec = 1; 1368 itv.it_value.tv_sec = conf->conf_timeout; 1369 1370 log_debugx("setting session timeout to %d seconds", 1371 conf->conf_timeout); 1372 error = setitimer(ITIMER_REAL, &itv, NULL); 1373 if (error != 0) 1374 log_err(1, "setitimer"); 1375 } 1376 1377 static int 1378 wait_for_children(bool block) 1379 { 1380 pid_t pid; 1381 int status; 1382 int num = 0; 1383 1384 for (;;) { 1385 /* 1386 * If "block" is true, wait for at least one process. 1387 */ 1388 if (block && num == 0) 1389 pid = wait4(-1, &status, 0, NULL); 1390 else 1391 pid = wait4(-1, &status, WNOHANG, NULL); 1392 if (pid <= 0) 1393 break; 1394 if (WIFSIGNALED(status)) { 1395 log_warnx("child process %d terminated with signal %d", 1396 pid, WTERMSIG(status)); 1397 } else if (WEXITSTATUS(status) != 0) { 1398 log_warnx("child process %d terminated with exit status %d", 1399 pid, WEXITSTATUS(status)); 1400 } else { 1401 log_debugx("child process %d terminated gracefully", pid); 1402 } 1403 num++; 1404 } 1405 1406 return (num); 1407 } 1408 1409 static void 1410 handle_connection(struct portal *portal, int fd, bool dont_fork) 1411 { 1412 struct connection *conn; 1413 #ifndef ICL_KERNEL_PROXY 1414 struct sockaddr_storage ss; 1415 socklen_t sslen = sizeof(ss); 1416 int error; 1417 #endif 1418 pid_t pid; 1419 char host[NI_MAXHOST + 1]; 1420 struct conf *conf; 1421 1422 conf = portal->p_portal_group->pg_conf; 1423 1424 if (dont_fork) { 1425 log_debugx("incoming connection; not forking due to -d flag"); 1426 } else { 1427 nchildren -= wait_for_children(false); 1428 assert(nchildren >= 0); 1429 1430 while (conf->conf_maxproc > 0 && nchildren >= conf->conf_maxproc) { 1431 log_debugx("maxproc limit of %d child processes hit; " 1432 "waiting for child process to exit", conf->conf_maxproc); 1433 nchildren -= wait_for_children(true); 1434 assert(nchildren >= 0); 1435 } 1436 log_debugx("incoming connection; forking child process #%d", 1437 nchildren); 1438 nchildren++; 1439 pid = fork(); 1440 if (pid < 0) 1441 log_err(1, "fork"); 1442 if (pid > 0) { 1443 close(fd); 1444 return; 1445 } 1446 } 1447 pidfile_close(conf->conf_pidfh); 1448 1449 #ifdef ICL_KERNEL_PROXY 1450 /* 1451 * XXX 1452 */ 1453 log_set_peer_addr("XXX"); 1454 #else 1455 error = getpeername(fd, (struct sockaddr *)&ss, &sslen); 1456 if (error != 0) 1457 log_err(1, "getpeername"); 1458 error = getnameinfo((struct sockaddr *)&ss, sslen, 1459 host, sizeof(host), NULL, 0, NI_NUMERICHOST); 1460 if (error != 0) 1461 log_errx(1, "getaddrinfo: %s", gai_strerror(error)); 1462 1463 log_debugx("accepted connection from %s; portal group \"%s\"", 1464 host, portal->p_portal_group->pg_name); 1465 log_set_peer_addr(host); 1466 setproctitle("%s", host); 1467 #endif 1468 1469 conn = connection_new(portal, fd, host); 1470 set_timeout(conf); 1471 kernel_capsicate(); 1472 login(conn); 1473 if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) { 1474 kernel_handoff(conn); 1475 log_debugx("connection handed off to the kernel"); 1476 } else { 1477 assert(conn->conn_session_type == CONN_SESSION_TYPE_DISCOVERY); 1478 discovery(conn); 1479 } 1480 log_debugx("nothing more to do; exiting"); 1481 exit(0); 1482 } 1483 1484 #ifndef ICL_KERNEL_PROXY 1485 static int 1486 fd_add(int fd, fd_set *fdset, int nfds) 1487 { 1488 1489 /* 1490 * Skip sockets which we failed to bind. 1491 */ 1492 if (fd <= 0) 1493 return (nfds); 1494 1495 FD_SET(fd, fdset); 1496 if (fd > nfds) 1497 nfds = fd; 1498 return (nfds); 1499 } 1500 #endif 1501 1502 static void 1503 main_loop(struct conf *conf, bool dont_fork) 1504 { 1505 struct portal_group *pg; 1506 struct portal *portal; 1507 #ifdef ICL_KERNEL_PROXY 1508 int connection_id; 1509 #else 1510 fd_set fdset; 1511 int error, nfds, client_fd; 1512 #endif 1513 1514 pidfile_write(conf->conf_pidfh); 1515 1516 for (;;) { 1517 if (sighup_received || sigterm_received) 1518 return; 1519 1520 #ifdef ICL_KERNEL_PROXY 1521 connection_id = kernel_accept(); 1522 if (connection_id == 0) 1523 continue; 1524 1525 /* 1526 * XXX: This is obviously temporary. 1527 */ 1528 pg = TAILQ_FIRST(&conf->conf_portal_groups); 1529 portal = TAILQ_FIRST(&pg->pg_portals); 1530 1531 handle_connection(portal, connection_id, dont_fork); 1532 #else 1533 FD_ZERO(&fdset); 1534 nfds = 0; 1535 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 1536 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) 1537 nfds = fd_add(portal->p_socket, &fdset, nfds); 1538 } 1539 error = select(nfds + 1, &fdset, NULL, NULL, NULL); 1540 if (error <= 0) { 1541 if (errno == EINTR) 1542 return; 1543 log_err(1, "select"); 1544 } 1545 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 1546 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { 1547 if (!FD_ISSET(portal->p_socket, &fdset)) 1548 continue; 1549 client_fd = accept(portal->p_socket, NULL, 0); 1550 if (client_fd < 0) 1551 log_err(1, "accept"); 1552 handle_connection(portal, client_fd, dont_fork); 1553 break; 1554 } 1555 } 1556 #endif /* !ICL_KERNEL_PROXY */ 1557 } 1558 } 1559 1560 static void 1561 sighup_handler(int dummy __unused) 1562 { 1563 1564 sighup_received = true; 1565 } 1566 1567 static void 1568 sigterm_handler(int dummy __unused) 1569 { 1570 1571 sigterm_received = true; 1572 } 1573 1574 static void 1575 register_signals(void) 1576 { 1577 struct sigaction sa; 1578 int error; 1579 1580 bzero(&sa, sizeof(sa)); 1581 sa.sa_handler = sighup_handler; 1582 sigfillset(&sa.sa_mask); 1583 error = sigaction(SIGHUP, &sa, NULL); 1584 if (error != 0) 1585 log_err(1, "sigaction"); 1586 1587 sa.sa_handler = sigterm_handler; 1588 error = sigaction(SIGTERM, &sa, NULL); 1589 if (error != 0) 1590 log_err(1, "sigaction"); 1591 1592 sa.sa_handler = sigterm_handler; 1593 error = sigaction(SIGINT, &sa, NULL); 1594 if (error != 0) 1595 log_err(1, "sigaction"); 1596 } 1597 1598 int 1599 main(int argc, char **argv) 1600 { 1601 struct conf *oldconf, *newconf, *tmpconf; 1602 const char *config_path = DEFAULT_CONFIG_PATH; 1603 int debug = 0, ch, error; 1604 bool dont_daemonize = false; 1605 1606 while ((ch = getopt(argc, argv, "df:")) != -1) { 1607 switch (ch) { 1608 case 'd': 1609 dont_daemonize = true; 1610 debug++; 1611 break; 1612 case 'f': 1613 config_path = optarg; 1614 break; 1615 case '?': 1616 default: 1617 usage(); 1618 } 1619 } 1620 argc -= optind; 1621 if (argc != 0) 1622 usage(); 1623 1624 log_init(debug); 1625 kernel_init(); 1626 1627 oldconf = conf_new_from_kernel(); 1628 newconf = conf_new_from_file(config_path); 1629 if (newconf == NULL) 1630 log_errx(1, "configuration error, exiting"); 1631 if (debug > 0) { 1632 oldconf->conf_debug = debug; 1633 newconf->conf_debug = debug; 1634 } 1635 1636 if (dont_daemonize == false) { 1637 if (daemon(0, 0) == -1) { 1638 log_warn("cannot daemonize"); 1639 pidfile_remove(newconf->conf_pidfh); 1640 exit(1); 1641 } 1642 } 1643 1644 #ifdef ICL_KERNEL_PROXY 1645 log_debugx("enabling CTL iSCSI port"); 1646 error = kernel_port_on(); 1647 if (error != 0) 1648 log_errx(1, "failed to enable CTL iSCSI port, exiting"); 1649 #endif 1650 1651 error = conf_apply(oldconf, newconf); 1652 if (error != 0) 1653 log_errx(1, "failed to apply configuration, exiting"); 1654 conf_delete(oldconf); 1655 oldconf = NULL; 1656 1657 register_signals(); 1658 1659 #ifndef ICL_KERNEL_PROXY 1660 log_debugx("enabling CTL iSCSI port"); 1661 error = kernel_port_on(); 1662 if (error != 0) 1663 log_errx(1, "failed to enable CTL iSCSI port, exiting"); 1664 #endif 1665 1666 for (;;) { 1667 main_loop(newconf, dont_daemonize); 1668 if (sighup_received) { 1669 sighup_received = false; 1670 log_debugx("received SIGHUP, reloading configuration"); 1671 tmpconf = conf_new_from_file(config_path); 1672 if (tmpconf == NULL) { 1673 log_warnx("configuration error, " 1674 "continuing with old configuration"); 1675 } else { 1676 if (debug > 0) 1677 tmpconf->conf_debug = debug; 1678 oldconf = newconf; 1679 newconf = tmpconf; 1680 error = conf_apply(oldconf, newconf); 1681 if (error != 0) 1682 log_warnx("failed to reload " 1683 "configuration"); 1684 conf_delete(oldconf); 1685 oldconf = NULL; 1686 } 1687 } else if (sigterm_received) { 1688 log_debugx("exiting on signal; " 1689 "reloading empty configuration"); 1690 1691 log_debugx("disabling CTL iSCSI port " 1692 "and terminating all connections"); 1693 error = kernel_port_off(); 1694 if (error != 0) 1695 log_warnx("failed to disable CTL iSCSI port"); 1696 1697 oldconf = newconf; 1698 newconf = conf_new(); 1699 if (debug > 0) 1700 newconf->conf_debug = debug; 1701 error = conf_apply(oldconf, newconf); 1702 if (error != 0) 1703 log_warnx("failed to apply configuration"); 1704 1705 log_warnx("exiting on signal"); 1706 exit(0); 1707 } else { 1708 nchildren -= wait_for_children(false); 1709 assert(nchildren >= 0); 1710 } 1711 } 1712 /* NOTREACHED */ 1713 } 1714