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