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
iscsi_inet_ntop(int af,const void * addr,char * buf)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
persistent_init_disc_addr_oids()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
persistent_init_static_addr_oids()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
persistent_static_addr_upgrade_to_v2()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
persistent_init()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
persistent_load()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
persistent_fini(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
persistent_disc_meth_set(iSCSIDiscoveryMethod_t method)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
persistent_disc_meth_get(void)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
persistent_disc_meth_clear(iSCSIDiscoveryMethod_t method)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
persistent_disc_meth_common(iSCSIDiscoveryMethod_t method,boolean_t do_clear)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
persistent_initiator_name_set(char * p)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
persistent_initiator_name_get(char * p,int size)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
persistent_alias_name_set(char * p)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
persistent_alias_name_get(char * p,int size)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
persistent_static_addr_set(char * target_name,entry_t * e)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
persistent_static_addr_next(void ** v,char * target_name,entry_t * e)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
persistent_static_addr_clear(uint32_t oid)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
persistent_static_addr_lock(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
persistent_static_addr_unlock(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
persistent_isns_addr_set(entry_t * e)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
persistent_isns_addr_next(void ** v,entry_t * e)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
persistent_isns_addr_clear(entry_t * e)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
persistent_isns_addr_lock(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
persistent_isns_addr_unlock(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
persistent_disc_addr_set(entry_t * e)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
persistent_disc_addr_next(void ** v,entry_t * e)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
persistent_disc_addr_clear(entry_t * e)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
persistent_disc_addr_lock(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
persistent_disc_addr_unlock(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
persistent_param_set(char * node,persistent_param_t * param)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
persistent_param_get(char * node,persistent_param_t * param)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
persistent_param_next(void ** v,char * node,persistent_param_t * param)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
persistent_param_clear(char * node)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
persistent_param_lock(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
persistent_param_unlock(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
persistent_set_config_session(char * node,iscsi_config_sess_t * ics)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
persistent_get_config_session(char * node,iscsi_config_sess_t * ics)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
persistent_get_tunable_param(char * node,persistent_tunable_param_t * tpsg)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
persistent_set_tunable_param(char * node,persistent_tunable_param_t * tpss)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
persistent_chap_set(char * node,iscsi_chap_props_t * chap)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
persistent_chap_get(char * node,iscsi_chap_props_t * chap)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
persistent_chap_next(void ** v,char * node,iscsi_chap_props_t * chap)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
persistent_chap_clear(char * node)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
persistent_chap_lock(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
persistent_chap_unlock(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
persistent_radius_set(iscsi_radius_props_t * radius)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
persistent_radius_get(iscsi_radius_props_t * radius)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
persistent_auth_set(char * node,iscsi_auth_props_t * auth)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
persistent_auth_get(char * node,iscsi_auth_props_t * auth)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
persistent_auth_next(void ** v,char * node,iscsi_auth_props_t * auth)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
persistent_auth_clear(char * node)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
persistent_auth_lock(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
persistent_auth_unlock(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
persistent_dump_data(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