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