1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include "iscsi.h" 27 #include "nvfile.h" 28 #include "persistent.h" 29 #include <sys/scsi/adapters/iscsi_if.h> 30 #include <netinet/in.h> 31 32 /* 33 * MAX_KEY_SIZE needs to be the same size of the ISCSI_MAX_NAME_LEN 34 * plus space for a ',' and a string form of tpgt (5 bytes). 35 */ 36 #define MAX_KEY_SIZE (ISCSI_MAX_NAME_LEN + 5) 37 38 /* 39 * Name identifiers for the various types of data 40 */ 41 #define DISCOVERY_METHOD_ID "DiscMethod" 42 #define NODE_NAME_ID "NodeName" 43 #define NODE_ALIAS_ID "NodeAlias" 44 #define STATIC_ADDR_ID "StaticAddr" 45 #define STATIC_ADDR2_ID "StaticAddr2" 46 #define DISCOVERY_ADDR_ID "DiscAddr" 47 #define ISNS_SERVER_ADDR_ID "ISNSAddr" 48 #define LOGIN_PARAMS_ID "Login" 49 #define CHAP_PARAMS_ID "Chap" 50 #define RADIUS_PARAMS_ID "Radius" 51 #define BIDIR_AUTH_PARAMS_ID "BidirAuth" 52 #define SESSION_PARAMS_ID "Session" 53 #define TUNABLE_PARAMS_ID "Tunable" 54 55 /* 56 * Local Global Variables 57 */ 58 static kmutex_t static_addr_data_lock; 59 static kmutex_t disc_addr_data_lock; 60 static kmutex_t isns_addr_data_lock; 61 static kmutex_t param_data_lock; 62 static kmutex_t chap_data_lock; 63 static kmutex_t auth_data_lock; 64 static kmutex_t tunable_data_lock; 65 /* 66 * Local Function Prototypes 67 */ 68 static boolean_t persistent_disc_meth_common(iSCSIDiscoveryMethod_t method, 69 boolean_t do_clear); 70 static void persistent_static_addr_upgrade_to_v2(); 71 72 /* 73 * This wrapper keeps old inet_ntop() behaviour and should be called when 74 * IP addresses are used as keys into persistent storage. 75 */ 76 static void 77 iscsi_inet_ntop(int af, const void *addr, char *buf) 78 { 79 #define UC(b) (((int)b) & 0xff) 80 if (af == AF_INET) { 81 uchar_t *v4addr = (uchar_t *)addr; 82 (void) snprintf(buf, INET6_ADDRSTRLEN, "%03d.%03d.%03d.%03d", 83 UC(v4addr[0]), UC(v4addr[1]), UC(v4addr[2]), UC(v4addr[3])); 84 } else { 85 (void) inet_ntop(af, addr, buf, INET6_ADDRSTRLEN); 86 } 87 #undef UC 88 } 89 90 /* 91 * persistent_init_disc_addr_oids - Oid is stored with discovery address 92 * however oids are not persisted and the discovery address oids need to 93 * be regenerated during initialization. 94 */ 95 static void 96 persistent_init_disc_addr_oids() 97 { 98 uint32_t addr_count = 0; 99 void *void_p = NULL; 100 entry_t e; 101 uint32_t i, curr_count; 102 103 /* 104 * Using two loops here as as addresses are updated and readded we get 105 * into an infinite loop while doing persistent_disc_addr_next if we 106 * update the entry as we go. The first loop will get the number of 107 * addresses that need to be updated and the second will update that 108 * many addresses. 109 */ 110 persistent_disc_addr_lock(); 111 while (persistent_disc_addr_next(&void_p, &e) == B_TRUE) { 112 addr_count++; 113 } 114 persistent_disc_addr_unlock(); 115 116 for (i = 0; i < addr_count; i++) { 117 curr_count = 0; 118 119 void_p = NULL; 120 persistent_disc_addr_lock(); 121 122 /* Use curr_count to skip previously updated addresses */ 123 while (persistent_disc_addr_next(&void_p, &e) == 124 B_TRUE && i < curr_count) { 125 curr_count++; 126 } 127 persistent_disc_addr_unlock(); 128 129 mutex_enter(&iscsi_oid_mutex); 130 e.e_oid = iscsi_oid++; 131 mutex_exit(&iscsi_oid_mutex); 132 133 if (persistent_disc_addr_set(&e) == B_FALSE) { 134 break; 135 } 136 } 137 } 138 139 /* 140 * persistent_init_static_addr_oids - Oid is stored with static address 141 * however oids are not persisted and the static address oids need to 142 * be regenerated during initialization. 143 */ 144 static void 145 persistent_init_static_addr_oids() 146 { 147 uint32_t addr_count = 0; 148 void *void_p = NULL; 149 entry_t e; 150 uint32_t i, curr_count; 151 char *target_name; 152 153 /* 154 * Solaris 10 Update 1/2 initially had a database 155 * that didn't support the multiple static-config 156 * entries to the same target. The below call 157 * will check if the database is still of that 158 * old structure and upgrade it. It will leave 159 * the old records incase a down grade of the 160 * software is required. 161 */ 162 persistent_static_addr_upgrade_to_v2(); 163 164 /* 165 * Using two loops here as as addresses are updated and readded we get 166 * into an infinite loop while doing persistent_disc_addr_next if we 167 * update the entry as we go. The first loop will get the number of 168 * addresses that need to be updated and the second will update that 169 * many addresses. 170 */ 171 target_name = kmem_alloc(MAX_KEY_SIZE, KM_SLEEP); 172 persistent_static_addr_lock(); 173 while (persistent_static_addr_next(&void_p, target_name, &e) == 174 B_TRUE) { 175 addr_count++; 176 } 177 178 for (i = 0; i < addr_count; i++) { 179 curr_count = 0; 180 181 void_p = NULL; 182 183 /* Use curr_count to skip previously updated addresses */ 184 while ((persistent_static_addr_next( 185 &void_p, target_name, &e) == B_TRUE) && 186 (i < curr_count)) { 187 curr_count++; 188 } 189 190 /* Skip the target whose address size length is 0 */ 191 if (e.e_insize == 0) { 192 continue; 193 } 194 195 mutex_enter(&iscsi_oid_mutex); 196 e.e_oid = iscsi_oid++; 197 mutex_exit(&iscsi_oid_mutex); 198 199 if (persistent_static_addr_set(target_name, &e) == B_FALSE) { 200 break; 201 } 202 } 203 persistent_static_addr_unlock(); 204 kmem_free(target_name, MAX_KEY_SIZE); 205 } 206 207 /* 208 * persistent_static_addr_upgrade_to_v2 - checks to see if the 209 * STATIC_ADDR2_ID exists in the persistent store tree. If not 210 * found then it converts the STATIC_ADDR_ID data into the 211 * STATIC_ADDR2_ID format and saves the branch. 212 */ 213 static void 214 persistent_static_addr_upgrade_to_v2() 215 { 216 entry_t e; 217 char *target_name; 218 char *c_end; 219 void *void_p = NULL; 220 221 /* 222 * Check is version 2 of STATIC_ADDR list exists. 223 */ 224 target_name = kmem_zalloc(MAX_KEY_SIZE, KM_SLEEP); 225 persistent_static_addr_lock(); 226 if (nvf_list_check(STATIC_ADDR2_ID) == B_FALSE) { 227 /* 228 * We need to upgrade any existing 229 * STATIC_ADDR data to version 2. Loop 230 * thru all old entries and set new version 231 * values. 232 */ 233 while (nvf_data_next(STATIC_ADDR_ID, &void_p, 234 target_name, (void *)&e, sizeof (e)) == B_TRUE) { 235 /* Convert STATIC_ADDR to STATIC_ADDR2 */ 236 c_end = strchr(target_name, ','); 237 if (c_end == NULL) { 238 continue; 239 } 240 *c_end = '\0'; 241 /* Skip the target whose address size length is 0 */ 242 if (e.e_insize == 0) { 243 continue; 244 } 245 /* Add updated record */ 246 (void) persistent_static_addr_set(target_name, &e); 247 } 248 } 249 persistent_static_addr_unlock(); 250 kmem_free(target_name, MAX_KEY_SIZE); 251 } 252 253 /* 254 * persistent_init -- initialize use of the persistent store 255 */ 256 void 257 persistent_init() 258 { 259 nvf_init(); 260 mutex_init(&static_addr_data_lock, NULL, MUTEX_DRIVER, NULL); 261 mutex_init(&disc_addr_data_lock, NULL, MUTEX_DRIVER, NULL); 262 mutex_init(&isns_addr_data_lock, NULL, MUTEX_DRIVER, NULL); 263 mutex_init(¶m_data_lock, NULL, MUTEX_DRIVER, NULL); 264 mutex_init(&chap_data_lock, NULL, MUTEX_DRIVER, NULL); 265 mutex_init(&auth_data_lock, NULL, MUTEX_DRIVER, NULL); 266 mutex_init(&tunable_data_lock, NULL, MUTEX_DRIVER, NULL); 267 } 268 269 /* 270 * persistent_load -- load the persistent store 271 */ 272 boolean_t 273 persistent_load() 274 { 275 boolean_t rval = B_FALSE; 276 277 rval = nvf_load(); 278 if (rval == B_TRUE) { 279 persistent_init_disc_addr_oids(); 280 persistent_init_static_addr_oids(); 281 } 282 283 return (rval); 284 } 285 286 /* 287 * persistent_fini -- finish using the persistent store 288 */ 289 void 290 persistent_fini(void) 291 { 292 nvf_fini(); 293 294 mutex_destroy(&static_addr_data_lock); 295 mutex_destroy(&disc_addr_data_lock); 296 mutex_destroy(¶m_data_lock); 297 mutex_destroy(&chap_data_lock); 298 mutex_destroy(&auth_data_lock); 299 mutex_destroy(&tunable_data_lock); 300 } 301 302 303 /* 304 * +--------------------------------------------------------------------+ 305 * | Discovery Method Interfaces | 306 * +--------------------------------------------------------------------+ 307 */ 308 309 /* 310 * persistent_disc_meth_set -- enable a specific discovery method 311 */ 312 boolean_t 313 persistent_disc_meth_set(iSCSIDiscoveryMethod_t method) 314 { 315 return (persistent_disc_meth_common(method, B_FALSE)); 316 } 317 318 /* 319 * persistent_disc_meth_get -- return the status of all discovery methods as 320 * found in the persistent store 321 */ 322 iSCSIDiscoveryMethod_t 323 persistent_disc_meth_get(void) 324 { 325 boolean_t rval; 326 iSCSIDiscoveryMethod_t methods; 327 328 rval = nvf_node_value_get(DISCOVERY_METHOD_ID, (uint32_t *)&methods); 329 if (rval == B_FALSE) { 330 methods = iSCSIDiscoveryMethodUnknown; 331 } 332 333 return (methods); 334 } 335 336 /* 337 * persistent_disc_meth_clear -- disable a specific discovery method 338 */ 339 boolean_t 340 persistent_disc_meth_clear(iSCSIDiscoveryMethod_t method) 341 { 342 return (persistent_disc_meth_common(method, B_TRUE)); 343 } 344 345 346 347 /* 348 * persistent_disc_meth_common - common function used to set or clear the 349 * status of a discovery method in the persistent store. 350 */ 351 static boolean_t 352 persistent_disc_meth_common(iSCSIDiscoveryMethod_t method, boolean_t do_clear) 353 { 354 boolean_t rval; 355 iSCSIDiscoveryMethod_t discovery_types = iSCSIDiscoveryMethodUnknown; 356 357 (void) nvf_node_value_get(DISCOVERY_METHOD_ID, 358 (uint32_t *)&discovery_types); 359 if (do_clear) { 360 discovery_types &= ~method; 361 } else { 362 discovery_types |= method; 363 } 364 365 rval = nvf_node_value_set(DISCOVERY_METHOD_ID, discovery_types); 366 367 return (rval); 368 } 369 370 371 372 /* 373 * +--------------------------------------------------------------------+ 374 * | Node/Initiator Name Interfaces | 375 * +--------------------------------------------------------------------+ 376 */ 377 378 /* 379 * persistent_initiator_name_set -- sets the node's initiator name 380 */ 381 boolean_t 382 persistent_initiator_name_set(char *p) 383 { 384 return (nvf_node_name_set(NODE_NAME_ID, p)); 385 } 386 387 /* 388 * persistent_initiator_name_get -- returns the node's initiator name 389 */ 390 boolean_t 391 persistent_initiator_name_get(char *p, int size) 392 { 393 return (nvf_node_name_get(NODE_NAME_ID, p, size)); 394 } 395 396 397 /* 398 * +--------------------------------------------------------------------+ 399 * | Node/Initiator Alias Interfaces | 400 * +--------------------------------------------------------------------+ 401 */ 402 403 /* 404 * persistent_alias_name_set -- sets the node's initiator name alias 405 */ 406 boolean_t 407 persistent_alias_name_set(char *p) 408 { 409 return (nvf_node_name_set(NODE_ALIAS_ID, p)); 410 } 411 412 /* 413 * persistent_initiator_name_get -- returns the node's initiator name alias 414 */ 415 boolean_t 416 persistent_alias_name_get(char *p, int size) 417 { 418 return (nvf_node_name_get(NODE_ALIAS_ID, p, size)); 419 } 420 421 422 /* 423 * +--------------------------------------------------------------------+ 424 * | Static Target Address Interfaces | 425 * +--------------------------------------------------------------------+ 426 */ 427 428 /* 429 * persistent_static_addr_set -- store hostname, IP address, and port 430 * information for a specific target. 431 */ 432 boolean_t 433 persistent_static_addr_set(char *target_name, entry_t *e) 434 { 435 boolean_t rval; 436 char *key; 437 char *ip_str; 438 439 ASSERT(target_name != NULL); 440 ASSERT(e != NULL); 441 ASSERT(mutex_owned(&static_addr_data_lock)); 442 443 key = kmem_zalloc(MAX_KEY_SIZE, KM_SLEEP); 444 ip_str = kmem_zalloc(INET6_ADDRSTRLEN, KM_SLEEP); 445 if (e->e_insize == sizeof (struct in_addr)) 446 iscsi_inet_ntop(AF_INET, &e->e_u.u_in4, ip_str); 447 else 448 iscsi_inet_ntop(AF_INET6, &e->e_u.u_in6, ip_str); 449 450 if (snprintf(key, MAX_KEY_SIZE - 1, "%s,%s:%d,%d", 451 target_name, ip_str, e->e_port, e->e_tpgt) >= MAX_KEY_SIZE) { 452 kmem_free(key, MAX_KEY_SIZE); 453 kmem_free(ip_str, INET6_ADDRSTRLEN); 454 return (B_FALSE); 455 } 456 457 rval = nvf_data_set(STATIC_ADDR2_ID, key, (void *)e, 458 sizeof (entry_t)); 459 460 kmem_free(key, MAX_KEY_SIZE); 461 kmem_free(ip_str, INET6_ADDRSTRLEN); 462 return (rval); 463 } 464 465 /* 466 * persistent_static_addr_next -- get the next target's hostname, IP address, 467 * and port information. 468 * 469 * The first time this function is called, the argument (void **v) 470 * should be a pointer to a value of NULL which causes this function to obtain 471 * the first static target element. 472 * 473 * This function assumes the associated static address lock is held. 474 * 475 * Returns B_TRUE when data is valid. B_FALSE returned when data is 476 * not available (end of configured targets has been reached). 477 * 478 */ 479 boolean_t 480 persistent_static_addr_next(void **v, char *target_name, entry_t *e) 481 { 482 boolean_t rval; 483 char *c_end, *key; 484 485 ASSERT(v != NULL); 486 ASSERT(target_name != NULL); 487 ASSERT(e != NULL); 488 ASSERT(mutex_owned(&static_addr_data_lock)); 489 490 key = kmem_zalloc(MAX_KEY_SIZE, KM_SLEEP); 491 rval = nvf_data_next(STATIC_ADDR2_ID, v, key, 492 (void *)e, sizeof (*e)); 493 494 /* extract target_name */ 495 c_end = strchr(key, ','); 496 if (c_end == NULL) { 497 kmem_free(key, MAX_KEY_SIZE); 498 return (B_FALSE); 499 } 500 *c_end = '\0'; 501 /* copy target name */ 502 (void) strcpy(target_name, key); 503 504 kmem_free(key, MAX_KEY_SIZE); 505 506 return (rval); 507 } 508 509 /* 510 * persistent_static_addr_clear -- remove the next hostname, IP address, and 511 * port information for a specific target from the configured static targets. 512 */ 513 boolean_t 514 persistent_static_addr_clear(uint32_t oid) 515 { 516 boolean_t rval = B_FALSE; 517 void *void_p = NULL; 518 entry_t e; 519 char *key; 520 char *target_name; 521 char *ip_str; 522 523 /* Find the entry based on oid then record the name and tpgt */ 524 target_name = kmem_zalloc(MAX_KEY_SIZE, KM_SLEEP); 525 persistent_static_addr_lock(); 526 while (persistent_static_addr_next( 527 &void_p, target_name, &e) == B_TRUE) { 528 if (e.e_oid == oid) { 529 break; 530 } 531 } 532 533 /* If we found a match clear the entry */ 534 if (e.e_oid == oid) { 535 ip_str = kmem_zalloc(INET6_ADDRSTRLEN, KM_SLEEP); 536 key = kmem_zalloc(MAX_KEY_SIZE, KM_SLEEP); 537 if (e.e_insize == sizeof (struct in_addr)) 538 iscsi_inet_ntop(AF_INET, &e.e_u.u_in4, ip_str); 539 else 540 iscsi_inet_ntop(AF_INET6, &e.e_u.u_in6, ip_str); 541 542 if (snprintf(key, MAX_KEY_SIZE - 1, "%s,%s:%d,%d", 543 target_name, ip_str, e.e_port, e.e_tpgt) >= MAX_KEY_SIZE) { 544 persistent_static_addr_unlock(); 545 kmem_free(key, MAX_KEY_SIZE); 546 kmem_free(ip_str, INET6_ADDRSTRLEN); 547 kmem_free(target_name, MAX_KEY_SIZE); 548 return (B_FALSE); 549 } 550 551 rval = nvf_data_clear(STATIC_ADDR2_ID, key); 552 kmem_free(key, MAX_KEY_SIZE); 553 kmem_free(ip_str, INET6_ADDRSTRLEN); 554 } 555 persistent_static_addr_unlock(); 556 kmem_free(target_name, MAX_KEY_SIZE); 557 558 return (rval); 559 } 560 561 562 /* 563 * persistent_static_addr_lock -- lock access to static targets. This 564 * ensures static targets are unchanged while the lock is held. The 565 * lock should be grabbed while walking through the static targets. 566 */ 567 void 568 persistent_static_addr_lock(void) 569 { 570 mutex_enter(&static_addr_data_lock); 571 } 572 573 /* 574 * persistent_static_addr_unlock -- unlock access to the configured of static 575 * targets. 576 */ 577 void 578 persistent_static_addr_unlock(void) 579 { 580 mutex_exit(&static_addr_data_lock); 581 } 582 583 584 /* 585 * +--------------------------------------------------------------------+ 586 * | ISNS Server Address Interfaces | 587 * +--------------------------------------------------------------------+ 588 */ 589 590 /* 591 * persistent_addr_set -- store entry address information 592 */ 593 boolean_t 594 persistent_isns_addr_set(entry_t *e) 595 { 596 char name[INET6_ADDRSTRLEN]; 597 boolean_t rval; 598 599 /* 600 * Create name from given discovery address - SendTargets discovery 601 * nodes do not have an associated node name. A name is manufactured 602 * from the IP address given. 603 */ 604 if (e->e_insize == sizeof (struct in_addr)) 605 iscsi_inet_ntop(AF_INET, &e->e_u.u_in4, name); 606 else 607 iscsi_inet_ntop(AF_INET6, &e->e_u.u_in6, name); 608 609 mutex_enter(&isns_addr_data_lock); 610 rval = nvf_data_set(ISNS_SERVER_ADDR_ID, name, 611 (void *)e, sizeof (entry_t)); 612 mutex_exit(&isns_addr_data_lock); 613 614 return (rval); 615 } 616 617 /* 618 * persistent_disc_addr_next -- get the next iSCSI discovery node's address 619 * and port information. 620 * 621 * The first time this function is called, the argument (void **v) 622 * should be a pointer to a value of NULL which causes this function to obtain 623 * the first discovery address element. 624 * 625 * This function assumes the associated disccovery address lock is held. 626 * 627 * Returns B_TRUE when data is valid. B_FALSE returned when data is 628 * not available (end of configured discovery addresses has been reached). 629 * 630 */ 631 boolean_t 632 persistent_isns_addr_next(void **v, entry_t *e) 633 { 634 char name[INET6_ADDRSTRLEN]; 635 636 ASSERT(mutex_owned(&isns_addr_data_lock)); 637 638 return (nvf_data_next(ISNS_SERVER_ADDR_ID, v, name, 639 (void *)e, sizeof (*e))); 640 } 641 642 /* 643 * persistent_disc_addr_clear -- remove IP address and port information from 644 * the configured SendTargets discovery nodes. 645 */ 646 boolean_t 647 persistent_isns_addr_clear(entry_t *e) 648 { 649 char name[INET6_ADDRSTRLEN]; 650 boolean_t rval; 651 652 /* 653 * Create name from given discovery address - SendTargets discovery 654 * nodes do not have an associated node name. A name is manufactured 655 * from the IP address given. 656 */ 657 if (e->e_insize == sizeof (struct in_addr)) 658 iscsi_inet_ntop(AF_INET, &e->e_u.u_in4, name); 659 else 660 iscsi_inet_ntop(AF_INET6, &e->e_u.u_in6, name); 661 662 mutex_enter(&static_addr_data_lock); 663 rval = nvf_data_clear(ISNS_SERVER_ADDR_ID, name); 664 mutex_exit(&static_addr_data_lock); 665 666 return (rval); 667 } 668 669 670 /* 671 * persistent_disc_addr_lock -- lock access to the SendTargets discovery 672 * addresses. This ensures discovery addresses are unchanged while the lock 673 * is held. The lock should be grabbed while walking through the discovery 674 * addresses 675 */ 676 void 677 persistent_isns_addr_lock(void) 678 { 679 mutex_enter(&isns_addr_data_lock); 680 } 681 682 /* 683 * persistent_disc_addr_unlock -- unlock access to discovery addresses. 684 */ 685 void 686 persistent_isns_addr_unlock(void) 687 { 688 mutex_exit(&isns_addr_data_lock); 689 } 690 691 /* 692 * +--------------------------------------------------------------------+ 693 * | Discovery Address Interfaces | 694 * +--------------------------------------------------------------------+ 695 */ 696 697 /* 698 * persistent_disc_addr_set -- store IP address, and port information for 699 * for an iSCSI discovery node that provides target information via a 700 * SendTargets response. 701 */ 702 boolean_t 703 persistent_disc_addr_set(entry_t *e) 704 { 705 char name[INET6_ADDRSTRLEN]; 706 boolean_t rval; 707 708 /* 709 * Create name from given discovery address - SendTargets discovery 710 * nodes do not have an associated node name. A name is manufactured 711 * from the IP address given. 712 */ 713 if (e->e_insize == sizeof (struct in_addr)) 714 iscsi_inet_ntop(AF_INET, &e->e_u.u_in4, name); 715 else 716 iscsi_inet_ntop(AF_INET6, &e->e_u.u_in6, name); 717 718 mutex_enter(&disc_addr_data_lock); 719 rval = nvf_data_set(DISCOVERY_ADDR_ID, name, 720 (void *)e, sizeof (entry_t)); 721 mutex_exit(&disc_addr_data_lock); 722 723 return (rval); 724 } 725 726 /* 727 * persistent_disc_addr_next -- get the next iSCSI discovery node's address 728 * and port information. 729 * 730 * The first time this function is called, the argument (void **v) 731 * should be a pointer to a value of NULL which causes this function to obtain 732 * the first discovery address element. 733 * 734 * This function assumes the associated disccovery address lock is held. 735 * 736 * Returns B_TRUE when data is valid. B_FALSE returned when data is 737 * not available (end of configured discovery addresses has been reached). 738 * 739 */ 740 boolean_t 741 persistent_disc_addr_next(void **v, entry_t *e) 742 { 743 char name[INET6_ADDRSTRLEN]; 744 745 ASSERT(mutex_owned(&disc_addr_data_lock)); 746 747 return (nvf_data_next(DISCOVERY_ADDR_ID, v, name, 748 (void *)e, sizeof (*e))); 749 } 750 751 /* 752 * persistent_disc_addr_clear -- remove IP address and port information from 753 * the configured SendTargets discovery nodes. 754 */ 755 boolean_t 756 persistent_disc_addr_clear(entry_t *e) 757 { 758 char name[INET6_ADDRSTRLEN]; 759 boolean_t rval; 760 761 /* 762 * Create name from given discovery address - SendTargets discovery 763 * nodes do not have an associated node name. A name is manufactured 764 * from the IP address given. 765 */ 766 if (e->e_insize == sizeof (struct in_addr)) 767 iscsi_inet_ntop(AF_INET, &e->e_u.u_in4, name); 768 else 769 iscsi_inet_ntop(AF_INET6, &e->e_u.u_in6, name); 770 771 mutex_enter(&static_addr_data_lock); 772 rval = nvf_data_clear(DISCOVERY_ADDR_ID, name); 773 mutex_exit(&static_addr_data_lock); 774 775 return (rval); 776 } 777 778 779 /* 780 * persistent_disc_addr_lock -- lock access to the SendTargets discovery 781 * addresses. This ensures discovery addresses are unchanged while the lock 782 * is held. The lock should be grabbed while walking through the discovery 783 * addresses 784 */ 785 void 786 persistent_disc_addr_lock(void) 787 { 788 mutex_enter(&disc_addr_data_lock); 789 } 790 791 /* 792 * persistent_disc_addr_unlock -- unlock access to discovery addresses. 793 */ 794 void 795 persistent_disc_addr_unlock(void) 796 { 797 mutex_exit(&disc_addr_data_lock); 798 } 799 800 801 /* 802 * +--------------------------------------------------------------------+ 803 * | Login Parameter Interfaces | 804 * +--------------------------------------------------------------------+ 805 */ 806 807 /* 808 * persistent_param_set -- store login parameters for a specific target 809 */ 810 boolean_t 811 persistent_param_set(char *node, persistent_param_t *param) 812 { 813 boolean_t rval; 814 815 mutex_enter(¶m_data_lock); 816 rval = nvf_data_set(LOGIN_PARAMS_ID, node, 817 (void *)param, sizeof (persistent_param_t)); 818 mutex_exit(¶m_data_lock); 819 820 return (rval); 821 } 822 823 /* 824 * persistent_param_get -- obtain login parameters for a specific target 825 */ 826 boolean_t 827 persistent_param_get(char *node, persistent_param_t *param) 828 { 829 return (nvf_data_get(LOGIN_PARAMS_ID, node, 830 (void *)param, sizeof (*param))); 831 } 832 833 /* 834 * persistent_param_next -- get the next target's login parameters. 835 * 836 * The first time this function is called, the argument (void **v) 837 * should be a pointer to a value of NULL which causes this function to obtain 838 * the first target's login parameters. 839 * 840 * This function assumes the associated login parameter lock is held. 841 * 842 * Returns B_TRUE when data in *param is valid. B_FALSE returned when no 843 * more data is available (end of configured target login parameters). 844 */ 845 boolean_t 846 persistent_param_next(void **v, char *node, persistent_param_t *param) 847 { 848 ASSERT(mutex_owned(¶m_data_lock)); 849 850 return (nvf_data_next(LOGIN_PARAMS_ID, v, node, 851 (void *)param, sizeof (*param))); 852 } 853 854 /* 855 * persistent_param_clear -- remove login parameters for a specific target 856 */ 857 boolean_t 858 persistent_param_clear(char *node) 859 { 860 boolean_t rval1, rval2, rval3; 861 862 mutex_enter(¶m_data_lock); 863 rval1 = nvf_data_clear(LOGIN_PARAMS_ID, node); 864 rval2 = nvf_data_clear(SESSION_PARAMS_ID, node); 865 rval3 = nvf_data_clear(TUNABLE_PARAMS_ID, node); 866 mutex_exit(¶m_data_lock); 867 868 return (((rval1 == B_TRUE) || (rval2 == B_TRUE) || (rval3 == B_TRUE)) 869 ? B_TRUE : B_FALSE); 870 } 871 872 /* 873 * persistent_param_lock -- lock access to login parameters. This 874 * ensures the login parameters will be unchanged while the lock is held. 875 * The lock should be grabbed while walking through the login parameters. 876 */ 877 void 878 persistent_param_lock(void) 879 { 880 mutex_enter(¶m_data_lock); 881 } 882 883 /* 884 * persistent_param_unlock -- unlock access to login parameters. 885 */ 886 void 887 persistent_param_unlock(void) 888 { 889 mutex_exit(¶m_data_lock); 890 } 891 892 /* 893 * +--------------------------------------------------------------------+ 894 * | Session Config Interfaces | 895 * +--------------------------------------------------------------------+ 896 */ 897 898 899 /* 900 * persistent_set_config_session -- store configured sessions 901 * for a specific target 902 */ 903 boolean_t 904 persistent_set_config_session(char *node, iscsi_config_sess_t *ics) 905 { 906 boolean_t rval; 907 int size; 908 909 /* 910 * Make ics_out match ics_in. Since when someone gets 911 * this information the in value becomes the out. 912 */ 913 ics->ics_out = ics->ics_in; 914 915 /* calculate size */ 916 size = ISCSI_SESSION_CONFIG_SIZE(ics->ics_in); 917 918 mutex_enter(¶m_data_lock); 919 rval = nvf_data_set(SESSION_PARAMS_ID, node, (void *)ics, size); 920 mutex_exit(¶m_data_lock); 921 922 return (rval); 923 } 924 925 /* 926 * persistent_get_config_session -- obtain configured sessions 927 * for a specific target 928 */ 929 boolean_t 930 persistent_get_config_session(char *node, iscsi_config_sess_t *ics) 931 { 932 boolean_t status; 933 int in; 934 int size; 935 936 ASSERT(ics->ics_in >= 1); 937 938 /* record caller buffer size */ 939 in = ics->ics_in; 940 941 /* Get base config_sess information */ 942 size = ISCSI_SESSION_CONFIG_SIZE(in); 943 status = nvf_data_get(SESSION_PARAMS_ID, node, 944 (void *)ics, size); 945 946 /* reset the in size */ 947 ics->ics_in = in; 948 949 return (status); 950 } 951 952 /* 953 * persistent_get_tunable_param -- obtain tunable parameters 954 * for a specific target 955 */ 956 boolean_t 957 persistent_get_tunable_param(char *node, persistent_tunable_param_t *tpsg) 958 { 959 return (nvf_data_get(TUNABLE_PARAMS_ID, node, 960 (void *)tpsg, sizeof (persistent_tunable_param_t))); 961 } 962 963 /* 964 * persistent_set_tunable_param -- store tunable parameters 965 * for a specific target 966 */ 967 boolean_t 968 persistent_set_tunable_param(char *node, persistent_tunable_param_t *tpss) 969 { 970 boolean_t rval; 971 mutex_enter(&tunable_data_lock); 972 rval = nvf_data_set(TUNABLE_PARAMS_ID, node, 973 (void *)tpss, sizeof (persistent_tunable_param_t)); 974 mutex_exit(&tunable_data_lock); 975 return (rval); 976 } 977 978 /* 979 * +--------------------------------------------------------------------+ 980 * | CHAP Parameter Interfaces | 981 * +--------------------------------------------------------------------+ 982 */ 983 984 /* 985 * persistent_chap_set -- store CHAP parameters for a specific target 986 */ 987 boolean_t 988 persistent_chap_set(char *node, iscsi_chap_props_t *chap) 989 { 990 boolean_t rval; 991 992 mutex_enter(&chap_data_lock); 993 rval = nvf_data_set(CHAP_PARAMS_ID, node, 994 (void *)chap, sizeof (iscsi_chap_props_t)); 995 mutex_exit(&chap_data_lock); 996 997 return (rval); 998 } 999 1000 /* 1001 * persistent_chap_get -- obtain CHAP parameters for a specific target 1002 */ 1003 boolean_t 1004 persistent_chap_get(char *node, iscsi_chap_props_t *chap) 1005 { 1006 return (nvf_data_get(CHAP_PARAMS_ID, node, 1007 (void *)chap, sizeof (*chap))); 1008 } 1009 1010 /* 1011 * persistent_chap_next -- copy the next target's chap parameters. 1012 * 1013 * The first time this function is called, the argument (void **v) 1014 * should be a pointer to a value of NULL which causes this function to obtain 1015 * the first target's login parameters. 1016 * 1017 * This function assumes the associated chap parameter lock is held. 1018 * 1019 * Returns B_TRUE when data in *param is valid. B_FALSE returned when no 1020 * more data is available. 1021 */ 1022 boolean_t 1023 persistent_chap_next(void **v, char *node, iscsi_chap_props_t *chap) 1024 { 1025 ASSERT(mutex_owned(&chap_data_lock)); 1026 1027 return (nvf_data_next(CHAP_PARAMS_ID, v, node, 1028 (void *)chap, sizeof (*chap))); 1029 } 1030 1031 /* 1032 * persistent_chap_clear -- remove CHAP parameters for a specific target 1033 */ 1034 boolean_t 1035 persistent_chap_clear(char *node) 1036 { 1037 boolean_t rval; 1038 1039 mutex_enter(&chap_data_lock); 1040 rval = nvf_data_clear(CHAP_PARAMS_ID, node); 1041 mutex_exit(&chap_data_lock); 1042 1043 return (rval); 1044 } 1045 1046 /* 1047 * persistent_chap_lock -- lock access to chap parameters. This 1048 * ensures the chap parameters will be unchanged while the lock is held. 1049 * The lock should be grabbed while walking through the chap parameters. 1050 */ 1051 void 1052 persistent_chap_lock(void) 1053 { 1054 mutex_enter(&chap_data_lock); 1055 } 1056 1057 /* 1058 * persistent_chap_unlock -- unlock access to chap parameters. 1059 */ 1060 void 1061 persistent_chap_unlock(void) 1062 { 1063 mutex_exit(&chap_data_lock); 1064 } 1065 1066 1067 /* 1068 * +--------------------------------------------------------------------+ 1069 * | RADIUS Configuration Interfaces | 1070 * +--------------------------------------------------------------------+ 1071 */ 1072 1073 /* 1074 * persistent_radius_set -- stores the RADIUS configuration info 1075 */ 1076 boolean_t 1077 persistent_radius_set(iscsi_radius_props_t *radius) 1078 { 1079 return (nvf_node_data_set(RADIUS_PARAMS_ID, (void *)radius, 1080 sizeof (iscsi_radius_props_t))); 1081 } 1082 1083 /* 1084 * persistent_radius_get -- obtain the RADIUS configuration info 1085 */ 1086 iscsi_nvfile_status_t 1087 persistent_radius_get(iscsi_radius_props_t *radius) 1088 { 1089 return (nvf_node_data_get(RADIUS_PARAMS_ID, 1090 (void *)radius, sizeof (*radius))); 1091 } 1092 1093 1094 /* 1095 * +--------------------------------------------------------------------+ 1096 * | Authentication Configuration Interface | 1097 * +--------------------------------------------------------------------+ 1098 */ 1099 1100 /* 1101 * persistent_auth_set -- stores the bidirectional authentication settings 1102 * for a specific target 1103 */ 1104 boolean_t 1105 persistent_auth_set(char *node, iscsi_auth_props_t *auth) 1106 { 1107 boolean_t rval; 1108 1109 mutex_enter(&auth_data_lock); 1110 rval = nvf_data_set(BIDIR_AUTH_PARAMS_ID, node, 1111 (void *)auth, sizeof (iscsi_auth_props_t)); 1112 mutex_exit(&auth_data_lock); 1113 1114 return (rval); 1115 } 1116 1117 /* 1118 * persistent_auth_get -- gets the bidirectional authentication settings 1119 * for a specific target 1120 */ 1121 boolean_t 1122 persistent_auth_get(char *node, iscsi_auth_props_t *auth) 1123 { 1124 return (nvf_data_get(BIDIR_AUTH_PARAMS_ID, node, 1125 (void *)auth, sizeof (*auth))); 1126 } 1127 1128 /* 1129 * persistent_auth_next -- get the next target's bidirectional authentication 1130 * parameters. 1131 * 1132 * The first time this function is called, the argument (void **v) 1133 * should be a pointer to a value of NULL which causes this function to obtain 1134 * the first target's login parameters. 1135 * 1136 * This function assumes the associated bidirectional authentication lock is 1137 * held. 1138 * 1139 * Returns B_TRUE when data in *param is valid. B_FALSE returned when no 1140 * more data is available. 1141 */ 1142 boolean_t 1143 persistent_auth_next(void **v, char *node, iscsi_auth_props_t *auth) 1144 { 1145 ASSERT(mutex_owned(&auth_data_lock)); 1146 1147 return (nvf_data_next(BIDIR_AUTH_PARAMS_ID, v, node, 1148 (void *)auth, sizeof (*auth))); 1149 } 1150 1151 /* 1152 * persistent_auth_clear -- remove bidirectional authentication parameters for 1153 * a specific target 1154 */ 1155 boolean_t 1156 persistent_auth_clear(char *node) 1157 { 1158 boolean_t rval; 1159 1160 mutex_enter(&auth_data_lock); 1161 rval = nvf_data_clear(BIDIR_AUTH_PARAMS_ID, node); 1162 mutex_exit(&auth_data_lock); 1163 1164 return (rval); 1165 } 1166 1167 /* 1168 * persistent_auth_lock -- lock access to bidirectional authentication 1169 * parameters. This ensures the authentication parameters will be unchanged 1170 * while the lock is held. The lock should be grabbed while walking through 1171 * the authentication parameters. 1172 */ 1173 void 1174 persistent_auth_lock(void) 1175 { 1176 mutex_enter(&auth_data_lock); 1177 } 1178 1179 /* 1180 * persistent_auth_unlock -- unlock access to bidirectional authentication 1181 * parameters. 1182 */ 1183 void 1184 persistent_auth_unlock(void) 1185 { 1186 mutex_exit(&auth_data_lock); 1187 } 1188 1189 1190 /* 1191 * +--------------------------------------------------------------------+ 1192 * | Debug Functions | 1193 * +--------------------------------------------------------------------+ 1194 */ 1195 1196 #define BITBUF_LEN 128 1197 1198 /* 1199 * persistent_dump_data -- dump contents of persistent store 1200 */ 1201 void 1202 persistent_dump_data(void) 1203 { 1204 boolean_t rval; 1205 char *name; 1206 iSCSIDiscoveryMethod_t methods; 1207 char *bitbuf; 1208 iscsi_radius_props_t *radius; 1209 entry_t *entry; 1210 void *v; 1211 char *addr_buf; 1212 persistent_param_t *param; 1213 uint32_t param_id; 1214 char *param_name; 1215 iscsi_chap_props_t *chap; 1216 iscsi_auth_props_t *auth; 1217 1218 name = (char *)kmem_alloc(ISCSI_MAX_NAME_LEN, KM_SLEEP); 1219 addr_buf = (char *)kmem_alloc(INET6_ADDRSTRLEN, KM_SLEEP); 1220 bitbuf = (char *)kmem_alloc(BITBUF_LEN, KM_SLEEP); 1221 1222 rval = persistent_initiator_name_get(name, ISCSI_MAX_NAME_LEN); 1223 if (rval == B_TRUE) { 1224 cmn_err(CE_CONT, " Node Name: %s\n", name); 1225 } 1226 1227 rval = persistent_alias_name_get(name, ISCSI_MAX_NAME_LEN); 1228 if (rval == B_TRUE) { 1229 cmn_err(CE_CONT, " Node Alias: %s\n", name); 1230 } 1231 1232 methods = persistent_disc_meth_get(); 1233 if (methods != iSCSIDiscoveryMethodUnknown) { 1234 cmn_err(CE_CONT, " Methods: <%s>\n", 1235 prt_bitmap(methods, 1236 "\003SendTarget\002iSNS\001SLP\000Static", 1237 bitbuf, BITBUF_LEN)); 1238 } 1239 1240 radius = (iscsi_radius_props_t *)kmem_alloc(sizeof (*radius), 1241 KM_SLEEP); 1242 if (persistent_radius_get(radius) == ISCSI_NVFILE_SUCCESS) { 1243 cmn_err(CE_CONT, " <------ RADIUS Configuration ------>\n"); 1244 if (radius->r_insize == sizeof (struct in_addr)) { 1245 (void) inet_ntop(AF_INET, &radius->r_addr.u_in4, 1246 addr_buf, INET6_ADDRSTRLEN); 1247 } else { 1248 (void) inet_ntop(AF_INET6, &radius->r_addr.u_in6, 1249 addr_buf, INET6_ADDRSTRLEN); 1250 } 1251 cmn_err(CE_CONT, " IP: %s, port %d\n", addr_buf, 1252 radius->r_port); 1253 } 1254 kmem_free(radius, sizeof (*radius)); 1255 1256 entry = (entry_t *)kmem_alloc(sizeof (*entry), KM_SLEEP); 1257 v = NULL; 1258 cmn_err(CE_CONT, 1259 " <------ Static Target Discovery Addresses ------>\n"); 1260 persistent_static_addr_lock(); 1261 while (persistent_static_addr_next(&v, name, entry) == B_TRUE) { 1262 cmn_err(CE_CONT, " Target Name: %s TPGT: %d\n", 1263 name, entry->e_tpgt); 1264 if (entry->e_insize == sizeof (struct in_addr)) { 1265 (void) inet_ntop(AF_INET, &entry->e_u.u_in4, 1266 addr_buf, INET6_ADDRSTRLEN); 1267 } else { 1268 (void) inet_ntop(AF_INET6, &entry->e_u.u_in6, 1269 addr_buf, INET6_ADDRSTRLEN); 1270 } 1271 cmn_err(CE_CONT, 1272 " IP: %s, port %d\n", addr_buf, entry->e_port); 1273 } 1274 persistent_static_addr_unlock(); 1275 1276 v = NULL; 1277 cmn_err(CE_CONT, 1278 " <------ SendTargets Discovery Addresses ------>\n"); 1279 persistent_disc_addr_lock(); 1280 while (persistent_disc_addr_next(&v, entry) == B_TRUE) { 1281 if (entry->e_insize == sizeof (struct in_addr)) { 1282 (void) inet_ntop(AF_INET, &entry->e_u.u_in4, 1283 addr_buf, INET6_ADDRSTRLEN); 1284 } else { 1285 (void) inet_ntop(AF_INET6, &entry->e_u.u_in6, 1286 addr_buf, INET6_ADDRSTRLEN); 1287 } 1288 cmn_err(CE_CONT, 1289 " IP: %s, port %d\n", addr_buf, entry->e_port); 1290 } 1291 persistent_disc_addr_unlock(); 1292 1293 v = NULL; 1294 cmn_err(CE_CONT, 1295 " <------ ISNS Server Discovery Addresses ------>\n"); 1296 persistent_isns_addr_lock(); 1297 while (persistent_isns_addr_next(&v, entry) == B_TRUE) { 1298 if (entry->e_insize == sizeof (struct in_addr)) { 1299 (void) inet_ntop(AF_INET, &entry->e_u.u_in4, 1300 addr_buf, INET6_ADDRSTRLEN); 1301 } else { 1302 (void) inet_ntop(AF_INET6, &entry->e_u.u_in6, 1303 addr_buf, INET6_ADDRSTRLEN); 1304 } 1305 cmn_err(CE_CONT, 1306 " IP: %s, port %d\n", addr_buf, entry->e_port); 1307 } 1308 persistent_isns_addr_unlock(); 1309 kmem_free(entry, sizeof (*entry)); 1310 1311 param = (persistent_param_t *)kmem_alloc(sizeof (*param), KM_SLEEP); 1312 v = NULL; 1313 cmn_err(CE_CONT, " <------ Overriden Login Parameters ------>\n"); 1314 persistent_param_lock(); 1315 while (persistent_param_next(&v, name, param) == B_TRUE) { 1316 cmn_err(CE_CONT, " Host: %s\n", name); 1317 cmn_err(CE_CONT, " Bitmap: <%s>\n", 1318 prt_bitmap(param->p_bitmap, 1319 "\015DDIG\014HDIG\013SEGLEN\012OUT_R2T\011" 1320 "DATAPDU\010MAXCONN\007BURST\006R2T\005" 1321 "IMMDATA\004FIRSTBURST\003LEVEL\002T2WAIT" 1322 "\001T2RETAIN\000SEQIN", bitbuf, BITBUF_LEN)); 1323 for (param_id = 0; param_id < ISCSI_NUM_LOGIN_PARAM; 1324 param_id++) { 1325 if (param->p_bitmap & (1 << param_id)) { 1326 param_name = utils_map_param(param_id); 1327 if (param_name == NULL) { 1328 param_name = "Param_Not_Found"; 1329 } 1330 switch (param_id) { 1331 case ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER: 1332 cmn_err(CE_CONT, " %s = %s", 1333 param_name, (param->p_params. 1334 data_sequence_in_order == B_TRUE) ? 1335 "True" : "False"); 1336 break; 1337 case ISCSI_LOGIN_PARAM_INITIAL_R2T: 1338 cmn_err(CE_CONT, " %s = %s", 1339 param_name, (param->p_params. 1340 initial_r2t == B_TRUE) ? 1341 "True" : "False"); 1342 break; 1343 case ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER: 1344 cmn_err(CE_CONT, " %s = %s", 1345 param_name, (param->p_params. 1346 data_pdu_in_order == B_TRUE) ? 1347 "True" : "False"); 1348 break; 1349 case ISCSI_LOGIN_PARAM_HEADER_DIGEST: 1350 cmn_err(CE_CONT, " %s = %d", 1351 param_name, param->p_params. 1352 header_digest); 1353 break; 1354 case ISCSI_LOGIN_PARAM_DATA_DIGEST: 1355 cmn_err(CE_CONT, " %s = %d", 1356 param_name, param->p_params. 1357 data_digest); 1358 break; 1359 case ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN: 1360 cmn_err(CE_CONT, " %s = %d", 1361 param_name, param->p_params. 1362 default_time_to_retain); 1363 break; 1364 case ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT: 1365 cmn_err(CE_CONT, " %s = %d", 1366 param_name, param->p_params. 1367 default_time_to_wait); 1368 break; 1369 case ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH: 1370 cmn_err(CE_CONT, " %s = %d", 1371 param_name, param->p_params. 1372 max_recv_data_seg_len); 1373 break; 1374 case ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH: 1375 cmn_err(CE_CONT, " %s = %d", 1376 param_name, param->p_params. 1377 first_burst_length); 1378 break; 1379 case ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH: 1380 cmn_err(CE_CONT, " %s = %d", 1381 param_name, param->p_params. 1382 max_burst_length); 1383 break; 1384 case ISCSI_LOGIN_PARAM_MAX_CONNECTIONS: 1385 cmn_err(CE_CONT, " %s = %d", 1386 param_name, param->p_params. 1387 max_connections); 1388 break; 1389 case ISCSI_LOGIN_PARAM_OUTSTANDING_R2T: 1390 cmn_err(CE_CONT, " %s = %d", 1391 param_name, param->p_params. 1392 max_outstanding_r2t); 1393 break; 1394 case ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL: 1395 cmn_err(CE_CONT, " %s = %d", 1396 param_name, param->p_params. 1397 error_recovery_level); 1398 break; 1399 default: 1400 break; 1401 } 1402 } 1403 } 1404 } 1405 persistent_param_unlock(); 1406 kmem_free(param, sizeof (*param)); 1407 1408 chap = (iscsi_chap_props_t *)kmem_alloc(sizeof (*chap), KM_SLEEP); 1409 v = NULL; 1410 cmn_err(CE_CONT, " <------ Chap Parameters ------>\n"); 1411 persistent_chap_lock(); 1412 while (persistent_chap_next(&v, name, chap) == B_TRUE) { 1413 cmn_err(CE_CONT, " Host: %s\n", name); 1414 cmn_err(CE_CONT, " User: %s Secret: %s\n", 1415 chap->c_user, chap->c_secret); 1416 } 1417 persistent_chap_unlock(); 1418 kmem_free(chap, sizeof (*chap)); 1419 1420 auth = (iscsi_auth_props_t *)kmem_alloc(sizeof (*auth), KM_SLEEP); 1421 v = NULL; 1422 cmn_err(CE_CONT, " <------ Bidirectional Authentication ------>\n"); 1423 persistent_auth_lock(); 1424 while (persistent_auth_next(&v, name, auth) == B_TRUE) { 1425 cmn_err(CE_CONT, " Host: %s\n", name); 1426 cmn_err(CE_CONT, " Bidir Auth = %s\n", 1427 (auth->a_bi_auth == B_TRUE) ? "True" : "False"); 1428 } 1429 persistent_auth_unlock(); 1430 kmem_free(auth, sizeof (*auth)); 1431 1432 1433 kmem_free(bitbuf, BITBUF_LEN); 1434 kmem_free(addr_buf, INET6_ADDRSTRLEN); 1435 kmem_free(name, ISCSI_MAX_NAME_LEN); 1436 } 1437