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 */ 30 31#include <sys/cdefs.h>
|
32__FBSDID("$FreeBSD: stable/10/usr.sbin/ctld/ctld.c 279003 2015-02-19 14:33:46Z mav $");
|
32__FBSDID("$FreeBSD: stable/10/usr.sbin/ctld/ctld.c 279006 2015-02-19 14:52:01Z mav $"); |
33 34#include <sys/types.h> 35#include <sys/time.h> 36#include <sys/socket.h> 37#include <sys/wait.h> 38#include <netinet/in.h> 39#include <arpa/inet.h> 40#include <assert.h> 41#include <ctype.h> 42#include <errno.h> 43#include <netdb.h> 44#include <signal.h> 45#include <stdbool.h> 46#include <stdio.h> 47#include <stdint.h> 48#include <stdlib.h> 49#include <string.h> 50#include <unistd.h> 51 52#include "ctld.h" 53#include "isns.h" 54 55bool proxy_mode = false; 56 57static volatile bool sighup_received = false; 58static volatile bool sigterm_received = false; 59static volatile bool sigalrm_received = false; 60 61static int nchildren = 0; 62static uint16_t last_portal_group_tag = 0; 63 64static void 65usage(void) 66{ 67 68 fprintf(stderr, "usage: ctld [-d][-f config-file]\n"); 69 exit(1); 70} 71 72char * 73checked_strdup(const char *s) 74{ 75 char *c; 76 77 c = strdup(s); 78 if (c == NULL) 79 log_err(1, "strdup"); 80 return (c); 81} 82 83struct conf * 84conf_new(void) 85{ 86 struct conf *conf; 87 88 conf = calloc(1, sizeof(*conf)); 89 if (conf == NULL) 90 log_err(1, "calloc"); 91 TAILQ_INIT(&conf->conf_luns); 92 TAILQ_INIT(&conf->conf_targets); 93 TAILQ_INIT(&conf->conf_auth_groups);
|
94 TAILQ_INIT(&conf->conf_ports); |
95 TAILQ_INIT(&conf->conf_portal_groups); 96 TAILQ_INIT(&conf->conf_isns); 97 98 conf->conf_isns_period = 900; 99 conf->conf_isns_timeout = 5; 100 conf->conf_debug = 0; 101 conf->conf_timeout = 60; 102 conf->conf_maxproc = 30; 103 104 return (conf); 105} 106 107void 108conf_delete(struct conf *conf) 109{ 110 struct lun *lun, *ltmp; 111 struct target *targ, *tmp; 112 struct auth_group *ag, *cagtmp; 113 struct portal_group *pg, *cpgtmp; 114 struct isns *is, *istmp; 115 116 assert(conf->conf_pidfh == NULL); 117 118 TAILQ_FOREACH_SAFE(lun, &conf->conf_luns, l_next, ltmp) 119 lun_delete(lun); 120 TAILQ_FOREACH_SAFE(targ, &conf->conf_targets, t_next, tmp) 121 target_delete(targ); 122 TAILQ_FOREACH_SAFE(ag, &conf->conf_auth_groups, ag_next, cagtmp) 123 auth_group_delete(ag); 124 TAILQ_FOREACH_SAFE(pg, &conf->conf_portal_groups, pg_next, cpgtmp) 125 portal_group_delete(pg); 126 TAILQ_FOREACH_SAFE(is, &conf->conf_isns, i_next, istmp) 127 isns_delete(is);
|
128 assert(TAILQ_EMPTY(&conf->conf_ports)); |
129 free(conf->conf_pidfile_path); 130 free(conf); 131} 132 133static struct auth * 134auth_new(struct auth_group *ag) 135{ 136 struct auth *auth; 137 138 auth = calloc(1, sizeof(*auth)); 139 if (auth == NULL) 140 log_err(1, "calloc"); 141 auth->a_auth_group = ag; 142 TAILQ_INSERT_TAIL(&ag->ag_auths, auth, a_next); 143 return (auth); 144} 145 146static void 147auth_delete(struct auth *auth) 148{ 149 TAILQ_REMOVE(&auth->a_auth_group->ag_auths, auth, a_next); 150 151 free(auth->a_user); 152 free(auth->a_secret); 153 free(auth->a_mutual_user); 154 free(auth->a_mutual_secret); 155 free(auth); 156} 157 158const struct auth * 159auth_find(const struct auth_group *ag, const char *user) 160{ 161 const struct auth *auth; 162 163 TAILQ_FOREACH(auth, &ag->ag_auths, a_next) { 164 if (strcmp(auth->a_user, user) == 0) 165 return (auth); 166 } 167 168 return (NULL); 169} 170 171static void 172auth_check_secret_length(struct auth *auth) 173{ 174 size_t len; 175 176 len = strlen(auth->a_secret); 177 if (len > 16) { 178 if (auth->a_auth_group->ag_name != NULL) 179 log_warnx("secret for user \"%s\", auth-group \"%s\", " 180 "is too long; it should be at most 16 characters " 181 "long", auth->a_user, auth->a_auth_group->ag_name); 182 else 183 log_warnx("secret for user \"%s\", target \"%s\", " 184 "is too long; it should be at most 16 characters " 185 "long", auth->a_user, 186 auth->a_auth_group->ag_target->t_name); 187 } 188 if (len < 12) { 189 if (auth->a_auth_group->ag_name != NULL) 190 log_warnx("secret for user \"%s\", auth-group \"%s\", " 191 "is too short; it should be at least 12 characters " 192 "long", auth->a_user, 193 auth->a_auth_group->ag_name); 194 else 195 log_warnx("secret for user \"%s\", target \"%s\", " 196 "is too short; it should be at least 16 characters " 197 "long", auth->a_user, 198 auth->a_auth_group->ag_target->t_name); 199 } 200 201 if (auth->a_mutual_secret != NULL) { 202 len = strlen(auth->a_secret); 203 if (len > 16) { 204 if (auth->a_auth_group->ag_name != NULL) 205 log_warnx("mutual secret for user \"%s\", " 206 "auth-group \"%s\", is too long; it should " 207 "be at most 16 characters long", 208 auth->a_user, auth->a_auth_group->ag_name); 209 else 210 log_warnx("mutual secret for user \"%s\", " 211 "target \"%s\", is too long; it should " 212 "be at most 16 characters long", 213 auth->a_user, 214 auth->a_auth_group->ag_target->t_name); 215 } 216 if (len < 12) { 217 if (auth->a_auth_group->ag_name != NULL) 218 log_warnx("mutual secret for user \"%s\", " 219 "auth-group \"%s\", is too short; it " 220 "should be at least 12 characters long", 221 auth->a_user, auth->a_auth_group->ag_name); 222 else 223 log_warnx("mutual secret for user \"%s\", " 224 "target \"%s\", is too short; it should be " 225 "at least 16 characters long", 226 auth->a_user, 227 auth->a_auth_group->ag_target->t_name); 228 } 229 } 230} 231 232const struct auth * 233auth_new_chap(struct auth_group *ag, const char *user, 234 const char *secret) 235{ 236 struct auth *auth; 237 238 if (ag->ag_type == AG_TYPE_UNKNOWN) 239 ag->ag_type = AG_TYPE_CHAP; 240 if (ag->ag_type != AG_TYPE_CHAP) { 241 if (ag->ag_name != NULL) 242 log_warnx("cannot mix \"chap\" authentication with " 243 "other types for auth-group \"%s\"", ag->ag_name); 244 else 245 log_warnx("cannot mix \"chap\" authentication with " 246 "other types for target \"%s\"", 247 ag->ag_target->t_name); 248 return (NULL); 249 } 250 251 auth = auth_new(ag); 252 auth->a_user = checked_strdup(user); 253 auth->a_secret = checked_strdup(secret); 254 255 auth_check_secret_length(auth); 256 257 return (auth); 258} 259 260const struct auth * 261auth_new_chap_mutual(struct auth_group *ag, const char *user, 262 const char *secret, const char *user2, const char *secret2) 263{ 264 struct auth *auth; 265 266 if (ag->ag_type == AG_TYPE_UNKNOWN) 267 ag->ag_type = AG_TYPE_CHAP_MUTUAL; 268 if (ag->ag_type != AG_TYPE_CHAP_MUTUAL) { 269 if (ag->ag_name != NULL) 270 log_warnx("cannot mix \"chap-mutual\" authentication " 271 "with other types for auth-group \"%s\"", 272 ag->ag_name); 273 else 274 log_warnx("cannot mix \"chap-mutual\" authentication " 275 "with other types for target \"%s\"", 276 ag->ag_target->t_name); 277 return (NULL); 278 } 279 280 auth = auth_new(ag); 281 auth->a_user = checked_strdup(user); 282 auth->a_secret = checked_strdup(secret); 283 auth->a_mutual_user = checked_strdup(user2); 284 auth->a_mutual_secret = checked_strdup(secret2); 285 286 auth_check_secret_length(auth); 287 288 return (auth); 289} 290 291const struct auth_name * 292auth_name_new(struct auth_group *ag, const char *name) 293{ 294 struct auth_name *an; 295 296 an = calloc(1, sizeof(*an)); 297 if (an == NULL) 298 log_err(1, "calloc"); 299 an->an_auth_group = ag; 300 an->an_initator_name = checked_strdup(name); 301 TAILQ_INSERT_TAIL(&ag->ag_names, an, an_next); 302 return (an); 303} 304 305static void 306auth_name_delete(struct auth_name *an) 307{ 308 TAILQ_REMOVE(&an->an_auth_group->ag_names, an, an_next); 309 310 free(an->an_initator_name); 311 free(an); 312} 313 314bool 315auth_name_defined(const struct auth_group *ag) 316{ 317 if (TAILQ_EMPTY(&ag->ag_names)) 318 return (false); 319 return (true); 320} 321 322const struct auth_name * 323auth_name_find(const struct auth_group *ag, const char *name) 324{ 325 const struct auth_name *auth_name; 326 327 TAILQ_FOREACH(auth_name, &ag->ag_names, an_next) { 328 if (strcmp(auth_name->an_initator_name, name) == 0) 329 return (auth_name); 330 } 331 332 return (NULL); 333} 334 335int 336auth_name_check(const struct auth_group *ag, const char *initiator_name) 337{ 338 if (!auth_name_defined(ag)) 339 return (0); 340 341 if (auth_name_find(ag, initiator_name) == NULL) 342 return (1); 343 344 return (0); 345} 346 347const struct auth_portal * 348auth_portal_new(struct auth_group *ag, const char *portal) 349{ 350 struct auth_portal *ap; 351 char *net, *mask, *str, *tmp; 352 int len, dm, m; 353 354 ap = calloc(1, sizeof(*ap)); 355 if (ap == NULL) 356 log_err(1, "calloc"); 357 ap->ap_auth_group = ag; 358 ap->ap_initator_portal = checked_strdup(portal); 359 mask = str = checked_strdup(portal); 360 net = strsep(&mask, "/"); 361 if (net[0] == '[') 362 net++; 363 len = strlen(net); 364 if (len == 0) 365 goto error; 366 if (net[len - 1] == ']') 367 net[len - 1] = 0; 368 if (strchr(net, ':') != NULL) { 369 struct sockaddr_in6 *sin6 = 370 (struct sockaddr_in6 *)&ap->ap_sa; 371 372 sin6->sin6_len = sizeof(*sin6); 373 sin6->sin6_family = AF_INET6; 374 if (inet_pton(AF_INET6, net, &sin6->sin6_addr) <= 0) 375 goto error; 376 dm = 128; 377 } else { 378 struct sockaddr_in *sin = 379 (struct sockaddr_in *)&ap->ap_sa; 380 381 sin->sin_len = sizeof(*sin); 382 sin->sin_family = AF_INET; 383 if (inet_pton(AF_INET, net, &sin->sin_addr) <= 0) 384 goto error; 385 dm = 32; 386 } 387 if (mask != NULL) { 388 m = strtol(mask, &tmp, 0); 389 if (m < 0 || m > dm || tmp[0] != 0) 390 goto error; 391 } else 392 m = dm; 393 ap->ap_mask = m; 394 free(str); 395 TAILQ_INSERT_TAIL(&ag->ag_portals, ap, ap_next); 396 return (ap); 397 398error: 399 log_errx(1, "Incorrect initiator portal '%s'", portal); 400 return (NULL); 401} 402 403static void 404auth_portal_delete(struct auth_portal *ap) 405{ 406 TAILQ_REMOVE(&ap->ap_auth_group->ag_portals, ap, ap_next); 407 408 free(ap->ap_initator_portal); 409 free(ap); 410} 411 412bool 413auth_portal_defined(const struct auth_group *ag) 414{ 415 if (TAILQ_EMPTY(&ag->ag_portals)) 416 return (false); 417 return (true); 418} 419 420const struct auth_portal * 421auth_portal_find(const struct auth_group *ag, const struct sockaddr_storage *ss) 422{ 423 const struct auth_portal *ap; 424 const uint8_t *a, *b; 425 int i; 426 uint8_t bmask; 427 428 TAILQ_FOREACH(ap, &ag->ag_portals, ap_next) { 429 if (ap->ap_sa.ss_family != ss->ss_family) 430 continue; 431 if (ss->ss_family == AF_INET) { 432 a = (const uint8_t *) 433 &((const struct sockaddr_in *)ss)->sin_addr; 434 b = (const uint8_t *) 435 &((const struct sockaddr_in *)&ap->ap_sa)->sin_addr; 436 } else { 437 a = (const uint8_t *) 438 &((const struct sockaddr_in6 *)ss)->sin6_addr; 439 b = (const uint8_t *) 440 &((const struct sockaddr_in6 *)&ap->ap_sa)->sin6_addr; 441 } 442 for (i = 0; i < ap->ap_mask / 8; i++) { 443 if (a[i] != b[i]) 444 goto next; 445 } 446 if (ap->ap_mask % 8) { 447 bmask = 0xff << (8 - (ap->ap_mask % 8)); 448 if ((a[i] & bmask) != (b[i] & bmask)) 449 goto next; 450 } 451 return (ap); 452next: 453 ; 454 } 455 456 return (NULL); 457} 458 459int 460auth_portal_check(const struct auth_group *ag, const struct sockaddr_storage *sa) 461{ 462 463 if (!auth_portal_defined(ag)) 464 return (0); 465 466 if (auth_portal_find(ag, sa) == NULL) 467 return (1); 468 469 return (0); 470} 471 472struct auth_group * 473auth_group_new(struct conf *conf, const char *name) 474{ 475 struct auth_group *ag; 476 477 if (name != NULL) { 478 ag = auth_group_find(conf, name); 479 if (ag != NULL) { 480 log_warnx("duplicated auth-group \"%s\"", name); 481 return (NULL); 482 } 483 } 484 485 ag = calloc(1, sizeof(*ag)); 486 if (ag == NULL) 487 log_err(1, "calloc"); 488 if (name != NULL) 489 ag->ag_name = checked_strdup(name); 490 TAILQ_INIT(&ag->ag_auths); 491 TAILQ_INIT(&ag->ag_names); 492 TAILQ_INIT(&ag->ag_portals); 493 ag->ag_conf = conf; 494 TAILQ_INSERT_TAIL(&conf->conf_auth_groups, ag, ag_next); 495 496 return (ag); 497} 498 499void 500auth_group_delete(struct auth_group *ag) 501{ 502 struct auth *auth, *auth_tmp; 503 struct auth_name *auth_name, *auth_name_tmp; 504 struct auth_portal *auth_portal, *auth_portal_tmp; 505 506 TAILQ_REMOVE(&ag->ag_conf->conf_auth_groups, ag, ag_next); 507 508 TAILQ_FOREACH_SAFE(auth, &ag->ag_auths, a_next, auth_tmp) 509 auth_delete(auth); 510 TAILQ_FOREACH_SAFE(auth_name, &ag->ag_names, an_next, auth_name_tmp) 511 auth_name_delete(auth_name); 512 TAILQ_FOREACH_SAFE(auth_portal, &ag->ag_portals, ap_next, 513 auth_portal_tmp) 514 auth_portal_delete(auth_portal); 515 free(ag->ag_name); 516 free(ag); 517} 518 519struct auth_group * 520auth_group_find(const struct conf *conf, const char *name) 521{ 522 struct auth_group *ag; 523 524 TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) { 525 if (ag->ag_name != NULL && strcmp(ag->ag_name, name) == 0) 526 return (ag); 527 } 528 529 return (NULL); 530} 531 532int 533auth_group_set_type(struct auth_group *ag, const char *str) 534{ 535 int type; 536 537 if (strcmp(str, "none") == 0) { 538 type = AG_TYPE_NO_AUTHENTICATION; 539 } else if (strcmp(str, "deny") == 0) { 540 type = AG_TYPE_DENY; 541 } else if (strcmp(str, "chap") == 0) { 542 type = AG_TYPE_CHAP; 543 } else if (strcmp(str, "chap-mutual") == 0) { 544 type = AG_TYPE_CHAP_MUTUAL; 545 } else { 546 if (ag->ag_name != NULL) 547 log_warnx("invalid auth-type \"%s\" for auth-group " 548 "\"%s\"", str, ag->ag_name); 549 else 550 log_warnx("invalid auth-type \"%s\" for target " 551 "\"%s\"", str, ag->ag_target->t_name); 552 return (1); 553 } 554 555 if (ag->ag_type != AG_TYPE_UNKNOWN && ag->ag_type != type) { 556 if (ag->ag_name != NULL) { 557 log_warnx("cannot set auth-type to \"%s\" for " 558 "auth-group \"%s\"; already has a different " 559 "type", str, ag->ag_name); 560 } else { 561 log_warnx("cannot set auth-type to \"%s\" for target " 562 "\"%s\"; already has a different type", 563 str, ag->ag_target->t_name); 564 } 565 return (1); 566 } 567 568 ag->ag_type = type; 569 570 return (0); 571} 572 573static struct portal * 574portal_new(struct portal_group *pg) 575{ 576 struct portal *portal; 577 578 portal = calloc(1, sizeof(*portal)); 579 if (portal == NULL) 580 log_err(1, "calloc"); 581 TAILQ_INIT(&portal->p_targets); 582 portal->p_portal_group = pg; 583 TAILQ_INSERT_TAIL(&pg->pg_portals, portal, p_next); 584 return (portal); 585} 586 587static void 588portal_delete(struct portal *portal) 589{ 590 591 TAILQ_REMOVE(&portal->p_portal_group->pg_portals, portal, p_next); 592 if (portal->p_ai != NULL) 593 freeaddrinfo(portal->p_ai); 594 free(portal->p_listen); 595 free(portal); 596} 597 598struct portal_group * 599portal_group_new(struct conf *conf, const char *name) 600{ 601 struct portal_group *pg; 602 603 pg = portal_group_find(conf, name); 604 if (pg != NULL) { 605 log_warnx("duplicated portal-group \"%s\"", name); 606 return (NULL); 607 } 608 609 pg = calloc(1, sizeof(*pg)); 610 if (pg == NULL) 611 log_err(1, "calloc"); 612 pg->pg_name = checked_strdup(name); 613 TAILQ_INIT(&pg->pg_portals);
|
614 TAILQ_INIT(&pg->pg_ports); |
615 pg->pg_conf = conf; 616 pg->pg_tag = 0; /* Assigned later in conf_apply(). */ 617 TAILQ_INSERT_TAIL(&conf->conf_portal_groups, pg, pg_next); 618 619 return (pg); 620} 621 622void 623portal_group_delete(struct portal_group *pg) 624{ 625 struct portal *portal, *tmp;
|
626 struct port *port, *tport; |
627
|
628 TAILQ_FOREACH_SAFE(port, &pg->pg_ports, p_pgs, tport) 629 port_delete(port); |
630 TAILQ_REMOVE(&pg->pg_conf->conf_portal_groups, pg, pg_next); 631 632 TAILQ_FOREACH_SAFE(portal, &pg->pg_portals, p_next, tmp) 633 portal_delete(portal); 634 free(pg->pg_name); 635 free(pg->pg_redirection); 636 free(pg); 637} 638 639struct portal_group * 640portal_group_find(const struct conf *conf, const char *name) 641{ 642 struct portal_group *pg; 643 644 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 645 if (strcmp(pg->pg_name, name) == 0) 646 return (pg); 647 } 648 649 return (NULL); 650} 651 652static int 653parse_addr_port(char *arg, const char *def_port, struct addrinfo **ai) 654{ 655 struct addrinfo hints; 656 char *str, *addr, *ch; 657 const char *port; 658 int error, colons = 0; 659 660 str = arg = strdup(arg); 661 if (arg[0] == '[') { 662 /* 663 * IPv6 address in square brackets, perhaps with port. 664 */ 665 arg++; 666 addr = strsep(&arg, "]"); 667 if (arg == NULL) 668 return (1); 669 if (arg[0] == '\0') { 670 port = def_port; 671 } else if (arg[0] == ':') { 672 port = arg + 1; 673 } else { 674 free(str); 675 return (1); 676 } 677 } else { 678 /* 679 * Either IPv6 address without brackets - and without 680 * a port - or IPv4 address. Just count the colons. 681 */ 682 for (ch = arg; *ch != '\0'; ch++) { 683 if (*ch == ':') 684 colons++; 685 } 686 if (colons > 1) { 687 addr = arg; 688 port = def_port; 689 } else { 690 addr = strsep(&arg, ":"); 691 if (arg == NULL) 692 port = def_port; 693 else 694 port = arg; 695 } 696 } 697 698 memset(&hints, 0, sizeof(hints)); 699 hints.ai_family = PF_UNSPEC; 700 hints.ai_socktype = SOCK_STREAM; 701 hints.ai_flags = AI_PASSIVE; 702 error = getaddrinfo(addr, port, &hints, ai); 703 free(str); 704 return ((error != 0) ? 1 : 0); 705} 706 707int 708portal_group_add_listen(struct portal_group *pg, const char *value, bool iser) 709{ 710 struct portal *portal; 711 712 portal = portal_new(pg); 713 portal->p_listen = checked_strdup(value); 714 portal->p_iser = iser; 715 716 if (parse_addr_port(portal->p_listen, "3260", &portal->p_ai)) { 717 log_warnx("invalid listen address %s", portal->p_listen); 718 portal_delete(portal); 719 return (1); 720 } 721 722 /* 723 * XXX: getaddrinfo(3) may return multiple addresses; we should turn 724 * those into multiple portals. 725 */ 726 727 return (0); 728} 729 730int 731isns_new(struct conf *conf, const char *addr) 732{ 733 struct isns *isns; 734 735 isns = calloc(1, sizeof(*isns)); 736 if (isns == NULL) 737 log_err(1, "calloc"); 738 isns->i_conf = conf; 739 TAILQ_INSERT_TAIL(&conf->conf_isns, isns, i_next); 740 isns->i_addr = checked_strdup(addr); 741 742 if (parse_addr_port(isns->i_addr, "3205", &isns->i_ai)) { 743 log_warnx("invalid iSNS address %s", isns->i_addr); 744 isns_delete(isns); 745 return (1); 746 } 747 748 /* 749 * XXX: getaddrinfo(3) may return multiple addresses; we should turn 750 * those into multiple servers. 751 */ 752 753 return (0); 754} 755 756void 757isns_delete(struct isns *isns) 758{ 759 760 TAILQ_REMOVE(&isns->i_conf->conf_isns, isns, i_next); 761 free(isns->i_addr); 762 if (isns->i_ai != NULL) 763 freeaddrinfo(isns->i_ai); 764 free(isns); 765} 766 767static int 768isns_do_connect(struct isns *isns) 769{ 770 int s; 771 772 s = socket(isns->i_ai->ai_family, isns->i_ai->ai_socktype, 773 isns->i_ai->ai_protocol); 774 if (s < 0) { 775 log_warn("socket(2) failed for %s", isns->i_addr); 776 return (-1); 777 } 778 if (connect(s, isns->i_ai->ai_addr, isns->i_ai->ai_addrlen)) { 779 log_warn("connect(2) failed for %s", isns->i_addr); 780 close(s); 781 return (-1); 782 } 783 return(s); 784} 785 786static int 787isns_do_register(struct isns *isns, int s, const char *hostname) 788{ 789 struct conf *conf = isns->i_conf; 790 struct target *target; 791 struct portal *portal; 792 struct portal_group *pg;
|
793 struct port *port; |
794 struct isns_req *req; 795 int res = 0; 796 uint32_t error; 797 798 req = isns_req_create(ISNS_FUNC_DEVATTRREG, ISNS_FLAG_CLIENT); 799 isns_req_add_str(req, 32, TAILQ_FIRST(&conf->conf_targets)->t_name); 800 isns_req_add_delim(req); 801 isns_req_add_str(req, 1, hostname); 802 isns_req_add_32(req, 2, 2); /* 2 -- iSCSI */ 803 isns_req_add_32(req, 6, conf->conf_isns_period); 804 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 805 if (pg->pg_unassigned) 806 continue; 807 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { 808 isns_req_add_addr(req, 16, portal->p_ai); 809 isns_req_add_port(req, 17, portal->p_ai); 810 } 811 } 812 TAILQ_FOREACH(target, &conf->conf_targets, t_next) { 813 isns_req_add_str(req, 32, target->t_name); 814 isns_req_add_32(req, 33, 1); /* 1 -- Target*/ 815 if (target->t_alias != NULL) 816 isns_req_add_str(req, 34, target->t_alias);
|
810 pg = target->t_portal_group;
811 isns_req_add_32(req, 51, pg->pg_tag);
812 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) {
813 isns_req_add_addr(req, 49, portal->p_ai);
814 isns_req_add_port(req, 50, portal->p_ai);
|
817 TAILQ_FOREACH(port, &target->t_ports, p_ts) { 818 if ((pg = port->p_portal_group) == NULL) 819 continue; 820 isns_req_add_32(req, 51, pg->pg_tag); 821 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { 822 isns_req_add_addr(req, 49, portal->p_ai); 823 isns_req_add_port(req, 50, portal->p_ai); 824 } |
825 } 826 } 827 res = isns_req_send(s, req); 828 if (res < 0) { 829 log_warn("send(2) failed for %s", isns->i_addr); 830 goto quit; 831 } 832 res = isns_req_receive(s, req); 833 if (res < 0) { 834 log_warn("receive(2) failed for %s", isns->i_addr); 835 goto quit; 836 } 837 error = isns_req_get_status(req); 838 if (error != 0) { 839 log_warnx("iSNS register error %d for %s", error, isns->i_addr); 840 res = -1; 841 } 842quit: 843 isns_req_free(req); 844 return (res); 845} 846 847static int 848isns_do_check(struct isns *isns, int s, const char *hostname) 849{ 850 struct conf *conf = isns->i_conf; 851 struct isns_req *req; 852 int res = 0; 853 uint32_t error; 854 855 req = isns_req_create(ISNS_FUNC_DEVATTRQRY, ISNS_FLAG_CLIENT); 856 isns_req_add_str(req, 32, TAILQ_FIRST(&conf->conf_targets)->t_name); 857 isns_req_add_str(req, 1, hostname); 858 isns_req_add_delim(req); 859 isns_req_add(req, 2, 0, NULL); 860 res = isns_req_send(s, req); 861 if (res < 0) { 862 log_warn("send(2) failed for %s", isns->i_addr); 863 goto quit; 864 } 865 res = isns_req_receive(s, req); 866 if (res < 0) { 867 log_warn("receive(2) failed for %s", isns->i_addr); 868 goto quit; 869 } 870 error = isns_req_get_status(req); 871 if (error != 0) { 872 log_warnx("iSNS check error %d for %s", error, isns->i_addr); 873 res = -1; 874 } 875quit: 876 isns_req_free(req); 877 return (res); 878} 879 880static int 881isns_do_deregister(struct isns *isns, int s, const char *hostname) 882{ 883 struct conf *conf = isns->i_conf; 884 struct isns_req *req; 885 int res = 0; 886 uint32_t error; 887 888 req = isns_req_create(ISNS_FUNC_DEVDEREG, ISNS_FLAG_CLIENT); 889 isns_req_add_str(req, 32, TAILQ_FIRST(&conf->conf_targets)->t_name); 890 isns_req_add_delim(req); 891 isns_req_add_str(req, 1, hostname); 892 res = isns_req_send(s, req); 893 if (res < 0) { 894 log_warn("send(2) failed for %s", isns->i_addr); 895 goto quit; 896 } 897 res = isns_req_receive(s, req); 898 if (res < 0) { 899 log_warn("receive(2) failed for %s", isns->i_addr); 900 goto quit; 901 } 902 error = isns_req_get_status(req); 903 if (error != 0) { 904 log_warnx("iSNS deregister error %d for %s", error, isns->i_addr); 905 res = -1; 906 } 907quit: 908 isns_req_free(req); 909 return (res); 910} 911 912void 913isns_register(struct isns *isns, struct isns *oldisns) 914{ 915 struct conf *conf = isns->i_conf; 916 int s; 917 char hostname[256]; 918 919 if (TAILQ_EMPTY(&conf->conf_targets) || 920 TAILQ_EMPTY(&conf->conf_portal_groups)) 921 return; 922 set_timeout(conf->conf_isns_timeout, false); 923 s = isns_do_connect(isns); 924 if (s < 0) { 925 set_timeout(0, false); 926 return; 927 } 928 gethostname(hostname, sizeof(hostname)); 929 930 if (oldisns == NULL || TAILQ_EMPTY(&oldisns->i_conf->conf_targets)) 931 oldisns = isns; 932 isns_do_deregister(oldisns, s, hostname); 933 isns_do_register(isns, s, hostname); 934 close(s); 935 set_timeout(0, false); 936} 937 938void 939isns_check(struct isns *isns) 940{ 941 struct conf *conf = isns->i_conf; 942 int s, res; 943 char hostname[256]; 944 945 if (TAILQ_EMPTY(&conf->conf_targets) || 946 TAILQ_EMPTY(&conf->conf_portal_groups)) 947 return; 948 set_timeout(conf->conf_isns_timeout, false); 949 s = isns_do_connect(isns); 950 if (s < 0) { 951 set_timeout(0, false); 952 return; 953 } 954 gethostname(hostname, sizeof(hostname)); 955 956 res = isns_do_check(isns, s, hostname); 957 if (res < 0) { 958 isns_do_deregister(isns, s, hostname); 959 isns_do_register(isns, s, hostname); 960 } 961 close(s); 962 set_timeout(0, false); 963} 964 965void 966isns_deregister(struct isns *isns) 967{ 968 struct conf *conf = isns->i_conf; 969 int s; 970 char hostname[256]; 971 972 if (TAILQ_EMPTY(&conf->conf_targets) || 973 TAILQ_EMPTY(&conf->conf_portal_groups)) 974 return; 975 set_timeout(conf->conf_isns_timeout, false); 976 s = isns_do_connect(isns); 977 if (s < 0) 978 return; 979 gethostname(hostname, sizeof(hostname)); 980 981 isns_do_deregister(isns, s, hostname); 982 close(s); 983 set_timeout(0, false); 984} 985 986int 987portal_group_set_filter(struct portal_group *pg, const char *str) 988{ 989 int filter; 990 991 if (strcmp(str, "none") == 0) { 992 filter = PG_FILTER_NONE; 993 } else if (strcmp(str, "portal") == 0) { 994 filter = PG_FILTER_PORTAL; 995 } else if (strcmp(str, "portal-name") == 0) { 996 filter = PG_FILTER_PORTAL_NAME; 997 } else if (strcmp(str, "portal-name-auth") == 0) { 998 filter = PG_FILTER_PORTAL_NAME_AUTH; 999 } else { 1000 log_warnx("invalid discovery-filter \"%s\" for portal-group " 1001 "\"%s\"; valid values are \"none\", \"portal\", " 1002 "\"portal-name\", and \"portal-name-auth\"", 1003 str, pg->pg_name); 1004 return (1); 1005 } 1006 1007 if (pg->pg_discovery_filter != PG_FILTER_UNKNOWN && 1008 pg->pg_discovery_filter != filter) { 1009 log_warnx("cannot set discovery-filter to \"%s\" for " 1010 "portal-group \"%s\"; already has a different " 1011 "value", str, pg->pg_name); 1012 return (1); 1013 } 1014 1015 pg->pg_discovery_filter = filter; 1016 1017 return (0); 1018} 1019 1020int 1021portal_group_set_redirection(struct portal_group *pg, const char *addr) 1022{ 1023 1024 if (pg->pg_redirection != NULL) { 1025 log_warnx("cannot set redirection to \"%s\" for " 1026 "portal-group \"%s\"; already defined", 1027 addr, pg->pg_name); 1028 return (1); 1029 } 1030 1031 pg->pg_redirection = checked_strdup(addr); 1032 1033 return (0); 1034} 1035 1036static bool 1037valid_hex(const char ch) 1038{ 1039 switch (ch) { 1040 case '0': 1041 case '1': 1042 case '2': 1043 case '3': 1044 case '4': 1045 case '5': 1046 case '6': 1047 case '7': 1048 case '8': 1049 case '9': 1050 case 'a': 1051 case 'A': 1052 case 'b': 1053 case 'B': 1054 case 'c': 1055 case 'C': 1056 case 'd': 1057 case 'D': 1058 case 'e': 1059 case 'E': 1060 case 'f': 1061 case 'F': 1062 return (true); 1063 default: 1064 return (false); 1065 } 1066} 1067 1068bool 1069valid_iscsi_name(const char *name) 1070{ 1071 int i; 1072 1073 if (strlen(name) >= MAX_NAME_LEN) { 1074 log_warnx("overlong name for target \"%s\"; max length allowed " 1075 "by iSCSI specification is %d characters", 1076 name, MAX_NAME_LEN); 1077 return (false); 1078 } 1079 1080 /* 1081 * In the cases below, we don't return an error, just in case the admin 1082 * was right, and we're wrong. 1083 */ 1084 if (strncasecmp(name, "iqn.", strlen("iqn.")) == 0) { 1085 for (i = strlen("iqn."); name[i] != '\0'; i++) { 1086 /* 1087 * XXX: We should verify UTF-8 normalisation, as defined 1088 * by 3.2.6.2: iSCSI Name Encoding. 1089 */ 1090 if (isalnum(name[i])) 1091 continue; 1092 if (name[i] == '-' || name[i] == '.' || name[i] == ':') 1093 continue; 1094 log_warnx("invalid character \"%c\" in target name " 1095 "\"%s\"; allowed characters are letters, digits, " 1096 "'-', '.', and ':'", name[i], name); 1097 break; 1098 } 1099 /* 1100 * XXX: Check more stuff: valid date and a valid reversed domain. 1101 */ 1102 } else if (strncasecmp(name, "eui.", strlen("eui.")) == 0) { 1103 if (strlen(name) != strlen("eui.") + 16) 1104 log_warnx("invalid target name \"%s\"; the \"eui.\" " 1105 "should be followed by exactly 16 hexadecimal " 1106 "digits", name); 1107 for (i = strlen("eui."); name[i] != '\0'; i++) { 1108 if (!valid_hex(name[i])) { 1109 log_warnx("invalid character \"%c\" in target " 1110 "name \"%s\"; allowed characters are 1-9 " 1111 "and A-F", name[i], name); 1112 break; 1113 } 1114 } 1115 } else if (strncasecmp(name, "naa.", strlen("naa.")) == 0) { 1116 if (strlen(name) > strlen("naa.") + 32) 1117 log_warnx("invalid target name \"%s\"; the \"naa.\" " 1118 "should be followed by at most 32 hexadecimal " 1119 "digits", name); 1120 for (i = strlen("naa."); name[i] != '\0'; i++) { 1121 if (!valid_hex(name[i])) { 1122 log_warnx("invalid character \"%c\" in target " 1123 "name \"%s\"; allowed characters are 1-9 " 1124 "and A-F", name[i], name); 1125 break; 1126 } 1127 } 1128 } else { 1129 log_warnx("invalid target name \"%s\"; should start with " 1130 "either \".iqn\", \"eui.\", or \"naa.\"", 1131 name); 1132 } 1133 return (true); 1134} 1135
|
1136struct port * 1137port_new(struct conf *conf, struct target *target, struct portal_group *pg) 1138{ 1139 struct port *port; 1140 1141 port = calloc(1, sizeof(*port)); 1142 if (port == NULL) 1143 log_err(1, "calloc"); 1144 asprintf(&port->p_name, "%s-%s", pg->pg_name, target->t_name); 1145 if (port_find(conf, port->p_name) != NULL) { 1146 log_warnx("duplicate port \"%s\"", port->p_name); 1147 free(port); 1148 return (NULL); 1149 } 1150 port->p_conf = conf; 1151 TAILQ_INSERT_TAIL(&conf->conf_ports, port, p_next); 1152 TAILQ_INSERT_TAIL(&target->t_ports, port, p_ts); 1153 port->p_target = target; 1154 TAILQ_INSERT_TAIL(&pg->pg_ports, port, p_pgs); 1155 port->p_portal_group = pg; 1156 return (port); 1157} 1158 1159struct port * 1160port_find(const struct conf *conf, const char *name) 1161{ 1162 struct port *port; 1163 1164 TAILQ_FOREACH(port, &conf->conf_ports, p_next) { 1165 if (strcasecmp(port->p_name, name) == 0) 1166 return (port); 1167 } 1168 1169 return (NULL); 1170} 1171 1172struct port * 1173port_find_in_pg(const struct portal_group *pg, const char *target) 1174{ 1175 struct port *port; 1176 1177 TAILQ_FOREACH(port, &pg->pg_ports, p_pgs) { 1178 if (strcasecmp(port->p_target->t_name, target) == 0) 1179 return (port); 1180 } 1181 1182 return (NULL); 1183} 1184 1185void 1186port_delete(struct port *port) 1187{ 1188 1189 if (port->p_portal_group) 1190 TAILQ_REMOVE(&port->p_portal_group->pg_ports, port, p_pgs); 1191 if (port->p_target) 1192 TAILQ_REMOVE(&port->p_target->t_ports, port, p_ts); 1193 TAILQ_REMOVE(&port->p_conf->conf_ports, port, p_next); 1194 free(port->p_name); 1195 free(port); 1196} 1197 |
1198struct target * 1199target_new(struct conf *conf, const char *name) 1200{ 1201 struct target *targ; 1202 int i, len; 1203 1204 targ = target_find(conf, name); 1205 if (targ != NULL) { 1206 log_warnx("duplicated target \"%s\"", name); 1207 return (NULL); 1208 } 1209 if (valid_iscsi_name(name) == false) { 1210 log_warnx("target name \"%s\" is invalid", name); 1211 return (NULL); 1212 } 1213 targ = calloc(1, sizeof(*targ)); 1214 if (targ == NULL) 1215 log_err(1, "calloc"); 1216 targ->t_name = checked_strdup(name); 1217 1218 /* 1219 * RFC 3722 requires us to normalize the name to lowercase. 1220 */ 1221 len = strlen(name); 1222 for (i = 0; i < len; i++) 1223 targ->t_name[i] = tolower(targ->t_name[i]); 1224 1225 targ->t_conf = conf;
|
1226 TAILQ_INIT(&targ->t_ports); |
1227 TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next); 1228 1229 return (targ); 1230} 1231 1232void 1233target_delete(struct target *targ) 1234{
|
1235 struct port *port, *tport; |
1236
|
1237 TAILQ_FOREACH_SAFE(port, &targ->t_ports, p_ts, tport) 1238 port_delete(port); |
1239 TAILQ_REMOVE(&targ->t_conf->conf_targets, targ, t_next); 1240 1241 free(targ->t_name); 1242 free(targ->t_redirection); 1243 free(targ); 1244} 1245 1246struct target * 1247target_find(struct conf *conf, const char *name) 1248{ 1249 struct target *targ; 1250 1251 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1252 if (strcasecmp(targ->t_name, name) == 0) 1253 return (targ); 1254 } 1255 1256 return (NULL); 1257} 1258 1259int 1260target_set_redirection(struct target *target, const char *addr) 1261{ 1262 1263 if (target->t_redirection != NULL) { 1264 log_warnx("cannot set redirection to \"%s\" for " 1265 "target \"%s\"; already defined", 1266 addr, target->t_name); 1267 return (1); 1268 } 1269 1270 target->t_redirection = checked_strdup(addr); 1271 1272 return (0); 1273} 1274
|
1199void
1200target_set_ctl_port(struct target *target, uint32_t value)
1201{
1202
1203 target->t_ctl_port = value;
1204}
1205
|
1275struct lun * 1276lun_new(struct conf *conf, const char *name) 1277{ 1278 struct lun *lun; 1279 1280 lun = lun_find(conf, name); 1281 if (lun != NULL) { 1282 log_warnx("duplicated lun \"%s\"", name); 1283 return (NULL); 1284 } 1285 1286 lun = calloc(1, sizeof(*lun)); 1287 if (lun == NULL) 1288 log_err(1, "calloc"); 1289 lun->l_conf = conf; 1290 lun->l_name = checked_strdup(name); 1291 TAILQ_INIT(&lun->l_options); 1292 TAILQ_INSERT_TAIL(&conf->conf_luns, lun, l_next); 1293 1294 return (lun); 1295} 1296 1297void 1298lun_delete(struct lun *lun) 1299{ 1300 struct target *targ; 1301 struct lun_option *lo, *tmp; 1302 int i; 1303 1304 TAILQ_FOREACH(targ, &lun->l_conf->conf_targets, t_next) { 1305 for (i = 0; i < MAX_LUNS; i++) { 1306 if (targ->t_luns[i] == lun) 1307 targ->t_luns[i] = NULL; 1308 } 1309 } 1310 TAILQ_REMOVE(&lun->l_conf->conf_luns, lun, l_next); 1311 1312 TAILQ_FOREACH_SAFE(lo, &lun->l_options, lo_next, tmp) 1313 lun_option_delete(lo); 1314 free(lun->l_name); 1315 free(lun->l_backend); 1316 free(lun->l_device_id); 1317 free(lun->l_path); 1318 free(lun->l_scsiname); 1319 free(lun->l_serial); 1320 free(lun); 1321} 1322 1323struct lun * 1324lun_find(const struct conf *conf, const char *name) 1325{ 1326 struct lun *lun; 1327 1328 TAILQ_FOREACH(lun, &conf->conf_luns, l_next) { 1329 if (strcmp(lun->l_name, name) == 0) 1330 return (lun); 1331 } 1332 1333 return (NULL); 1334} 1335 1336void 1337lun_set_backend(struct lun *lun, const char *value) 1338{ 1339 free(lun->l_backend); 1340 lun->l_backend = checked_strdup(value); 1341} 1342 1343void 1344lun_set_blocksize(struct lun *lun, size_t value) 1345{ 1346 1347 lun->l_blocksize = value; 1348} 1349 1350void 1351lun_set_device_id(struct lun *lun, const char *value) 1352{ 1353 free(lun->l_device_id); 1354 lun->l_device_id = checked_strdup(value); 1355} 1356 1357void 1358lun_set_path(struct lun *lun, const char *value) 1359{ 1360 free(lun->l_path); 1361 lun->l_path = checked_strdup(value); 1362} 1363 1364void 1365lun_set_scsiname(struct lun *lun, const char *value) 1366{ 1367 free(lun->l_scsiname); 1368 lun->l_scsiname = checked_strdup(value); 1369} 1370 1371void 1372lun_set_serial(struct lun *lun, const char *value) 1373{ 1374 free(lun->l_serial); 1375 lun->l_serial = checked_strdup(value); 1376} 1377 1378void 1379lun_set_size(struct lun *lun, size_t value) 1380{ 1381 1382 lun->l_size = value; 1383} 1384 1385void 1386lun_set_ctl_lun(struct lun *lun, uint32_t value) 1387{ 1388 1389 lun->l_ctl_lun = value; 1390} 1391 1392struct lun_option * 1393lun_option_new(struct lun *lun, const char *name, const char *value) 1394{ 1395 struct lun_option *lo; 1396 1397 lo = lun_option_find(lun, name); 1398 if (lo != NULL) { 1399 log_warnx("duplicated lun option \"%s\" for lun \"%s\"", 1400 name, lun->l_name); 1401 return (NULL); 1402 } 1403 1404 lo = calloc(1, sizeof(*lo)); 1405 if (lo == NULL) 1406 log_err(1, "calloc"); 1407 lo->lo_name = checked_strdup(name); 1408 lo->lo_value = checked_strdup(value); 1409 lo->lo_lun = lun; 1410 TAILQ_INSERT_TAIL(&lun->l_options, lo, lo_next); 1411 1412 return (lo); 1413} 1414 1415void 1416lun_option_delete(struct lun_option *lo) 1417{ 1418 1419 TAILQ_REMOVE(&lo->lo_lun->l_options, lo, lo_next); 1420 1421 free(lo->lo_name); 1422 free(lo->lo_value); 1423 free(lo); 1424} 1425 1426struct lun_option * 1427lun_option_find(const struct lun *lun, const char *name) 1428{ 1429 struct lun_option *lo; 1430 1431 TAILQ_FOREACH(lo, &lun->l_options, lo_next) { 1432 if (strcmp(lo->lo_name, name) == 0) 1433 return (lo); 1434 } 1435 1436 return (NULL); 1437} 1438 1439void 1440lun_option_set(struct lun_option *lo, const char *value) 1441{ 1442 1443 free(lo->lo_value); 1444 lo->lo_value = checked_strdup(value); 1445} 1446 1447static struct connection * 1448connection_new(struct portal *portal, int fd, const char *host, 1449 const struct sockaddr *client_sa) 1450{ 1451 struct connection *conn; 1452 1453 conn = calloc(1, sizeof(*conn)); 1454 if (conn == NULL) 1455 log_err(1, "calloc"); 1456 conn->conn_portal = portal; 1457 conn->conn_socket = fd; 1458 conn->conn_initiator_addr = checked_strdup(host); 1459 memcpy(&conn->conn_initiator_sa, client_sa, client_sa->sa_len); 1460 1461 /* 1462 * Default values, from RFC 3720, section 12. 1463 */ 1464 conn->conn_max_data_segment_length = 8192; 1465 conn->conn_max_burst_length = 262144; 1466 conn->conn_immediate_data = true; 1467 1468 return (conn); 1469} 1470 1471#if 0 1472static void 1473conf_print(struct conf *conf) 1474{ 1475 struct auth_group *ag; 1476 struct auth *auth; 1477 struct auth_name *auth_name; 1478 struct auth_portal *auth_portal; 1479 struct portal_group *pg; 1480 struct portal *portal; 1481 struct target *targ; 1482 struct lun *lun; 1483 struct lun_option *lo; 1484 1485 TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) { 1486 fprintf(stderr, "auth-group %s {\n", ag->ag_name); 1487 TAILQ_FOREACH(auth, &ag->ag_auths, a_next) 1488 fprintf(stderr, "\t chap-mutual %s %s %s %s\n", 1489 auth->a_user, auth->a_secret, 1490 auth->a_mutual_user, auth->a_mutual_secret); 1491 TAILQ_FOREACH(auth_name, &ag->ag_names, an_next) 1492 fprintf(stderr, "\t initiator-name %s\n", 1493 auth_name->an_initator_name); 1494 TAILQ_FOREACH(auth_portal, &ag->ag_portals, an_next) 1495 fprintf(stderr, "\t initiator-portal %s\n", 1496 auth_portal->an_initator_portal); 1497 fprintf(stderr, "}\n"); 1498 } 1499 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 1500 fprintf(stderr, "portal-group %s {\n", pg->pg_name); 1501 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) 1502 fprintf(stderr, "\t listen %s\n", portal->p_listen); 1503 fprintf(stderr, "}\n"); 1504 } 1505 TAILQ_FOREACH(lun, &conf->conf_luns, l_next) { 1506 fprintf(stderr, "\tlun %s {\n", lun->l_name); 1507 fprintf(stderr, "\t\tpath %s\n", lun->l_path); 1508 TAILQ_FOREACH(lo, &lun->l_options, lo_next) 1509 fprintf(stderr, "\t\toption %s %s\n", 1510 lo->lo_name, lo->lo_value); 1511 fprintf(stderr, "\t}\n"); 1512 } 1513 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1514 fprintf(stderr, "target %s {\n", targ->t_name); 1515 if (targ->t_alias != NULL) 1516 fprintf(stderr, "\t alias %s\n", targ->t_alias); 1517 fprintf(stderr, "}\n"); 1518 } 1519} 1520#endif 1521 1522static int 1523conf_verify_lun(struct lun *lun) 1524{ 1525 const struct lun *lun2; 1526 1527 if (lun->l_backend == NULL) 1528 lun_set_backend(lun, "block"); 1529 if (strcmp(lun->l_backend, "block") == 0) { 1530 if (lun->l_path == NULL) { 1531 log_warnx("missing path for lun \"%s\"", 1532 lun->l_name); 1533 return (1); 1534 } 1535 } else if (strcmp(lun->l_backend, "ramdisk") == 0) { 1536 if (lun->l_size == 0) { 1537 log_warnx("missing size for ramdisk-backed lun \"%s\"", 1538 lun->l_name); 1539 return (1); 1540 } 1541 if (lun->l_path != NULL) { 1542 log_warnx("path must not be specified " 1543 "for ramdisk-backed lun \"%s\"", 1544 lun->l_name); 1545 return (1); 1546 } 1547 } 1548 if (lun->l_blocksize == 0) { 1549 lun_set_blocksize(lun, DEFAULT_BLOCKSIZE); 1550 } else if (lun->l_blocksize < 0) { 1551 log_warnx("invalid blocksize for lun \"%s\"; " 1552 "must be larger than 0", lun->l_name); 1553 return (1); 1554 } 1555 if (lun->l_size != 0 && lun->l_size % lun->l_blocksize != 0) { 1556 log_warnx("invalid size for lun \"%s\"; " 1557 "must be multiple of blocksize", lun->l_name); 1558 return (1); 1559 } 1560 TAILQ_FOREACH(lun2, &lun->l_conf->conf_luns, l_next) { 1561 if (lun == lun2) 1562 continue; 1563 if (lun->l_path != NULL && lun2->l_path != NULL && 1564 strcmp(lun->l_path, lun2->l_path) == 0) { 1565 log_debugx("WARNING: path \"%s\" duplicated " 1566 "between lun \"%s\", and " 1567 "lun \"%s\"", lun->l_path, 1568 lun->l_name, lun2->l_name); 1569 } 1570 } 1571 1572 return (0); 1573} 1574 1575int 1576conf_verify(struct conf *conf) 1577{ 1578 struct auth_group *ag; 1579 struct portal_group *pg;
|
1580 struct port *port; |
1581 struct target *targ; 1582 struct lun *lun; 1583 bool found; 1584 int error, i; 1585 1586 if (conf->conf_pidfile_path == NULL) 1587 conf->conf_pidfile_path = checked_strdup(DEFAULT_PIDFILE); 1588 1589 TAILQ_FOREACH(lun, &conf->conf_luns, l_next) { 1590 error = conf_verify_lun(lun); 1591 if (error != 0) 1592 return (error); 1593 } 1594 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1595 if (targ->t_auth_group == NULL) { 1596 targ->t_auth_group = auth_group_find(conf, 1597 "default"); 1598 assert(targ->t_auth_group != NULL); 1599 }
|
1530 if (targ->t_portal_group == NULL) {
1531 targ->t_portal_group = portal_group_find(conf,
1532 "default");
1533 assert(targ->t_portal_group != NULL);
|
1600 if (TAILQ_EMPTY(&targ->t_ports)) { 1601 pg = portal_group_find(conf, "default"); 1602 assert(pg != NULL); 1603 port_new(conf, targ, pg); |
1604 } 1605 found = false; 1606 for (i = 0; i < MAX_LUNS; i++) { 1607 if (targ->t_luns[i] != NULL) 1608 found = true; 1609 } 1610 if (!found && targ->t_redirection == NULL) { 1611 log_warnx("no LUNs defined for target \"%s\"", 1612 targ->t_name); 1613 } 1614 if (found && targ->t_redirection != NULL) { 1615 log_debugx("target \"%s\" contains luns, " 1616 " but configured for redirection", 1617 targ->t_name); 1618 } 1619 } 1620 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 1621 assert(pg->pg_name != NULL); 1622 if (pg->pg_discovery_auth_group == NULL) { 1623 pg->pg_discovery_auth_group = 1624 auth_group_find(conf, "default"); 1625 assert(pg->pg_discovery_auth_group != NULL); 1626 } 1627 1628 if (pg->pg_discovery_filter == PG_FILTER_UNKNOWN) 1629 pg->pg_discovery_filter = PG_FILTER_NONE; 1630
|
1561 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) {
1562 if (targ->t_portal_group == pg)
1563 break;
1564 }
1565 if (pg->pg_redirection != NULL) {
1566 if (targ != NULL) {
|
1631 if (!TAILQ_EMPTY(&pg->pg_ports)) { 1632 if (pg->pg_redirection != NULL) { |
1633 log_debugx("portal-group \"%s\" assigned "
|
1568 "to target \"%s\", but configured "
|
1634 "to target, but configured " |
1635 "for redirection",
|
1570 pg->pg_name, targ->t_name);
|
1636 pg->pg_name); |
1637 } 1638 pg->pg_unassigned = false;
|
1573 } else if (targ != NULL) {
1574 pg->pg_unassigned = false;
|
1639 } else { 1640 if (strcmp(pg->pg_name, "default") != 0) 1641 log_warnx("portal-group \"%s\" not assigned " 1642 "to any target", pg->pg_name); 1643 pg->pg_unassigned = true; 1644 } 1645 } 1646 TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) { 1647 if (ag->ag_name == NULL) 1648 assert(ag->ag_target != NULL); 1649 else 1650 assert(ag->ag_target == NULL); 1651 1652 found = false; 1653 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1654 if (targ->t_auth_group == ag) { 1655 found = true; 1656 break; 1657 } 1658 }
|
1659 TAILQ_FOREACH(port, &conf->conf_ports, p_next) { 1660 if (port->p_auth_group == ag) { 1661 found = true; 1662 break; 1663 } 1664 } |
1665 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 1666 if (pg->pg_discovery_auth_group == ag) { 1667 found = true; 1668 break; 1669 } 1670 } 1671 if (!found && ag->ag_name != NULL && 1672 strcmp(ag->ag_name, "default") != 0 && 1673 strcmp(ag->ag_name, "no-authentication") != 0 && 1674 strcmp(ag->ag_name, "no-access") != 0) { 1675 log_warnx("auth-group \"%s\" not assigned " 1676 "to any target", ag->ag_name); 1677 } 1678 } 1679 1680 return (0); 1681} 1682 1683static int 1684conf_apply(struct conf *oldconf, struct conf *newconf) 1685{
|
1616 struct target *oldtarg, *newtarg, *tmptarg;
|
1686 struct lun *oldlun, *newlun, *tmplun; 1687 struct portal_group *oldpg, *newpg; 1688 struct portal *oldp, *newp;
|
1689 struct port *oldport, *newport, *tmpport; |
1690 struct isns *oldns, *newns; 1691 pid_t otherpid; 1692 int changed, cumulated_error = 0, error, sockbuf; 1693 int one = 1; 1694 1695 if (oldconf->conf_debug != newconf->conf_debug) { 1696 log_debugx("changing debug level to %d", newconf->conf_debug); 1697 log_init(newconf->conf_debug); 1698 } 1699 1700 if (oldconf->conf_pidfh != NULL) { 1701 assert(oldconf->conf_pidfile_path != NULL); 1702 if (newconf->conf_pidfile_path != NULL && 1703 strcmp(oldconf->conf_pidfile_path, 1704 newconf->conf_pidfile_path) == 0) { 1705 newconf->conf_pidfh = oldconf->conf_pidfh; 1706 oldconf->conf_pidfh = NULL; 1707 } else { 1708 log_debugx("removing pidfile %s", 1709 oldconf->conf_pidfile_path); 1710 pidfile_remove(oldconf->conf_pidfh); 1711 oldconf->conf_pidfh = NULL; 1712 } 1713 } 1714 1715 if (newconf->conf_pidfh == NULL && newconf->conf_pidfile_path != NULL) { 1716 log_debugx("opening pidfile %s", newconf->conf_pidfile_path); 1717 newconf->conf_pidfh = 1718 pidfile_open(newconf->conf_pidfile_path, 0600, &otherpid); 1719 if (newconf->conf_pidfh == NULL) { 1720 if (errno == EEXIST) 1721 log_errx(1, "daemon already running, pid: %jd.", 1722 (intmax_t)otherpid); 1723 log_err(1, "cannot open or create pidfile \"%s\"", 1724 newconf->conf_pidfile_path); 1725 } 1726 } 1727 1728 /* 1729 * Go through the new portal groups, assigning tags or preserving old. 1730 */ 1731 TAILQ_FOREACH(newpg, &newconf->conf_portal_groups, pg_next) { 1732 oldpg = portal_group_find(oldconf, newpg->pg_name); 1733 if (oldpg != NULL) 1734 newpg->pg_tag = oldpg->pg_tag; 1735 else 1736 newpg->pg_tag = ++last_portal_group_tag; 1737 } 1738 1739 /* Deregister on removed iSNS servers. */ 1740 TAILQ_FOREACH(oldns, &oldconf->conf_isns, i_next) { 1741 TAILQ_FOREACH(newns, &newconf->conf_isns, i_next) { 1742 if (strcmp(oldns->i_addr, newns->i_addr) == 0) 1743 break; 1744 } 1745 if (newns == NULL) 1746 isns_deregister(oldns); 1747 } 1748 1749 /* 1750 * XXX: If target or lun removal fails, we should somehow "move" 1751 * the old lun or target into newconf, so that subsequent 1752 * conf_apply() would try to remove them again. That would 1753 * be somewhat hairy, though, and lun deletion failures don't 1754 * really happen, so leave it as it is for now. 1755 */ 1756 /*
|
1687 * First, remove any targets present in the old configuration
|
1757 * First, remove any ports present in the old configuration |
1758 * and missing in the new one. 1759 */
|
1690 TAILQ_FOREACH_SAFE(oldtarg, &oldconf->conf_targets, t_next, tmptarg) {
1691 newtarg = target_find(newconf, oldtarg->t_name);
1692 if (newtarg != NULL)
|
1760 TAILQ_FOREACH_SAFE(oldport, &oldconf->conf_ports, p_next, tmpport) { 1761 newport = port_find(newconf, oldport->p_name); 1762 if (newport != NULL) |
1763 continue;
|
1694 error = kernel_port_remove(oldtarg);
|
1764 error = kernel_port_remove(oldport); |
1765 if (error != 0) {
|
1696 log_warnx("failed to remove target %s",
1697 oldtarg->t_name);
|
1766 log_warnx("failed to remove port %s", 1767 oldport->p_name); |
1768 /* 1769 * XXX: Uncomment after fixing the root cause. 1770 * 1771 * cumulated_error++; 1772 */ 1773 } 1774 } 1775 1776 /* 1777 * Second, remove any LUNs present in the old configuration 1778 * and missing in the new one. 1779 */ 1780 TAILQ_FOREACH_SAFE(oldlun, &oldconf->conf_luns, l_next, tmplun) { 1781 newlun = lun_find(newconf, oldlun->l_name); 1782 if (newlun == NULL) { 1783 log_debugx("lun \"%s\", CTL lun %d " 1784 "not found in new configuration; " 1785 "removing", oldlun->l_name, oldlun->l_ctl_lun); 1786 error = kernel_lun_remove(oldlun); 1787 if (error != 0) { 1788 log_warnx("failed to remove lun \"%s\", " 1789 "CTL lun %d", 1790 oldlun->l_name, oldlun->l_ctl_lun); 1791 cumulated_error++; 1792 } 1793 continue; 1794 } 1795 1796 /* 1797 * Also remove the LUNs changed by more than size. 1798 */ 1799 changed = 0; 1800 assert(oldlun->l_backend != NULL); 1801 assert(newlun->l_backend != NULL); 1802 if (strcmp(newlun->l_backend, oldlun->l_backend) != 0) { 1803 log_debugx("backend for lun \"%s\", " 1804 "CTL lun %d changed; removing", 1805 oldlun->l_name, oldlun->l_ctl_lun); 1806 changed = 1; 1807 } 1808 if (oldlun->l_blocksize != newlun->l_blocksize) { 1809 log_debugx("blocksize for lun \"%s\", " 1810 "CTL lun %d changed; removing", 1811 oldlun->l_name, oldlun->l_ctl_lun); 1812 changed = 1; 1813 } 1814 if (newlun->l_device_id != NULL && 1815 (oldlun->l_device_id == NULL || 1816 strcmp(oldlun->l_device_id, newlun->l_device_id) != 1817 0)) { 1818 log_debugx("device-id for lun \"%s\", " 1819 "CTL lun %d changed; removing", 1820 oldlun->l_name, oldlun->l_ctl_lun); 1821 changed = 1; 1822 } 1823 if (newlun->l_path != NULL && 1824 (oldlun->l_path == NULL || 1825 strcmp(oldlun->l_path, newlun->l_path) != 0)) { 1826 log_debugx("path for lun \"%s\", " 1827 "CTL lun %d, changed; removing", 1828 oldlun->l_name, oldlun->l_ctl_lun); 1829 changed = 1; 1830 } 1831 if (newlun->l_serial != NULL && 1832 (oldlun->l_serial == NULL || 1833 strcmp(oldlun->l_serial, newlun->l_serial) != 0)) { 1834 log_debugx("serial for lun \"%s\", " 1835 "CTL lun %d changed; removing", 1836 oldlun->l_name, oldlun->l_ctl_lun); 1837 changed = 1; 1838 } 1839 if (changed) { 1840 error = kernel_lun_remove(oldlun); 1841 if (error != 0) { 1842 log_warnx("failed to remove lun \"%s\", " 1843 "CTL lun %d", 1844 oldlun->l_name, oldlun->l_ctl_lun); 1845 cumulated_error++; 1846 } 1847 lun_delete(oldlun); 1848 continue; 1849 } 1850 1851 lun_set_ctl_lun(newlun, oldlun->l_ctl_lun); 1852 } 1853 1854 TAILQ_FOREACH_SAFE(newlun, &newconf->conf_luns, l_next, tmplun) { 1855 oldlun = lun_find(oldconf, newlun->l_name); 1856 if (oldlun != NULL) { 1857 if (newlun->l_size != oldlun->l_size || 1858 newlun->l_size == 0) { 1859 log_debugx("resizing lun \"%s\", CTL lun %d", 1860 newlun->l_name, newlun->l_ctl_lun); 1861 error = kernel_lun_resize(newlun); 1862 if (error != 0) { 1863 log_warnx("failed to " 1864 "resize lun \"%s\", CTL lun %d", 1865 newlun->l_name, 1866 newlun->l_ctl_lun); 1867 cumulated_error++; 1868 } 1869 } 1870 continue; 1871 } 1872 log_debugx("adding lun \"%s\"", newlun->l_name); 1873 error = kernel_lun_add(newlun); 1874 if (error != 0) { 1875 log_warnx("failed to add lun \"%s\"", newlun->l_name); 1876 lun_delete(newlun); 1877 cumulated_error++; 1878 } 1879 } 1880 1881 /*
|
1812 * Now add new targets or modify existing ones.
|
1882 * Now add new ports or modify existing ones. |
1883 */
|
1814 TAILQ_FOREACH(newtarg, &newconf->conf_targets, t_next) {
1815 oldtarg = target_find(oldconf, newtarg->t_name);
|
1884 TAILQ_FOREACH(newport, &newconf->conf_ports, p_next) { 1885 oldport = port_find(oldconf, newport->p_name); |
1886
|
1817 if (oldtarg == NULL)
1818 error = kernel_port_add(newtarg);
1819 else {
1820 target_set_ctl_port(newtarg, oldtarg->t_ctl_port);
1821 error = kernel_port_update(newtarg);
|
1887 if (oldport == NULL) { 1888 error = kernel_port_add(newport); 1889 } else { 1890 newport->p_ctl_port = oldport->p_ctl_port; 1891 error = kernel_port_update(newport); |
1892 } 1893 if (error != 0) {
|
1824 log_warnx("failed to %s target %s",
1825 (oldtarg == NULL) ? "add" : "update",
1826 newtarg->t_name);
|
1894 log_warnx("failed to %s port %s", 1895 (oldport == NULL) ? "add" : "update", 1896 newport->p_name); |
1897 /* 1898 * XXX: Uncomment after fixing the root cause. 1899 * 1900 * cumulated_error++; 1901 */ 1902 } 1903 } 1904 1905 /* 1906 * Go through the new portals, opening the sockets as neccessary. 1907 */ 1908 TAILQ_FOREACH(newpg, &newconf->conf_portal_groups, pg_next) { 1909 if (newpg->pg_unassigned) { 1910 log_debugx("not listening on portal-group \"%s\", " 1911 "not assigned to any target", 1912 newpg->pg_name); 1913 continue; 1914 } 1915 TAILQ_FOREACH(newp, &newpg->pg_portals, p_next) { 1916 /* 1917 * Try to find already open portal and reuse 1918 * the listening socket. We don't care about 1919 * what portal or portal group that was, what 1920 * matters is the listening address. 1921 */ 1922 TAILQ_FOREACH(oldpg, &oldconf->conf_portal_groups, 1923 pg_next) { 1924 TAILQ_FOREACH(oldp, &oldpg->pg_portals, 1925 p_next) { 1926 if (strcmp(newp->p_listen, 1927 oldp->p_listen) == 0 && 1928 oldp->p_socket > 0) { 1929 newp->p_socket = 1930 oldp->p_socket; 1931 oldp->p_socket = 0; 1932 break; 1933 } 1934 } 1935 } 1936 if (newp->p_socket > 0) { 1937 /* 1938 * We're done with this portal. 1939 */ 1940 continue; 1941 } 1942 1943#ifdef ICL_KERNEL_PROXY 1944 if (proxy_mode) { 1945 newpg->pg_conf->conf_portal_id++; 1946 newp->p_id = newpg->pg_conf->conf_portal_id; 1947 log_debugx("listening on %s, portal-group " 1948 "\"%s\", portal id %d, using ICL proxy", 1949 newp->p_listen, newpg->pg_name, newp->p_id); 1950 kernel_listen(newp->p_ai, newp->p_iser, 1951 newp->p_id); 1952 continue; 1953 } 1954#endif 1955 assert(proxy_mode == false); 1956 assert(newp->p_iser == false); 1957 1958 log_debugx("listening on %s, portal-group \"%s\"", 1959 newp->p_listen, newpg->pg_name); 1960 newp->p_socket = socket(newp->p_ai->ai_family, 1961 newp->p_ai->ai_socktype, 1962 newp->p_ai->ai_protocol); 1963 if (newp->p_socket < 0) { 1964 log_warn("socket(2) failed for %s", 1965 newp->p_listen); 1966 cumulated_error++; 1967 continue; 1968 } 1969 sockbuf = SOCKBUF_SIZE; 1970 if (setsockopt(newp->p_socket, SOL_SOCKET, SO_RCVBUF, 1971 &sockbuf, sizeof(sockbuf)) == -1) 1972 log_warn("setsockopt(SO_RCVBUF) failed " 1973 "for %s", newp->p_listen); 1974 sockbuf = SOCKBUF_SIZE; 1975 if (setsockopt(newp->p_socket, SOL_SOCKET, SO_SNDBUF, 1976 &sockbuf, sizeof(sockbuf)) == -1) 1977 log_warn("setsockopt(SO_SNDBUF) failed " 1978 "for %s", newp->p_listen); 1979 error = setsockopt(newp->p_socket, SOL_SOCKET, 1980 SO_REUSEADDR, &one, sizeof(one)); 1981 if (error != 0) { 1982 log_warn("setsockopt(SO_REUSEADDR) failed " 1983 "for %s", newp->p_listen); 1984 close(newp->p_socket); 1985 newp->p_socket = 0; 1986 cumulated_error++; 1987 continue; 1988 } 1989 error = bind(newp->p_socket, newp->p_ai->ai_addr, 1990 newp->p_ai->ai_addrlen); 1991 if (error != 0) { 1992 log_warn("bind(2) failed for %s", 1993 newp->p_listen); 1994 close(newp->p_socket); 1995 newp->p_socket = 0; 1996 cumulated_error++; 1997 continue; 1998 } 1999 error = listen(newp->p_socket, -1); 2000 if (error != 0) { 2001 log_warn("listen(2) failed for %s", 2002 newp->p_listen); 2003 close(newp->p_socket); 2004 newp->p_socket = 0; 2005 cumulated_error++; 2006 continue; 2007 } 2008 } 2009 } 2010 2011 /* 2012 * Go through the no longer used sockets, closing them. 2013 */ 2014 TAILQ_FOREACH(oldpg, &oldconf->conf_portal_groups, pg_next) { 2015 TAILQ_FOREACH(oldp, &oldpg->pg_portals, p_next) { 2016 if (oldp->p_socket <= 0) 2017 continue; 2018 log_debugx("closing socket for %s, portal-group \"%s\"", 2019 oldp->p_listen, oldpg->pg_name); 2020 close(oldp->p_socket); 2021 oldp->p_socket = 0; 2022 } 2023 } 2024 2025 /* (Re-)Register on remaining/new iSNS servers. */ 2026 TAILQ_FOREACH(newns, &newconf->conf_isns, i_next) { 2027 TAILQ_FOREACH(oldns, &oldconf->conf_isns, i_next) { 2028 if (strcmp(oldns->i_addr, newns->i_addr) == 0) 2029 break; 2030 } 2031 isns_register(newns, oldns); 2032 } 2033 2034 /* Schedule iSNS update */ 2035 if (!TAILQ_EMPTY(&newconf->conf_isns)) 2036 set_timeout((newconf->conf_isns_period + 2) / 3, false); 2037 2038 return (cumulated_error); 2039} 2040 2041bool 2042timed_out(void) 2043{ 2044 2045 return (sigalrm_received); 2046} 2047 2048static void 2049sigalrm_handler_fatal(int dummy __unused) 2050{ 2051 /* 2052 * It would be easiest to just log an error and exit. We can't 2053 * do this, though, because log_errx() is not signal safe, since 2054 * it calls syslog(3). Instead, set a flag checked by pdu_send() 2055 * and pdu_receive(), to call log_errx() there. Should they fail 2056 * to notice, we'll exit here one second later. 2057 */ 2058 if (sigalrm_received) { 2059 /* 2060 * Oh well. Just give up and quit. 2061 */ 2062 _exit(2); 2063 } 2064 2065 sigalrm_received = true; 2066} 2067 2068static void 2069sigalrm_handler(int dummy __unused) 2070{ 2071 2072 sigalrm_received = true; 2073} 2074 2075void 2076set_timeout(int timeout, int fatal) 2077{ 2078 struct sigaction sa; 2079 struct itimerval itv; 2080 int error; 2081 2082 if (timeout <= 0) { 2083 log_debugx("session timeout disabled"); 2084 bzero(&itv, sizeof(itv)); 2085 error = setitimer(ITIMER_REAL, &itv, NULL); 2086 if (error != 0) 2087 log_err(1, "setitimer"); 2088 sigalrm_received = false; 2089 return; 2090 } 2091 2092 sigalrm_received = false; 2093 bzero(&sa, sizeof(sa)); 2094 if (fatal) 2095 sa.sa_handler = sigalrm_handler_fatal; 2096 else 2097 sa.sa_handler = sigalrm_handler; 2098 sigfillset(&sa.sa_mask); 2099 error = sigaction(SIGALRM, &sa, NULL); 2100 if (error != 0) 2101 log_err(1, "sigaction"); 2102 2103 /* 2104 * First SIGALRM will arive after conf_timeout seconds. 2105 * If we do nothing, another one will arrive a second later. 2106 */ 2107 log_debugx("setting session timeout to %d seconds", timeout); 2108 bzero(&itv, sizeof(itv)); 2109 itv.it_interval.tv_sec = 1; 2110 itv.it_value.tv_sec = timeout; 2111 error = setitimer(ITIMER_REAL, &itv, NULL); 2112 if (error != 0) 2113 log_err(1, "setitimer"); 2114} 2115 2116static int 2117wait_for_children(bool block) 2118{ 2119 pid_t pid; 2120 int status; 2121 int num = 0; 2122 2123 for (;;) { 2124 /* 2125 * If "block" is true, wait for at least one process. 2126 */ 2127 if (block && num == 0) 2128 pid = wait4(-1, &status, 0, NULL); 2129 else 2130 pid = wait4(-1, &status, WNOHANG, NULL); 2131 if (pid <= 0) 2132 break; 2133 if (WIFSIGNALED(status)) { 2134 log_warnx("child process %d terminated with signal %d", 2135 pid, WTERMSIG(status)); 2136 } else if (WEXITSTATUS(status) != 0) { 2137 log_warnx("child process %d terminated with exit status %d", 2138 pid, WEXITSTATUS(status)); 2139 } else { 2140 log_debugx("child process %d terminated gracefully", pid); 2141 } 2142 num++; 2143 } 2144 2145 return (num); 2146} 2147 2148static void 2149handle_connection(struct portal *portal, int fd, 2150 const struct sockaddr *client_sa, bool dont_fork) 2151{ 2152 struct connection *conn; 2153 int error; 2154 pid_t pid; 2155 char host[NI_MAXHOST + 1]; 2156 struct conf *conf; 2157 2158 conf = portal->p_portal_group->pg_conf; 2159 2160 if (dont_fork) { 2161 log_debugx("incoming connection; not forking due to -d flag"); 2162 } else { 2163 nchildren -= wait_for_children(false); 2164 assert(nchildren >= 0); 2165 2166 while (conf->conf_maxproc > 0 && nchildren >= conf->conf_maxproc) { 2167 log_debugx("maxproc limit of %d child processes hit; " 2168 "waiting for child process to exit", conf->conf_maxproc); 2169 nchildren -= wait_for_children(true); 2170 assert(nchildren >= 0); 2171 } 2172 log_debugx("incoming connection; forking child process #%d", 2173 nchildren); 2174 nchildren++; 2175 pid = fork(); 2176 if (pid < 0) 2177 log_err(1, "fork"); 2178 if (pid > 0) { 2179 close(fd); 2180 return; 2181 } 2182 } 2183 pidfile_close(conf->conf_pidfh); 2184 2185 error = getnameinfo(client_sa, client_sa->sa_len, 2186 host, sizeof(host), NULL, 0, NI_NUMERICHOST); 2187 if (error != 0) 2188 log_errx(1, "getnameinfo: %s", gai_strerror(error)); 2189 2190 log_debugx("accepted connection from %s; portal group \"%s\"", 2191 host, portal->p_portal_group->pg_name); 2192 log_set_peer_addr(host); 2193 setproctitle("%s", host); 2194 2195 conn = connection_new(portal, fd, host, client_sa); 2196 set_timeout(conf->conf_timeout, true); 2197 kernel_capsicate(); 2198 login(conn); 2199 if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) { 2200 kernel_handoff(conn); 2201 log_debugx("connection handed off to the kernel"); 2202 } else { 2203 assert(conn->conn_session_type == CONN_SESSION_TYPE_DISCOVERY); 2204 discovery(conn); 2205 } 2206 log_debugx("nothing more to do; exiting"); 2207 exit(0); 2208} 2209 2210static int 2211fd_add(int fd, fd_set *fdset, int nfds) 2212{ 2213 2214 /* 2215 * Skip sockets which we failed to bind. 2216 */ 2217 if (fd <= 0) 2218 return (nfds); 2219 2220 FD_SET(fd, fdset); 2221 if (fd > nfds) 2222 nfds = fd; 2223 return (nfds); 2224} 2225 2226static void 2227main_loop(struct conf *conf, bool dont_fork) 2228{ 2229 struct portal_group *pg; 2230 struct portal *portal; 2231 struct sockaddr_storage client_sa; 2232 socklen_t client_salen; 2233#ifdef ICL_KERNEL_PROXY 2234 int connection_id; 2235 int portal_id; 2236#endif 2237 fd_set fdset; 2238 int error, nfds, client_fd; 2239 2240 pidfile_write(conf->conf_pidfh); 2241 2242 for (;;) { 2243 if (sighup_received || sigterm_received || timed_out()) 2244 return; 2245 2246#ifdef ICL_KERNEL_PROXY 2247 if (proxy_mode) { 2248 client_salen = sizeof(client_sa); 2249 kernel_accept(&connection_id, &portal_id, 2250 (struct sockaddr *)&client_sa, &client_salen); 2251 assert(client_salen >= client_sa.ss_len); 2252 2253 log_debugx("incoming connection, id %d, portal id %d", 2254 connection_id, portal_id); 2255 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 2256 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { 2257 if (portal->p_id == portal_id) { 2258 goto found; 2259 } 2260 } 2261 } 2262 2263 log_errx(1, "kernel returned invalid portal_id %d", 2264 portal_id); 2265 2266found: 2267 handle_connection(portal, connection_id, 2268 (struct sockaddr *)&client_sa, dont_fork); 2269 } else { 2270#endif 2271 assert(proxy_mode == false); 2272 2273 FD_ZERO(&fdset); 2274 nfds = 0; 2275 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 2276 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) 2277 nfds = fd_add(portal->p_socket, &fdset, nfds); 2278 } 2279 error = select(nfds + 1, &fdset, NULL, NULL, NULL); 2280 if (error <= 0) { 2281 if (errno == EINTR) 2282 return; 2283 log_err(1, "select"); 2284 } 2285 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 2286 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { 2287 if (!FD_ISSET(portal->p_socket, &fdset)) 2288 continue; 2289 client_salen = sizeof(client_sa); 2290 client_fd = accept(portal->p_socket, 2291 (struct sockaddr *)&client_sa, 2292 &client_salen); 2293 if (client_fd < 0) 2294 log_err(1, "accept"); 2295 assert(client_salen >= client_sa.ss_len); 2296 2297 handle_connection(portal, client_fd, 2298 (struct sockaddr *)&client_sa, 2299 dont_fork); 2300 break; 2301 } 2302 } 2303#ifdef ICL_KERNEL_PROXY 2304 } 2305#endif 2306 } 2307} 2308 2309static void 2310sighup_handler(int dummy __unused) 2311{ 2312 2313 sighup_received = true; 2314} 2315 2316static void 2317sigterm_handler(int dummy __unused) 2318{ 2319 2320 sigterm_received = true; 2321} 2322 2323static void 2324sigchld_handler(int dummy __unused) 2325{ 2326 2327 /* 2328 * The only purpose of this handler is to make SIGCHLD 2329 * interrupt the ISCSIDWAIT ioctl(2), so we can call 2330 * wait_for_children(). 2331 */ 2332} 2333 2334static void 2335register_signals(void) 2336{ 2337 struct sigaction sa; 2338 int error; 2339 2340 bzero(&sa, sizeof(sa)); 2341 sa.sa_handler = sighup_handler; 2342 sigfillset(&sa.sa_mask); 2343 error = sigaction(SIGHUP, &sa, NULL); 2344 if (error != 0) 2345 log_err(1, "sigaction"); 2346 2347 sa.sa_handler = sigterm_handler; 2348 error = sigaction(SIGTERM, &sa, NULL); 2349 if (error != 0) 2350 log_err(1, "sigaction"); 2351 2352 sa.sa_handler = sigterm_handler; 2353 error = sigaction(SIGINT, &sa, NULL); 2354 if (error != 0) 2355 log_err(1, "sigaction"); 2356 2357 sa.sa_handler = sigchld_handler; 2358 error = sigaction(SIGCHLD, &sa, NULL); 2359 if (error != 0) 2360 log_err(1, "sigaction"); 2361} 2362 2363int 2364main(int argc, char **argv) 2365{ 2366 struct conf *oldconf, *newconf, *tmpconf; 2367 struct isns *newns; 2368 const char *config_path = DEFAULT_CONFIG_PATH; 2369 int debug = 0, ch, error; 2370 bool dont_daemonize = false; 2371 2372 while ((ch = getopt(argc, argv, "df:R")) != -1) { 2373 switch (ch) { 2374 case 'd': 2375 dont_daemonize = true; 2376 debug++; 2377 break; 2378 case 'f': 2379 config_path = optarg; 2380 break; 2381 case 'R': 2382#ifndef ICL_KERNEL_PROXY 2383 log_errx(1, "ctld(8) compiled without ICL_KERNEL_PROXY " 2384 "does not support iSER protocol"); 2385#endif 2386 proxy_mode = true; 2387 break; 2388 case '?': 2389 default: 2390 usage(); 2391 } 2392 } 2393 argc -= optind; 2394 if (argc != 0) 2395 usage(); 2396 2397 log_init(debug); 2398 kernel_init(); 2399 2400 oldconf = conf_new_from_kernel(); 2401 newconf = conf_new_from_file(config_path); 2402 if (newconf == NULL) 2403 log_errx(1, "configuration error; exiting"); 2404 if (debug > 0) { 2405 oldconf->conf_debug = debug; 2406 newconf->conf_debug = debug; 2407 } 2408 2409 error = conf_apply(oldconf, newconf); 2410 if (error != 0) 2411 log_errx(1, "failed to apply configuration; exiting"); 2412 2413 conf_delete(oldconf); 2414 oldconf = NULL; 2415 2416 register_signals(); 2417 2418 if (dont_daemonize == false) { 2419 log_debugx("daemonizing"); 2420 if (daemon(0, 0) == -1) { 2421 log_warn("cannot daemonize"); 2422 pidfile_remove(newconf->conf_pidfh); 2423 exit(1); 2424 } 2425 } 2426 2427 /* Schedule iSNS update */ 2428 if (!TAILQ_EMPTY(&newconf->conf_isns)) 2429 set_timeout((newconf->conf_isns_period + 2) / 3, false); 2430 2431 for (;;) { 2432 main_loop(newconf, dont_daemonize); 2433 if (sighup_received) { 2434 sighup_received = false; 2435 log_debugx("received SIGHUP, reloading configuration"); 2436 tmpconf = conf_new_from_file(config_path); 2437 if (tmpconf == NULL) { 2438 log_warnx("configuration error, " 2439 "continuing with old configuration"); 2440 } else { 2441 if (debug > 0) 2442 tmpconf->conf_debug = debug; 2443 oldconf = newconf; 2444 newconf = tmpconf; 2445 error = conf_apply(oldconf, newconf); 2446 if (error != 0) 2447 log_warnx("failed to reload " 2448 "configuration"); 2449 conf_delete(oldconf); 2450 oldconf = NULL; 2451 } 2452 } else if (sigterm_received) { 2453 log_debugx("exiting on signal; " 2454 "reloading empty configuration"); 2455 2456 log_debugx("removing CTL iSCSI ports " 2457 "and terminating all connections"); 2458 2459 oldconf = newconf; 2460 newconf = conf_new(); 2461 if (debug > 0) 2462 newconf->conf_debug = debug; 2463 error = conf_apply(oldconf, newconf); 2464 if (error != 0) 2465 log_warnx("failed to apply configuration"); 2466 conf_delete(oldconf); 2467 oldconf = NULL; 2468 2469 log_warnx("exiting on signal"); 2470 exit(0); 2471 } else { 2472 nchildren -= wait_for_children(false); 2473 assert(nchildren >= 0); 2474 if (timed_out()) { 2475 set_timeout(0, false); 2476 TAILQ_FOREACH(newns, &newconf->conf_isns, i_next) 2477 isns_check(newns); 2478 /* Schedule iSNS update */ 2479 if (!TAILQ_EMPTY(&newconf->conf_isns)) { 2480 set_timeout((newconf->conf_isns_period 2481 + 2) / 3, 2482 false); 2483 } 2484 } 2485 } 2486 } 2487 /* NOTREACHED */ 2488}
|