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