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