1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>. 5 * Copyright (c) Intel Corporation. 6 * All rights reserved. 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 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * * Neither the name of Intel Corporation nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include "spdk/stdinc.h" 36 37 #include "spdk/conf.h" 38 #include "spdk/string.h" 39 40 #include "spdk_internal/log.h" 41 42 #include "iscsi/iscsi.h" 43 #include "iscsi/init_grp.h" 44 45 static struct spdk_iscsi_init_grp * 46 spdk_iscsi_init_grp_create(int tag) 47 { 48 struct spdk_iscsi_init_grp *ig; 49 50 ig = calloc(1, sizeof(*ig)); 51 if (ig == NULL) { 52 SPDK_ERRLOG("calloc() failed for initiator group\n"); 53 return NULL; 54 } 55 56 ig->tag = tag; 57 TAILQ_INIT(&ig->initiator_head); 58 TAILQ_INIT(&ig->netmask_head); 59 return ig; 60 } 61 62 static struct spdk_iscsi_initiator_name * 63 spdk_iscsi_init_grp_find_initiator(struct spdk_iscsi_init_grp *ig, char *name) 64 { 65 struct spdk_iscsi_initiator_name *iname; 66 67 TAILQ_FOREACH(iname, &ig->initiator_head, tailq) { 68 if (!strcmp(iname->name, name)) { 69 return iname; 70 } 71 } 72 return NULL; 73 } 74 75 static int 76 spdk_iscsi_init_grp_add_initiator(struct spdk_iscsi_init_grp *ig, char *name) 77 { 78 struct spdk_iscsi_initiator_name *iname; 79 char *p; 80 81 if (ig->ninitiators >= MAX_INITIATOR) { 82 SPDK_ERRLOG("> MAX_INITIATOR(=%d) is not allowed\n", MAX_INITIATOR); 83 return -EPERM; 84 } 85 86 if (strlen(name) > MAX_INITIATOR_NAME) { 87 SPDK_ERRLOG("Initiator Name is larger than 223 bytes\n"); 88 return -EINVAL; 89 } 90 91 iname = spdk_iscsi_init_grp_find_initiator(ig, name); 92 if (iname != NULL) { 93 return -EEXIST; 94 } 95 96 iname = malloc(sizeof(*iname)); 97 if (iname == NULL) { 98 SPDK_ERRLOG("malloc() failed for initiator name str\n"); 99 return -ENOMEM; 100 } 101 102 iname->name = strdup(name); 103 if (iname->name == NULL) { 104 SPDK_ERRLOG("strdup() failed for initiator name\n"); 105 free(iname); 106 return -ENOMEM; 107 } 108 109 /* Replace "ALL" by "ANY" if set */ 110 p = strstr(iname->name, "ALL"); 111 if (p != NULL) { 112 SPDK_WARNLOG("Please use \"%s\" instead of \"%s\"\n", "ANY", "ALL"); 113 SPDK_WARNLOG("Converting \"%s\" to \"%s\" automatically\n", "ALL", "ANY"); 114 memcpy(p, "ANY", 3); 115 } 116 117 TAILQ_INSERT_TAIL(&ig->initiator_head, iname, tailq); 118 ig->ninitiators++; 119 120 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "InitiatorName %s\n", name); 121 return 0; 122 } 123 124 static int 125 spdk_iscsi_init_grp_delete_initiator(struct spdk_iscsi_init_grp *ig, char *name) 126 { 127 struct spdk_iscsi_initiator_name *iname; 128 129 iname = spdk_iscsi_init_grp_find_initiator(ig, name); 130 if (iname == NULL) { 131 return -ENOENT; 132 } 133 134 TAILQ_REMOVE(&ig->initiator_head, iname, tailq); 135 ig->ninitiators--; 136 free(iname->name); 137 free(iname); 138 return 0; 139 } 140 141 static int 142 spdk_iscsi_init_grp_add_initiators(struct spdk_iscsi_init_grp *ig, int num_inames, char **inames) 143 { 144 int i; 145 int rc; 146 147 for (i = 0; i < num_inames; i++) { 148 rc = spdk_iscsi_init_grp_add_initiator(ig, inames[i]); 149 if (rc < 0) { 150 goto cleanup; 151 } 152 } 153 return 0; 154 155 cleanup: 156 for (; i > 0; --i) { 157 spdk_iscsi_init_grp_delete_initiator(ig, inames[i - 1]); 158 } 159 return rc; 160 } 161 162 static void 163 spdk_iscsi_init_grp_delete_all_initiators(struct spdk_iscsi_init_grp *ig) 164 { 165 struct spdk_iscsi_initiator_name *iname, *tmp; 166 167 TAILQ_FOREACH_SAFE(iname, &ig->initiator_head, tailq, tmp) { 168 TAILQ_REMOVE(&ig->initiator_head, iname, tailq); 169 ig->ninitiators--; 170 free(iname->name); 171 free(iname); 172 } 173 } 174 175 static int 176 spdk_iscsi_init_grp_delete_initiators(struct spdk_iscsi_init_grp *ig, int num_inames, char **inames) 177 { 178 int i; 179 int rc; 180 181 for (i = 0; i < num_inames; i++) { 182 rc = spdk_iscsi_init_grp_delete_initiator(ig, inames[i]); 183 if (rc < 0) { 184 goto cleanup; 185 } 186 } 187 return 0; 188 189 cleanup: 190 for (; i > 0; --i) { 191 rc = spdk_iscsi_init_grp_add_initiator(ig, inames[i - 1]); 192 if (rc != 0) { 193 spdk_iscsi_init_grp_delete_all_initiators(ig); 194 break; 195 } 196 } 197 return -1; 198 } 199 200 static struct spdk_iscsi_initiator_netmask * 201 spdk_iscsi_init_grp_find_netmask(struct spdk_iscsi_init_grp *ig, const char *mask) 202 { 203 struct spdk_iscsi_initiator_netmask *netmask; 204 205 TAILQ_FOREACH(netmask, &ig->netmask_head, tailq) { 206 if (!strcmp(netmask->mask, mask)) { 207 return netmask; 208 } 209 } 210 return NULL; 211 } 212 213 static int 214 spdk_iscsi_init_grp_add_netmask(struct spdk_iscsi_init_grp *ig, char *mask) 215 { 216 struct spdk_iscsi_initiator_netmask *imask; 217 char *p; 218 219 if (ig->nnetmasks >= MAX_NETMASK) { 220 SPDK_ERRLOG("> MAX_NETMASK(=%d) is not allowed\n", MAX_NETMASK); 221 return -EPERM; 222 } 223 224 imask = spdk_iscsi_init_grp_find_netmask(ig, mask); 225 if (imask != NULL) { 226 return -EEXIST; 227 } 228 229 imask = malloc(sizeof(*imask)); 230 if (imask == NULL) { 231 SPDK_ERRLOG("malloc() failed for inititator mask str\n"); 232 return -ENOMEM; 233 } 234 235 imask->mask = strdup(mask); 236 if (imask->mask == NULL) { 237 SPDK_ERRLOG("strdup() failed for initiator mask\n"); 238 free(imask); 239 return -ENOMEM; 240 } 241 242 /* Replace "ALL" by "ANY" if set */ 243 p = strstr(imask->mask, "ALL"); 244 if (p != NULL) { 245 SPDK_WARNLOG("Please use \"%s\" instead of \"%s\"\n", "ANY", "ALL"); 246 SPDK_WARNLOG("Converting \"%s\" to \"%s\" automatically\n", "ALL", "ANY"); 247 memcpy(p, "ANY", 3); 248 } 249 250 TAILQ_INSERT_TAIL(&ig->netmask_head, imask, tailq); 251 ig->nnetmasks++; 252 253 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Netmask %s\n", mask); 254 return 0; 255 } 256 257 static int 258 spdk_iscsi_init_grp_delete_netmask(struct spdk_iscsi_init_grp *ig, char *mask) 259 { 260 struct spdk_iscsi_initiator_netmask *imask; 261 262 imask = spdk_iscsi_init_grp_find_netmask(ig, mask); 263 if (imask == NULL) { 264 return -ENOENT; 265 } 266 267 TAILQ_REMOVE(&ig->netmask_head, imask, tailq); 268 ig->nnetmasks--; 269 free(imask->mask); 270 free(imask); 271 return 0; 272 } 273 274 static int 275 spdk_iscsi_init_grp_add_netmasks(struct spdk_iscsi_init_grp *ig, int num_imasks, char **imasks) 276 { 277 int i; 278 int rc; 279 280 for (i = 0; i < num_imasks; i++) { 281 rc = spdk_iscsi_init_grp_add_netmask(ig, imasks[i]); 282 if (rc != 0) { 283 goto cleanup; 284 } 285 } 286 return 0; 287 288 cleanup: 289 for (; i > 0; --i) { 290 spdk_iscsi_init_grp_delete_netmask(ig, imasks[i - 1]); 291 } 292 return rc; 293 } 294 295 static void 296 spdk_iscsi_init_grp_delete_all_netmasks(struct spdk_iscsi_init_grp *ig) 297 { 298 struct spdk_iscsi_initiator_netmask *imask, *tmp; 299 300 TAILQ_FOREACH_SAFE(imask, &ig->netmask_head, tailq, tmp) { 301 TAILQ_REMOVE(&ig->netmask_head, imask, tailq); 302 ig->nnetmasks--; 303 free(imask->mask); 304 free(imask); 305 } 306 } 307 308 static int 309 spdk_iscsi_init_grp_delete_netmasks(struct spdk_iscsi_init_grp *ig, int num_imasks, char **imasks) 310 { 311 int i; 312 int rc; 313 314 for (i = 0; i < num_imasks; i++) { 315 rc = spdk_iscsi_init_grp_delete_netmask(ig, imasks[i]); 316 if (rc != 0) { 317 goto cleanup; 318 } 319 } 320 return 0; 321 322 cleanup: 323 for (; i > 0; --i) { 324 rc = spdk_iscsi_init_grp_add_netmask(ig, imasks[i - 1]); 325 if (rc != 0) { 326 spdk_iscsi_init_grp_delete_all_netmasks(ig); 327 break; 328 } 329 } 330 return -1; 331 } 332 333 /* Read spdk iscsi target's config file and create initiator group */ 334 static int 335 spdk_iscsi_parse_init_grp(struct spdk_conf_section *sp) 336 { 337 int i, rc = 0; 338 const char *val = NULL; 339 int num_initiator_names; 340 int num_initiator_masks; 341 char **initiators = NULL, **netmasks = NULL; 342 int tag = spdk_conf_section_get_num(sp); 343 344 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "add initiator group %d\n", tag); 345 346 val = spdk_conf_section_get_val(sp, "Comment"); 347 if (val != NULL) { 348 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Comment %s\n", val); 349 } 350 351 /* counts number of definitions */ 352 for (i = 0; ; i++) { 353 val = spdk_conf_section_get_nval(sp, "InitiatorName", i); 354 if (val == NULL) { 355 break; 356 } 357 } 358 if (i == 0) { 359 SPDK_ERRLOG("num_initiator_names = 0\n"); 360 return -EINVAL; 361 } 362 num_initiator_names = i; 363 if (num_initiator_names > MAX_INITIATOR) { 364 SPDK_ERRLOG("%d > MAX_INITIATOR\n", num_initiator_names); 365 return -E2BIG; 366 } 367 for (i = 0; ; i++) { 368 val = spdk_conf_section_get_nval(sp, "Netmask", i); 369 if (val == NULL) { 370 break; 371 } 372 } 373 if (i == 0) { 374 SPDK_ERRLOG("num_initiator_mask = 0\n"); 375 return -EINVAL; 376 } 377 num_initiator_masks = i; 378 if (num_initiator_masks > MAX_NETMASK) { 379 SPDK_ERRLOG("%d > MAX_NETMASK\n", num_initiator_masks); 380 return -E2BIG; 381 } 382 383 initiators = calloc(num_initiator_names, sizeof(char *)); 384 if (!initiators) { 385 SPDK_ERRLOG("calloc() failed for temp initiator name array\n"); 386 return -ENOMEM; 387 } 388 for (i = 0; i < num_initiator_names; i++) { 389 val = spdk_conf_section_get_nval(sp, "InitiatorName", i); 390 if (!val) { 391 SPDK_ERRLOG("InitiatorName %d not found\n", i); 392 rc = -EINVAL; 393 goto cleanup; 394 } 395 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "InitiatorName %s\n", val); 396 initiators[i] = strdup(val); 397 if (!initiators[i]) { 398 SPDK_ERRLOG("strdup() failed for temp initiator name\n"); 399 rc = -ENOMEM; 400 goto cleanup; 401 } 402 } 403 netmasks = calloc(num_initiator_masks, sizeof(char *)); 404 if (!netmasks) { 405 SPDK_ERRLOG("malloc() failed for portal group\n"); 406 rc = -ENOMEM; 407 goto cleanup; 408 } 409 for (i = 0; i < num_initiator_masks; i++) { 410 val = spdk_conf_section_get_nval(sp, "Netmask", i); 411 if (!val) { 412 SPDK_ERRLOG("Netmask %d not found\n", i); 413 rc = -EINVAL; 414 goto cleanup; 415 } 416 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Netmask %s\n", val); 417 netmasks[i] = strdup(val); 418 if (!netmasks[i]) { 419 SPDK_ERRLOG("strdup() failed for temp initiator mask\n"); 420 rc = -ENOMEM; 421 goto cleanup; 422 } 423 } 424 425 rc = spdk_iscsi_init_grp_create_from_initiator_list(tag, 426 num_initiator_names, initiators, num_initiator_masks, netmasks); 427 428 cleanup: 429 if (initiators) { 430 for (i = 0; i < num_initiator_names; i++) { 431 if (initiators[i]) { 432 free(initiators[i]); 433 } 434 } 435 free(initiators); 436 } 437 if (netmasks) { 438 for (i = 0; i < num_initiator_masks; i++) { 439 if (netmasks[i]) { 440 free(netmasks[i]); 441 } 442 } 443 free(netmasks); 444 } 445 return rc; 446 } 447 448 int 449 spdk_iscsi_init_grp_register(struct spdk_iscsi_init_grp *ig) 450 { 451 struct spdk_iscsi_init_grp *tmp; 452 int rc = -1; 453 454 assert(ig != NULL); 455 456 pthread_mutex_lock(&g_spdk_iscsi.mutex); 457 tmp = spdk_iscsi_init_grp_find_by_tag(ig->tag); 458 if (tmp == NULL) { 459 TAILQ_INSERT_TAIL(&g_spdk_iscsi.ig_head, ig, tailq); 460 rc = 0; 461 } 462 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 463 464 return rc; 465 } 466 467 /* 468 * Create initiator group from list of initiator ip/hostnames and netmasks 469 * The initiator hostname/netmask lists are allocated by the caller on the 470 * heap. Freed later by common initiator_group_destroy() code 471 */ 472 int 473 spdk_iscsi_init_grp_create_from_initiator_list(int tag, 474 int num_initiator_names, 475 char **initiator_names, 476 int num_initiator_masks, 477 char **initiator_masks) 478 { 479 int rc = -1; 480 struct spdk_iscsi_init_grp *ig = NULL; 481 482 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, 483 "add initiator group (from initiator list) tag=%d, #initiators=%d, #masks=%d\n", 484 tag, num_initiator_names, num_initiator_masks); 485 486 ig = spdk_iscsi_init_grp_create(tag); 487 if (!ig) { 488 SPDK_ERRLOG("initiator group create error (%d)\n", tag); 489 return rc; 490 } 491 492 rc = spdk_iscsi_init_grp_add_initiators(ig, num_initiator_names, 493 initiator_names); 494 if (rc < 0) { 495 SPDK_ERRLOG("add initiator name error\n"); 496 goto cleanup; 497 } 498 499 rc = spdk_iscsi_init_grp_add_netmasks(ig, num_initiator_masks, 500 initiator_masks); 501 if (rc < 0) { 502 SPDK_ERRLOG("add initiator netmask error\n"); 503 goto cleanup; 504 } 505 506 rc = spdk_iscsi_init_grp_register(ig); 507 if (rc < 0) { 508 SPDK_ERRLOG("initiator group register error (%d)\n", tag); 509 goto cleanup; 510 } 511 return 0; 512 513 cleanup: 514 spdk_iscsi_init_grp_destroy(ig); 515 return rc; 516 } 517 518 int 519 spdk_iscsi_init_grp_add_initiators_from_initiator_list(int tag, 520 int num_initiator_names, 521 char **initiator_names, 522 int num_initiator_masks, 523 char **initiator_masks) 524 { 525 int rc = -1; 526 struct spdk_iscsi_init_grp *ig; 527 528 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, 529 "add initiator to initiator group: tag=%d, #initiators=%d, #masks=%d\n", 530 tag, num_initiator_names, num_initiator_masks); 531 532 pthread_mutex_lock(&g_spdk_iscsi.mutex); 533 ig = spdk_iscsi_init_grp_find_by_tag(tag); 534 if (!ig) { 535 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 536 SPDK_ERRLOG("initiator group (%d) is not found\n", tag); 537 return rc; 538 } 539 540 rc = spdk_iscsi_init_grp_add_initiators(ig, num_initiator_names, 541 initiator_names); 542 if (rc < 0) { 543 SPDK_ERRLOG("add initiator name error\n"); 544 goto error; 545 } 546 547 rc = spdk_iscsi_init_grp_add_netmasks(ig, num_initiator_masks, 548 initiator_masks); 549 if (rc < 0) { 550 SPDK_ERRLOG("add initiator netmask error\n"); 551 spdk_iscsi_init_grp_delete_initiators(ig, num_initiator_names, 552 initiator_names); 553 } 554 555 error: 556 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 557 return rc; 558 } 559 560 int 561 spdk_iscsi_init_grp_delete_initiators_from_initiator_list(int tag, 562 int num_initiator_names, 563 char **initiator_names, 564 int num_initiator_masks, 565 char **initiator_masks) 566 { 567 int rc = -1; 568 struct spdk_iscsi_init_grp *ig; 569 570 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, 571 "delete initiator from initiator group: tag=%d, #initiators=%d, #masks=%d\n", 572 tag, num_initiator_names, num_initiator_masks); 573 574 pthread_mutex_lock(&g_spdk_iscsi.mutex); 575 ig = spdk_iscsi_init_grp_find_by_tag(tag); 576 if (!ig) { 577 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 578 SPDK_ERRLOG("initiator group (%d) is not found\n", tag); 579 return rc; 580 } 581 582 rc = spdk_iscsi_init_grp_delete_initiators(ig, num_initiator_names, 583 initiator_names); 584 if (rc < 0) { 585 SPDK_ERRLOG("delete initiator name error\n"); 586 goto error; 587 } 588 589 rc = spdk_iscsi_init_grp_delete_netmasks(ig, num_initiator_masks, 590 initiator_masks); 591 if (rc < 0) { 592 SPDK_ERRLOG("delete initiator netmask error\n"); 593 spdk_iscsi_init_grp_add_initiators(ig, num_initiator_names, 594 initiator_names); 595 goto error; 596 } 597 598 error: 599 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 600 return rc; 601 } 602 603 void 604 spdk_iscsi_init_grp_destroy(struct spdk_iscsi_init_grp *ig) 605 { 606 if (!ig) { 607 return; 608 } 609 610 spdk_iscsi_init_grp_delete_all_initiators(ig); 611 spdk_iscsi_init_grp_delete_all_netmasks(ig); 612 free(ig); 613 }; 614 615 struct spdk_iscsi_init_grp * 616 spdk_iscsi_init_grp_find_by_tag(int tag) 617 { 618 struct spdk_iscsi_init_grp *ig; 619 620 TAILQ_FOREACH(ig, &g_spdk_iscsi.ig_head, tailq) { 621 if (ig->tag == tag) { 622 return ig; 623 } 624 } 625 626 return NULL; 627 } 628 629 int 630 spdk_iscsi_parse_init_grps(void) 631 { 632 struct spdk_conf_section *sp; 633 int rc; 634 635 sp = spdk_conf_first_section(NULL); 636 while (sp != NULL) { 637 if (spdk_conf_section_match_prefix(sp, "InitiatorGroup")) { 638 if (spdk_conf_section_get_num(sp) == 0) { 639 SPDK_ERRLOG("Group 0 is invalid\n"); 640 return -1; 641 } 642 rc = spdk_iscsi_parse_init_grp(sp); 643 if (rc < 0) { 644 SPDK_ERRLOG("parse_init_group() failed\n"); 645 return -1; 646 } 647 } 648 sp = spdk_conf_next_section(sp); 649 } 650 return 0; 651 } 652 653 void 654 spdk_iscsi_init_grps_destroy(void) 655 { 656 struct spdk_iscsi_init_grp *ig, *tmp; 657 658 SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "spdk_iscsi_init_grp_array_destroy\n"); 659 pthread_mutex_lock(&g_spdk_iscsi.mutex); 660 TAILQ_FOREACH_SAFE(ig, &g_spdk_iscsi.ig_head, tailq, tmp) { 661 TAILQ_REMOVE(&g_spdk_iscsi.ig_head, ig, tailq); 662 spdk_iscsi_init_grp_destroy(ig); 663 } 664 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 665 } 666 667 struct spdk_iscsi_init_grp * 668 spdk_iscsi_init_grp_unregister(int tag) 669 { 670 struct spdk_iscsi_init_grp *ig; 671 672 pthread_mutex_lock(&g_spdk_iscsi.mutex); 673 TAILQ_FOREACH(ig, &g_spdk_iscsi.ig_head, tailq) { 674 if (ig->tag == tag) { 675 TAILQ_REMOVE(&g_spdk_iscsi.ig_head, ig, tailq); 676 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 677 return ig; 678 } 679 } 680 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 681 return NULL; 682 } 683 684 static const char *initiator_group_section = \ 685 "\n" 686 "# Users must change the InitiatorGroup section(s) to match the IP\n" 687 "# addresses and initiator configuration in their environment.\n" 688 "# Netmask can be used to specify a single IP address or a range of IP addresses\n" 689 "# Netmask 192.168.1.20 <== single IP address\n" 690 "# Netmask 192.168.1.0/24 <== IP range 192.168.1.*\n"; 691 692 #define INITIATOR_GROUP_TMPL \ 693 "[InitiatorGroup%d]\n" \ 694 " Comment \"Initiator Group%d\"\n" 695 696 #define INITIATOR_TMPL \ 697 " InitiatorName " 698 699 #define NETMASK_TMPL \ 700 " Netmask " 701 702 void 703 spdk_iscsi_init_grps_config_text(FILE *fp) 704 { 705 struct spdk_iscsi_init_grp *ig; 706 struct spdk_iscsi_initiator_name *iname; 707 struct spdk_iscsi_initiator_netmask *imask; 708 709 /* Create initiator group section */ 710 fprintf(fp, "%s", initiator_group_section); 711 712 /* Dump initiator groups */ 713 TAILQ_FOREACH(ig, &g_spdk_iscsi.ig_head, tailq) { 714 if (NULL == ig) { continue; } 715 fprintf(fp, INITIATOR_GROUP_TMPL, ig->tag, ig->tag); 716 717 /* Dump initiators */ 718 fprintf(fp, INITIATOR_TMPL); 719 TAILQ_FOREACH(iname, &ig->initiator_head, tailq) { 720 fprintf(fp, "%s ", iname->name); 721 } 722 fprintf(fp, "\n"); 723 724 /* Dump netmasks */ 725 fprintf(fp, NETMASK_TMPL); 726 TAILQ_FOREACH(imask, &ig->netmask_head, tailq) { 727 fprintf(fp, "%s ", imask->mask); 728 } 729 fprintf(fp, "\n"); 730 } 731 } 732 733 static void 734 spdk_iscsi_init_grp_info_json(struct spdk_iscsi_init_grp *ig, 735 struct spdk_json_write_ctx *w) 736 { 737 struct spdk_iscsi_initiator_name *iname; 738 struct spdk_iscsi_initiator_netmask *imask; 739 740 spdk_json_write_object_begin(w); 741 742 spdk_json_write_named_int32(w, "tag", ig->tag); 743 744 spdk_json_write_named_array_begin(w, "initiators"); 745 TAILQ_FOREACH(iname, &ig->initiator_head, tailq) { 746 spdk_json_write_string(w, iname->name); 747 } 748 spdk_json_write_array_end(w); 749 750 spdk_json_write_named_array_begin(w, "netmasks"); 751 TAILQ_FOREACH(imask, &ig->netmask_head, tailq) { 752 spdk_json_write_string(w, imask->mask); 753 } 754 spdk_json_write_array_end(w); 755 756 spdk_json_write_object_end(w); 757 } 758 759 static void 760 spdk_iscsi_init_grp_config_json(struct spdk_iscsi_init_grp *ig, 761 struct spdk_json_write_ctx *w) 762 { 763 spdk_json_write_object_begin(w); 764 765 spdk_json_write_named_string(w, "method", "add_initiator_group"); 766 767 spdk_json_write_name(w, "params"); 768 spdk_iscsi_init_grp_info_json(ig, w); 769 770 spdk_json_write_object_end(w); 771 } 772 773 void 774 spdk_iscsi_init_grps_info_json(struct spdk_json_write_ctx *w) 775 { 776 struct spdk_iscsi_init_grp *ig; 777 778 TAILQ_FOREACH(ig, &g_spdk_iscsi.ig_head, tailq) { 779 spdk_iscsi_init_grp_info_json(ig, w); 780 } 781 } 782 783 void 784 spdk_iscsi_init_grps_config_json(struct spdk_json_write_ctx *w) 785 { 786 struct spdk_iscsi_init_grp *ig; 787 788 TAILQ_FOREACH(ig, &g_spdk_iscsi.ig_head, tailq) { 789 spdk_iscsi_init_grp_config_json(ig, w); 790 } 791 } 792