ctld.c revision 265506
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: stable/10/usr.sbin/ctld/ctld.c 265506 2014-05-07 07:28:23Z trasz $ 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 51static volatile bool sighup_received = false; 52static volatile bool sigterm_received = false; 53static volatile bool sigalrm_received = false; 54 55static int nchildren = 0; 56 57static void 58usage(void) 59{ 60 61 fprintf(stderr, "usage: ctld [-d][-f config-file]\n"); 62 exit(1); 63} 64 65char * 66checked_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 76struct conf * 77conf_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 95void 96conf_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 114static struct auth * 115auth_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 127static void 128auth_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 139const struct auth * 140auth_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 152static void 153auth_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 213const struct auth * 214auth_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 241const struct auth * 242auth_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 272const struct auth_name * 273auth_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 286static void 287auth_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 295bool 296auth_name_defined(const struct auth_group *ag) 297{ 298 if (TAILQ_EMPTY(&ag->ag_names)) 299 return (false); 300 return (true); 301} 302 303const struct auth_name * 304auth_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 316const struct auth_portal * 317auth_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 330static void 331auth_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 339bool 340auth_portal_defined(const struct auth_group *ag) 341{ 342 if (TAILQ_EMPTY(&ag->ag_portals)) 343 return (false); 344 return (true); 345} 346 347const struct auth_portal * 348auth_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 360struct auth_group * 361auth_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 387void 388auth_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 407struct auth_group * 408auth_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 420static int 421auth_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 435int 436auth_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 474static struct portal * 475portal_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 488static void 489portal_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 497struct portal_group * 498portal_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 521void 522portal_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 534struct portal_group * 535portal_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 547int 548portal_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 642static bool 643valid_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 674bool 675valid_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 742struct target * 743target_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 776void 777target_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 789struct target * 790target_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 802struct lun * 803lun_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 825void 826lun_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 841struct lun * 842lun_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 854void 855lun_set_backend(struct lun *lun, const char *value) 856{ 857 free(lun->l_backend); 858 lun->l_backend = checked_strdup(value); 859} 860 861void 862lun_set_blocksize(struct lun *lun, size_t value) 863{ 864 865 lun->l_blocksize = value; 866} 867 868void 869lun_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 875void 876lun_set_path(struct lun *lun, const char *value) 877{ 878 free(lun->l_path); 879 lun->l_path = checked_strdup(value); 880} 881 882void 883lun_set_serial(struct lun *lun, const char *value) 884{ 885 free(lun->l_serial); 886 lun->l_serial = checked_strdup(value); 887} 888 889void 890lun_set_size(struct lun *lun, size_t value) 891{ 892 893 lun->l_size = value; 894} 895 896void 897lun_set_ctl_lun(struct lun *lun, uint32_t value) 898{ 899 900 lun->l_ctl_lun = value; 901} 902 903struct lun_option * 904lun_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 926void 927lun_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 937struct lun_option * 938lun_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 950void 951lun_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 958static struct connection * 959connection_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 981static void 982conf_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 1031static int 1032conf_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 1095int 1096conf_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_lun; 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_lun = false; 1120 TAILQ_FOREACH(lun, &targ->t_luns, l_next) { 1121 error = conf_verify_lun(lun); 1122 if (error != 0) 1123 return (error); 1124 found_lun = true; 1125 } 1126 if (!found_lun) { 1127 log_warnx("no LUNs defined for target \"%s\"", 1128 targ->t_name); 1129 return (1); 1130 } 1131 } 1132 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 1133 assert(pg->pg_name != NULL); 1134 if (pg->pg_discovery_auth_group == NULL) { 1135 pg->pg_discovery_auth_group = 1136 auth_group_find(conf, "default"); 1137 assert(pg->pg_discovery_auth_group != NULL); 1138 } 1139 1140 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1141 if (targ->t_portal_group == pg) 1142 break; 1143 } 1144 if (targ == NULL) { 1145 if (strcmp(pg->pg_name, "default") != 0) 1146 log_warnx("portal-group \"%s\" not assigned " 1147 "to any target", pg->pg_name); 1148 pg->pg_unassigned = true; 1149 } else 1150 pg->pg_unassigned = false; 1151 } 1152 TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) { 1153 if (ag->ag_name == NULL) 1154 assert(ag->ag_target != NULL); 1155 else 1156 assert(ag->ag_target == NULL); 1157 1158 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1159 if (targ->t_auth_group == ag) 1160 break; 1161 } 1162 if (targ == NULL && ag->ag_name != NULL && 1163 strcmp(ag->ag_name, "default") != 0 && 1164 strcmp(ag->ag_name, "no-authentication") != 0 && 1165 strcmp(ag->ag_name, "no-access") != 0) { 1166 log_warnx("auth-group \"%s\" not assigned " 1167 "to any target", ag->ag_name); 1168 } 1169 } 1170 1171 return (0); 1172} 1173 1174static int 1175conf_apply(struct conf *oldconf, struct conf *newconf) 1176{ 1177 struct target *oldtarg, *newtarg, *tmptarg; 1178 struct lun *oldlun, *newlun, *tmplun; 1179 struct portal_group *oldpg, *newpg; 1180 struct portal *oldp, *newp; 1181 pid_t otherpid; 1182 int changed, cumulated_error = 0, error; 1183#ifndef ICL_KERNEL_PROXY 1184 int one = 1; 1185#endif 1186 1187 if (oldconf->conf_debug != newconf->conf_debug) { 1188 log_debugx("changing debug level to %d", newconf->conf_debug); 1189 log_init(newconf->conf_debug); 1190 } 1191 1192 if (oldconf->conf_pidfh != NULL) { 1193 assert(oldconf->conf_pidfile_path != NULL); 1194 if (newconf->conf_pidfile_path != NULL && 1195 strcmp(oldconf->conf_pidfile_path, 1196 newconf->conf_pidfile_path) == 0) { 1197 newconf->conf_pidfh = oldconf->conf_pidfh; 1198 oldconf->conf_pidfh = NULL; 1199 } else { 1200 log_debugx("removing pidfile %s", 1201 oldconf->conf_pidfile_path); 1202 pidfile_remove(oldconf->conf_pidfh); 1203 oldconf->conf_pidfh = NULL; 1204 } 1205 } 1206 1207 if (newconf->conf_pidfh == NULL && newconf->conf_pidfile_path != NULL) { 1208 log_debugx("opening pidfile %s", newconf->conf_pidfile_path); 1209 newconf->conf_pidfh = 1210 pidfile_open(newconf->conf_pidfile_path, 0600, &otherpid); 1211 if (newconf->conf_pidfh == NULL) { 1212 if (errno == EEXIST) 1213 log_errx(1, "daemon already running, pid: %jd.", 1214 (intmax_t)otherpid); 1215 log_err(1, "cannot open or create pidfile \"%s\"", 1216 newconf->conf_pidfile_path); 1217 } 1218 } 1219 1220 TAILQ_FOREACH_SAFE(oldtarg, &oldconf->conf_targets, t_next, tmptarg) { 1221 /* 1222 * First, remove any targets present in the old configuration 1223 * and missing in the new one. 1224 */ 1225 newtarg = target_find(newconf, oldtarg->t_name); 1226 if (newtarg == NULL) { 1227 TAILQ_FOREACH_SAFE(oldlun, &oldtarg->t_luns, l_next, 1228 tmplun) { 1229 log_debugx("target %s not found in new " 1230 "configuration; removing its lun %d, " 1231 "backed by CTL lun %d", 1232 oldtarg->t_name, oldlun->l_lun, 1233 oldlun->l_ctl_lun); 1234 error = kernel_lun_remove(oldlun); 1235 if (error != 0) { 1236 log_warnx("failed to remove lun %d, " 1237 "target %s, CTL lun %d", 1238 oldlun->l_lun, oldtarg->t_name, 1239 oldlun->l_ctl_lun); 1240 cumulated_error++; 1241 } 1242 lun_delete(oldlun); 1243 } 1244 target_delete(oldtarg); 1245 continue; 1246 } 1247 1248 /* 1249 * Second, remove any LUNs present in the old target 1250 * and missing in the new one. 1251 */ 1252 TAILQ_FOREACH_SAFE(oldlun, &oldtarg->t_luns, l_next, tmplun) { 1253 newlun = lun_find(newtarg, oldlun->l_lun); 1254 if (newlun == NULL) { 1255 log_debugx("lun %d, target %s, CTL lun %d " 1256 "not found in new configuration; " 1257 "removing", oldlun->l_lun, oldtarg->t_name, 1258 oldlun->l_ctl_lun); 1259 error = kernel_lun_remove(oldlun); 1260 if (error != 0) { 1261 log_warnx("failed to remove lun %d, " 1262 "target %s, CTL lun %d", 1263 oldlun->l_lun, oldtarg->t_name, 1264 oldlun->l_ctl_lun); 1265 cumulated_error++; 1266 } 1267 lun_delete(oldlun); 1268 continue; 1269 } 1270 1271 /* 1272 * Also remove the LUNs changed by more than size. 1273 */ 1274 changed = 0; 1275 assert(oldlun->l_backend != NULL); 1276 assert(newlun->l_backend != NULL); 1277 if (strcmp(newlun->l_backend, oldlun->l_backend) != 0) { 1278 log_debugx("backend for lun %d, target %s, " 1279 "CTL lun %d changed; removing", 1280 oldlun->l_lun, oldtarg->t_name, 1281 oldlun->l_ctl_lun); 1282 changed = 1; 1283 } 1284 if (oldlun->l_blocksize != newlun->l_blocksize) { 1285 log_debugx("blocksize for lun %d, target %s, " 1286 "CTL lun %d changed; removing", 1287 oldlun->l_lun, oldtarg->t_name, 1288 oldlun->l_ctl_lun); 1289 changed = 1; 1290 } 1291 if (newlun->l_device_id != NULL && 1292 (oldlun->l_device_id == NULL || 1293 strcmp(oldlun->l_device_id, newlun->l_device_id) != 1294 0)) { 1295 log_debugx("device-id for lun %d, target %s, " 1296 "CTL lun %d changed; removing", 1297 oldlun->l_lun, oldtarg->t_name, 1298 oldlun->l_ctl_lun); 1299 changed = 1; 1300 } 1301 if (newlun->l_path != NULL && 1302 (oldlun->l_path == NULL || 1303 strcmp(oldlun->l_path, newlun->l_path) != 0)) { 1304 log_debugx("path for lun %d, target %s, " 1305 "CTL lun %d, changed; removing", 1306 oldlun->l_lun, oldtarg->t_name, 1307 oldlun->l_ctl_lun); 1308 changed = 1; 1309 } 1310 if (newlun->l_serial != NULL && 1311 (oldlun->l_serial == NULL || 1312 strcmp(oldlun->l_serial, newlun->l_serial) != 0)) { 1313 log_debugx("serial for lun %d, target %s, " 1314 "CTL lun %d changed; removing", 1315 oldlun->l_lun, oldtarg->t_name, 1316 oldlun->l_ctl_lun); 1317 changed = 1; 1318 } 1319 if (changed) { 1320 error = kernel_lun_remove(oldlun); 1321 if (error != 0) { 1322 log_warnx("failed to remove lun %d, " 1323 "target %s, CTL lun %d", 1324 oldlun->l_lun, oldtarg->t_name, 1325 oldlun->l_ctl_lun); 1326 cumulated_error++; 1327 } 1328 lun_delete(oldlun); 1329 continue; 1330 } 1331 1332 lun_set_ctl_lun(newlun, oldlun->l_ctl_lun); 1333 } 1334 } 1335 1336 /* 1337 * Now add new targets or modify existing ones. 1338 */ 1339 TAILQ_FOREACH(newtarg, &newconf->conf_targets, t_next) { 1340 oldtarg = target_find(oldconf, newtarg->t_name); 1341 1342 TAILQ_FOREACH(newlun, &newtarg->t_luns, l_next) { 1343 if (oldtarg != NULL) { 1344 oldlun = lun_find(oldtarg, newlun->l_lun); 1345 if (oldlun != NULL) { 1346 if (newlun->l_size != oldlun->l_size) { 1347 log_debugx("resizing lun %d, " 1348 "target %s, CTL lun %d", 1349 newlun->l_lun, 1350 newtarg->t_name, 1351 newlun->l_ctl_lun); 1352 error = 1353 kernel_lun_resize(newlun); 1354 if (error != 0) { 1355 log_warnx("failed to " 1356 "resize lun %d, " 1357 "target %s, " 1358 "CTL lun %d", 1359 newlun->l_lun, 1360 newtarg->t_name, 1361 newlun->l_lun); 1362 cumulated_error++; 1363 } 1364 } 1365 continue; 1366 } 1367 } 1368 log_debugx("adding lun %d, target %s", 1369 newlun->l_lun, newtarg->t_name); 1370 error = kernel_lun_add(newlun); 1371 if (error != 0) { 1372 log_warnx("failed to add lun %d, target %s", 1373 newlun->l_lun, newtarg->t_name); 1374 cumulated_error++; 1375 } 1376 } 1377 } 1378 1379 /* 1380 * Go through the new portals, opening the sockets as neccessary. 1381 */ 1382 TAILQ_FOREACH(newpg, &newconf->conf_portal_groups, pg_next) { 1383 if (newpg->pg_unassigned) { 1384 log_debugx("not listening on portal-group \"%s\", " 1385 "not assigned to any target", 1386 newpg->pg_name); 1387 continue; 1388 } 1389 TAILQ_FOREACH(newp, &newpg->pg_portals, p_next) { 1390 /* 1391 * Try to find already open portal and reuse 1392 * the listening socket. We don't care about 1393 * what portal or portal group that was, what 1394 * matters is the listening address. 1395 */ 1396 TAILQ_FOREACH(oldpg, &oldconf->conf_portal_groups, 1397 pg_next) { 1398 TAILQ_FOREACH(oldp, &oldpg->pg_portals, 1399 p_next) { 1400 if (strcmp(newp->p_listen, 1401 oldp->p_listen) == 0 && 1402 oldp->p_socket > 0) { 1403 newp->p_socket = 1404 oldp->p_socket; 1405 oldp->p_socket = 0; 1406 break; 1407 } 1408 } 1409 } 1410 if (newp->p_socket > 0) { 1411 /* 1412 * We're done with this portal. 1413 */ 1414 continue; 1415 } 1416 1417#ifdef ICL_KERNEL_PROXY 1418 log_debugx("listening on %s, portal-group \"%s\" using ICL proxy", 1419 newp->p_listen, newpg->pg_name); 1420 kernel_listen(newp->p_ai, newp->p_iser); 1421#else 1422 assert(newp->p_iser == false); 1423 1424 log_debugx("listening on %s, portal-group \"%s\"", 1425 newp->p_listen, newpg->pg_name); 1426 newp->p_socket = socket(newp->p_ai->ai_family, 1427 newp->p_ai->ai_socktype, 1428 newp->p_ai->ai_protocol); 1429 if (newp->p_socket < 0) { 1430 log_warn("socket(2) failed for %s", 1431 newp->p_listen); 1432 cumulated_error++; 1433 continue; 1434 } 1435 error = setsockopt(newp->p_socket, SOL_SOCKET, 1436 SO_REUSEADDR, &one, sizeof(one)); 1437 if (error != 0) { 1438 log_warn("setsockopt(SO_REUSEADDR) failed " 1439 "for %s", newp->p_listen); 1440 close(newp->p_socket); 1441 newp->p_socket = 0; 1442 cumulated_error++; 1443 continue; 1444 } 1445 error = bind(newp->p_socket, newp->p_ai->ai_addr, 1446 newp->p_ai->ai_addrlen); 1447 if (error != 0) { 1448 log_warn("bind(2) failed for %s", 1449 newp->p_listen); 1450 close(newp->p_socket); 1451 newp->p_socket = 0; 1452 cumulated_error++; 1453 continue; 1454 } 1455 error = listen(newp->p_socket, -1); 1456 if (error != 0) { 1457 log_warn("listen(2) failed for %s", 1458 newp->p_listen); 1459 close(newp->p_socket); 1460 newp->p_socket = 0; 1461 cumulated_error++; 1462 continue; 1463 } 1464#endif /* !ICL_KERNEL_PROXY */ 1465 } 1466 } 1467 1468 /* 1469 * Go through the no longer used sockets, closing them. 1470 */ 1471 TAILQ_FOREACH(oldpg, &oldconf->conf_portal_groups, pg_next) { 1472 TAILQ_FOREACH(oldp, &oldpg->pg_portals, p_next) { 1473 if (oldp->p_socket <= 0) 1474 continue; 1475 log_debugx("closing socket for %s, portal-group \"%s\"", 1476 oldp->p_listen, oldpg->pg_name); 1477 close(oldp->p_socket); 1478 oldp->p_socket = 0; 1479 } 1480 } 1481 1482 return (cumulated_error); 1483} 1484 1485bool 1486timed_out(void) 1487{ 1488 1489 return (sigalrm_received); 1490} 1491 1492static void 1493sigalrm_handler(int dummy __unused) 1494{ 1495 /* 1496 * It would be easiest to just log an error and exit. We can't 1497 * do this, though, because log_errx() is not signal safe, since 1498 * it calls syslog(3). Instead, set a flag checked by pdu_send() 1499 * and pdu_receive(), to call log_errx() there. Should they fail 1500 * to notice, we'll exit here one second later. 1501 */ 1502 if (sigalrm_received) { 1503 /* 1504 * Oh well. Just give up and quit. 1505 */ 1506 _exit(2); 1507 } 1508 1509 sigalrm_received = true; 1510} 1511 1512static void 1513set_timeout(const struct conf *conf) 1514{ 1515 struct sigaction sa; 1516 struct itimerval itv; 1517 int error; 1518 1519 if (conf->conf_timeout <= 0) { 1520 log_debugx("session timeout disabled"); 1521 return; 1522 } 1523 1524 bzero(&sa, sizeof(sa)); 1525 sa.sa_handler = sigalrm_handler; 1526 sigfillset(&sa.sa_mask); 1527 error = sigaction(SIGALRM, &sa, NULL); 1528 if (error != 0) 1529 log_err(1, "sigaction"); 1530 1531 /* 1532 * First SIGALRM will arive after conf_timeout seconds. 1533 * If we do nothing, another one will arrive a second later. 1534 */ 1535 bzero(&itv, sizeof(itv)); 1536 itv.it_interval.tv_sec = 1; 1537 itv.it_value.tv_sec = conf->conf_timeout; 1538 1539 log_debugx("setting session timeout to %d seconds", 1540 conf->conf_timeout); 1541 error = setitimer(ITIMER_REAL, &itv, NULL); 1542 if (error != 0) 1543 log_err(1, "setitimer"); 1544} 1545 1546static int 1547wait_for_children(bool block) 1548{ 1549 pid_t pid; 1550 int status; 1551 int num = 0; 1552 1553 for (;;) { 1554 /* 1555 * If "block" is true, wait for at least one process. 1556 */ 1557 if (block && num == 0) 1558 pid = wait4(-1, &status, 0, NULL); 1559 else 1560 pid = wait4(-1, &status, WNOHANG, NULL); 1561 if (pid <= 0) 1562 break; 1563 if (WIFSIGNALED(status)) { 1564 log_warnx("child process %d terminated with signal %d", 1565 pid, WTERMSIG(status)); 1566 } else if (WEXITSTATUS(status) != 0) { 1567 log_warnx("child process %d terminated with exit status %d", 1568 pid, WEXITSTATUS(status)); 1569 } else { 1570 log_debugx("child process %d terminated gracefully", pid); 1571 } 1572 num++; 1573 } 1574 1575 return (num); 1576} 1577 1578static void 1579handle_connection(struct portal *portal, int fd, bool dont_fork) 1580{ 1581 struct connection *conn; 1582#ifndef ICL_KERNEL_PROXY 1583 struct sockaddr_storage ss; 1584 socklen_t sslen = sizeof(ss); 1585 int error; 1586#endif 1587 pid_t pid; 1588 char host[NI_MAXHOST + 1]; 1589 struct conf *conf; 1590 1591 conf = portal->p_portal_group->pg_conf; 1592 1593 if (dont_fork) { 1594 log_debugx("incoming connection; not forking due to -d flag"); 1595 } else { 1596 nchildren -= wait_for_children(false); 1597 assert(nchildren >= 0); 1598 1599 while (conf->conf_maxproc > 0 && nchildren >= conf->conf_maxproc) { 1600 log_debugx("maxproc limit of %d child processes hit; " 1601 "waiting for child process to exit", conf->conf_maxproc); 1602 nchildren -= wait_for_children(true); 1603 assert(nchildren >= 0); 1604 } 1605 log_debugx("incoming connection; forking child process #%d", 1606 nchildren); 1607 nchildren++; 1608 pid = fork(); 1609 if (pid < 0) 1610 log_err(1, "fork"); 1611 if (pid > 0) { 1612 close(fd); 1613 return; 1614 } 1615 } 1616 pidfile_close(conf->conf_pidfh); 1617 1618#ifdef ICL_KERNEL_PROXY 1619 /* 1620 * XXX 1621 */ 1622 log_set_peer_addr("XXX"); 1623#else 1624 error = getpeername(fd, (struct sockaddr *)&ss, &sslen); 1625 if (error != 0) 1626 log_err(1, "getpeername"); 1627 error = getnameinfo((struct sockaddr *)&ss, sslen, 1628 host, sizeof(host), NULL, 0, NI_NUMERICHOST); 1629 if (error != 0) 1630 log_errx(1, "getaddrinfo: %s", gai_strerror(error)); 1631 1632 log_debugx("accepted connection from %s; portal group \"%s\"", 1633 host, portal->p_portal_group->pg_name); 1634 log_set_peer_addr(host); 1635 setproctitle("%s", host); 1636#endif 1637 1638 conn = connection_new(portal, fd, host); 1639 set_timeout(conf); 1640 kernel_capsicate(); 1641 login(conn); 1642 if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) { 1643 kernel_handoff(conn); 1644 log_debugx("connection handed off to the kernel"); 1645 } else { 1646 assert(conn->conn_session_type == CONN_SESSION_TYPE_DISCOVERY); 1647 discovery(conn); 1648 } 1649 log_debugx("nothing more to do; exiting"); 1650 exit(0); 1651} 1652 1653#ifndef ICL_KERNEL_PROXY 1654static int 1655fd_add(int fd, fd_set *fdset, int nfds) 1656{ 1657 1658 /* 1659 * Skip sockets which we failed to bind. 1660 */ 1661 if (fd <= 0) 1662 return (nfds); 1663 1664 FD_SET(fd, fdset); 1665 if (fd > nfds) 1666 nfds = fd; 1667 return (nfds); 1668} 1669#endif 1670 1671static void 1672main_loop(struct conf *conf, bool dont_fork) 1673{ 1674 struct portal_group *pg; 1675 struct portal *portal; 1676#ifdef ICL_KERNEL_PROXY 1677 int connection_id; 1678#else 1679 fd_set fdset; 1680 int error, nfds, client_fd; 1681#endif 1682 1683 pidfile_write(conf->conf_pidfh); 1684 1685 for (;;) { 1686 if (sighup_received || sigterm_received) 1687 return; 1688 1689#ifdef ICL_KERNEL_PROXY 1690 connection_id = kernel_accept(); 1691 if (connection_id == 0) 1692 continue; 1693 1694 /* 1695 * XXX: This is obviously temporary. 1696 */ 1697 pg = TAILQ_FIRST(&conf->conf_portal_groups); 1698 portal = TAILQ_FIRST(&pg->pg_portals); 1699 1700 handle_connection(portal, connection_id, dont_fork); 1701#else 1702 FD_ZERO(&fdset); 1703 nfds = 0; 1704 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 1705 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) 1706 nfds = fd_add(portal->p_socket, &fdset, nfds); 1707 } 1708 error = select(nfds + 1, &fdset, NULL, NULL, NULL); 1709 if (error <= 0) { 1710 if (errno == EINTR) 1711 return; 1712 log_err(1, "select"); 1713 } 1714 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 1715 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { 1716 if (!FD_ISSET(portal->p_socket, &fdset)) 1717 continue; 1718 client_fd = accept(portal->p_socket, NULL, 0); 1719 if (client_fd < 0) 1720 log_err(1, "accept"); 1721 handle_connection(portal, client_fd, dont_fork); 1722 break; 1723 } 1724 } 1725#endif /* !ICL_KERNEL_PROXY */ 1726 } 1727} 1728 1729static void 1730sighup_handler(int dummy __unused) 1731{ 1732 1733 sighup_received = true; 1734} 1735 1736static void 1737sigterm_handler(int dummy __unused) 1738{ 1739 1740 sigterm_received = true; 1741} 1742 1743static void 1744sigchld_handler(int dummy __unused) 1745{ 1746 1747 /* 1748 * The only purpose of this handler is to make SIGCHLD 1749 * interrupt the ISCSIDWAIT ioctl(2), so we can call 1750 * wait_for_children(). 1751 */ 1752} 1753 1754static void 1755register_signals(void) 1756{ 1757 struct sigaction sa; 1758 int error; 1759 1760 bzero(&sa, sizeof(sa)); 1761 sa.sa_handler = sighup_handler; 1762 sigfillset(&sa.sa_mask); 1763 error = sigaction(SIGHUP, &sa, NULL); 1764 if (error != 0) 1765 log_err(1, "sigaction"); 1766 1767 sa.sa_handler = sigterm_handler; 1768 error = sigaction(SIGTERM, &sa, NULL); 1769 if (error != 0) 1770 log_err(1, "sigaction"); 1771 1772 sa.sa_handler = sigterm_handler; 1773 error = sigaction(SIGINT, &sa, NULL); 1774 if (error != 0) 1775 log_err(1, "sigaction"); 1776 1777 sa.sa_handler = sigchld_handler; 1778 error = sigaction(SIGCHLD, &sa, NULL); 1779 if (error != 0) 1780 log_err(1, "sigaction"); 1781} 1782 1783int 1784main(int argc, char **argv) 1785{ 1786 struct conf *oldconf, *newconf, *tmpconf; 1787 const char *config_path = DEFAULT_CONFIG_PATH; 1788 int debug = 0, ch, error; 1789 bool dont_daemonize = false; 1790 1791 while ((ch = getopt(argc, argv, "df:")) != -1) { 1792 switch (ch) { 1793 case 'd': 1794 dont_daemonize = true; 1795 debug++; 1796 break; 1797 case 'f': 1798 config_path = optarg; 1799 break; 1800 case '?': 1801 default: 1802 usage(); 1803 } 1804 } 1805 argc -= optind; 1806 if (argc != 0) 1807 usage(); 1808 1809 log_init(debug); 1810 kernel_init(); 1811 1812 oldconf = conf_new_from_kernel(); 1813 newconf = conf_new_from_file(config_path); 1814 if (newconf == NULL) 1815 log_errx(1, "configuration error, exiting"); 1816 if (debug > 0) { 1817 oldconf->conf_debug = debug; 1818 newconf->conf_debug = debug; 1819 } 1820 1821#ifdef ICL_KERNEL_PROXY 1822 log_debugx("enabling CTL iSCSI port"); 1823 error = kernel_port_on(); 1824 if (error != 0) 1825 log_errx(1, "failed to enable CTL iSCSI port, exiting"); 1826#endif 1827 1828 error = conf_apply(oldconf, newconf); 1829 if (error != 0) 1830 log_errx(1, "failed to apply configuration, exiting"); 1831 conf_delete(oldconf); 1832 oldconf = NULL; 1833 1834 register_signals(); 1835 1836#ifndef ICL_KERNEL_PROXY 1837 log_debugx("enabling CTL iSCSI port"); 1838 error = kernel_port_on(); 1839 if (error != 0) 1840 log_errx(1, "failed to enable CTL iSCSI port, exiting"); 1841#endif 1842 1843 if (dont_daemonize == false) { 1844 log_debugx("daemonizing"); 1845 if (daemon(0, 0) == -1) { 1846 log_warn("cannot daemonize"); 1847 pidfile_remove(newconf->conf_pidfh); 1848 exit(1); 1849 } 1850 } 1851 1852 for (;;) { 1853 main_loop(newconf, dont_daemonize); 1854 if (sighup_received) { 1855 sighup_received = false; 1856 log_debugx("received SIGHUP, reloading configuration"); 1857 tmpconf = conf_new_from_file(config_path); 1858 if (tmpconf == NULL) { 1859 log_warnx("configuration error, " 1860 "continuing with old configuration"); 1861 } else { 1862 if (debug > 0) 1863 tmpconf->conf_debug = debug; 1864 oldconf = newconf; 1865 newconf = tmpconf; 1866 error = conf_apply(oldconf, newconf); 1867 if (error != 0) 1868 log_warnx("failed to reload " 1869 "configuration"); 1870 conf_delete(oldconf); 1871 oldconf = NULL; 1872 } 1873 } else if (sigterm_received) { 1874 log_debugx("exiting on signal; " 1875 "reloading empty configuration"); 1876 1877 log_debugx("disabling CTL iSCSI port " 1878 "and terminating all connections"); 1879 error = kernel_port_off(); 1880 if (error != 0) 1881 log_warnx("failed to disable CTL iSCSI port"); 1882 1883 oldconf = newconf; 1884 newconf = conf_new(); 1885 if (debug > 0) 1886 newconf->conf_debug = debug; 1887 error = conf_apply(oldconf, newconf); 1888 if (error != 0) 1889 log_warnx("failed to apply configuration"); 1890 1891 log_warnx("exiting on signal"); 1892 exit(0); 1893 } else { 1894 nchildren -= wait_for_children(false); 1895 assert(nchildren >= 0); 1896 } 1897 } 1898 /* NOTREACHED */ 1899} 1900