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