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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
28 #include "persistent.h"
29 #include <sys/scsi/adapters/iscsi_if.h>
30 #include <netinet/in.h>
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).
36 #define MAX_KEY_SIZE (ISCSI_MAX_NAME_LEN + 5)
39 * Name identifiers for the various types of data
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"
56 * Local Global Variables
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
;
66 * Local Function Prototypes
68 static boolean_t
persistent_disc_meth_common(iSCSIDiscoveryMethod_t method
,
70 static void persistent_static_addr_upgrade_to_v2();
73 * This wrapper keeps old inet_ntop() behaviour and should be called when
74 * IP addresses are used as keys into persistent storage.
77 iscsi_inet_ntop(int af
, const void *addr
, char *buf
)
79 #define UC(b) (((int)b) & 0xff)
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]));
85 (void) inet_ntop(af
, addr
, buf
, INET6_ADDRSTRLEN
);
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.
96 persistent_init_disc_addr_oids()
98 uint32_t addr_count
= 0;
101 uint32_t i
, curr_count
;
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
110 persistent_disc_addr_lock();
111 while (persistent_disc_addr_next(&void_p
, &e
) == B_TRUE
) {
114 persistent_disc_addr_unlock();
116 for (i
= 0; i
< addr_count
; i
++) {
120 persistent_disc_addr_lock();
122 /* Use curr_count to skip previously updated addresses */
123 while (persistent_disc_addr_next(&void_p
, &e
) ==
124 B_TRUE
&& i
< curr_count
) {
127 persistent_disc_addr_unlock();
129 mutex_enter(&iscsi_oid_mutex
);
130 e
.e_oid
= iscsi_oid
++;
131 mutex_exit(&iscsi_oid_mutex
);
133 if (persistent_disc_addr_set(&e
) == B_FALSE
) {
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.
145 persistent_init_static_addr_oids()
147 uint32_t addr_count
= 0;
150 uint32_t i
, curr_count
;
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.
162 persistent_static_addr_upgrade_to_v2();
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
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
) ==
178 for (i
= 0; i
< addr_count
; i
++) {
183 /* Use curr_count to skip previously updated addresses */
184 while ((persistent_static_addr_next(
185 &void_p
, target_name
, &e
) == B_TRUE
) &&
190 /* Skip the target whose address size length is 0 */
191 if (e
.e_insize
== 0) {
195 mutex_enter(&iscsi_oid_mutex
);
196 e
.e_oid
= iscsi_oid
++;
197 mutex_exit(&iscsi_oid_mutex
);
199 if (persistent_static_addr_set(target_name
, &e
) == B_FALSE
) {
203 persistent_static_addr_unlock();
204 kmem_free(target_name
, MAX_KEY_SIZE
);
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.
214 persistent_static_addr_upgrade_to_v2()
222 * Check is version 2 of STATIC_ADDR list exists.
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
) {
228 * We need to upgrade any existing
229 * STATIC_ADDR data to version 2. Loop
230 * thru all old entries and set new version
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
, ',');
241 /* Skip the target whose address size length is 0 */
242 if (e
.e_insize
== 0) {
245 /* Add updated record */
246 (void) persistent_static_addr_set(target_name
, &e
);
249 persistent_static_addr_unlock();
250 kmem_free(target_name
, MAX_KEY_SIZE
);
254 * persistent_init -- initialize use of the persistent store
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
);
270 * persistent_load -- load the persistent store
275 boolean_t rval
= B_FALSE
;
278 if (rval
== B_TRUE
) {
279 persistent_init_disc_addr_oids();
280 persistent_init_static_addr_oids();
287 * persistent_fini -- finish using the persistent store
290 persistent_fini(void)
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
);
304 * +--------------------------------------------------------------------+
305 * | Discovery Method Interfaces |
306 * +--------------------------------------------------------------------+
310 * persistent_disc_meth_set -- enable a specific discovery method
313 persistent_disc_meth_set(iSCSIDiscoveryMethod_t method
)
315 return (persistent_disc_meth_common(method
, B_FALSE
));
319 * persistent_disc_meth_get -- return the status of all discovery methods as
320 * found in the persistent store
322 iSCSIDiscoveryMethod_t
323 persistent_disc_meth_get(void)
326 iSCSIDiscoveryMethod_t methods
;
328 rval
= nvf_node_value_get(DISCOVERY_METHOD_ID
, (uint32_t *)&methods
);
329 if (rval
== B_FALSE
) {
330 methods
= iSCSIDiscoveryMethodUnknown
;
337 * persistent_disc_meth_clear -- disable a specific discovery method
340 persistent_disc_meth_clear(iSCSIDiscoveryMethod_t method
)
342 return (persistent_disc_meth_common(method
, B_TRUE
));
348 * persistent_disc_meth_common - common function used to set or clear the
349 * status of a discovery method in the persistent store.
352 persistent_disc_meth_common(iSCSIDiscoveryMethod_t method
, boolean_t do_clear
)
355 iSCSIDiscoveryMethod_t discovery_types
= iSCSIDiscoveryMethodUnknown
;
357 (void) nvf_node_value_get(DISCOVERY_METHOD_ID
,
358 (uint32_t *)&discovery_types
);
360 discovery_types
&= ~method
;
362 discovery_types
|= method
;
365 rval
= nvf_node_value_set(DISCOVERY_METHOD_ID
, discovery_types
);
373 * +--------------------------------------------------------------------+
374 * | Node/Initiator Name Interfaces |
375 * +--------------------------------------------------------------------+
379 * persistent_initiator_name_set -- sets the node's initiator name
382 persistent_initiator_name_set(char *p
)
384 return (nvf_node_name_set(NODE_NAME_ID
, p
));
388 * persistent_initiator_name_get -- returns the node's initiator name
391 persistent_initiator_name_get(char *p
, int size
)
393 return (nvf_node_name_get(NODE_NAME_ID
, p
, size
));
398 * +--------------------------------------------------------------------+
399 * | Node/Initiator Alias Interfaces |
400 * +--------------------------------------------------------------------+
404 * persistent_alias_name_set -- sets the node's initiator name alias
407 persistent_alias_name_set(char *p
)
409 return (nvf_node_name_set(NODE_ALIAS_ID
, p
));
413 * persistent_initiator_name_get -- returns the node's initiator name alias
416 persistent_alias_name_get(char *p
, int size
)
418 return (nvf_node_name_get(NODE_ALIAS_ID
, p
, size
));
423 * +--------------------------------------------------------------------+
424 * | Static Target Address Interfaces |
425 * +--------------------------------------------------------------------+
429 * persistent_static_addr_set -- store hostname, IP address, and port
430 * information for a specific target.
433 persistent_static_addr_set(char *target_name
, entry_t
*e
)
439 ASSERT(target_name
!= NULL
);
441 ASSERT(mutex_owned(&static_addr_data_lock
));
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
);
448 iscsi_inet_ntop(AF_INET6
, &e
->e_u
.u_in6
, ip_str
);
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
);
457 rval
= nvf_data_set(STATIC_ADDR2_ID
, key
, (void *)e
,
460 kmem_free(key
, MAX_KEY_SIZE
);
461 kmem_free(ip_str
, INET6_ADDRSTRLEN
);
466 * persistent_static_addr_next -- get the next target's hostname, IP address,
467 * and port information.
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.
473 * This function assumes the associated static address lock is held.
475 * Returns B_TRUE when data is valid. B_FALSE returned when data is
476 * not available (end of configured targets has been reached).
480 persistent_static_addr_next(void **v
, char *target_name
, entry_t
*e
)
486 ASSERT(target_name
!= NULL
);
488 ASSERT(mutex_owned(&static_addr_data_lock
));
490 key
= kmem_zalloc(MAX_KEY_SIZE
, KM_SLEEP
);
491 rval
= nvf_data_next(STATIC_ADDR2_ID
, v
, key
,
492 (void *)e
, sizeof (*e
));
494 /* extract target_name */
495 c_end
= strchr(key
, ',');
497 kmem_free(key
, MAX_KEY_SIZE
);
501 /* copy target name */
502 (void) strcpy(target_name
, key
);
504 kmem_free(key
, MAX_KEY_SIZE
);
510 * persistent_static_addr_clear -- remove the next hostname, IP address, and
511 * port information for a specific target from the configured static targets.
514 persistent_static_addr_clear(uint32_t oid
)
516 boolean_t rval
= B_FALSE
;
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
) {
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
);
540 iscsi_inet_ntop(AF_INET6
, &e
.e_u
.u_in6
, ip_str
);
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
);
551 rval
= nvf_data_clear(STATIC_ADDR2_ID
, key
);
552 kmem_free(key
, MAX_KEY_SIZE
);
553 kmem_free(ip_str
, INET6_ADDRSTRLEN
);
555 persistent_static_addr_unlock();
556 kmem_free(target_name
, MAX_KEY_SIZE
);
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.
568 persistent_static_addr_lock(void)
570 mutex_enter(&static_addr_data_lock
);
574 * persistent_static_addr_unlock -- unlock access to the configured of static
578 persistent_static_addr_unlock(void)
580 mutex_exit(&static_addr_data_lock
);
585 * +--------------------------------------------------------------------+
586 * | ISNS Server Address Interfaces |
587 * +--------------------------------------------------------------------+
591 * persistent_addr_set -- store entry address information
594 persistent_isns_addr_set(entry_t
*e
)
596 char name
[INET6_ADDRSTRLEN
];
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.
604 if (e
->e_insize
== sizeof (struct in_addr
))
605 iscsi_inet_ntop(AF_INET
, &e
->e_u
.u_in4
, name
);
607 iscsi_inet_ntop(AF_INET6
, &e
->e_u
.u_in6
, name
);
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
);
618 * persistent_disc_addr_next -- get the next iSCSI discovery node's address
619 * and port information.
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.
625 * This function assumes the associated disccovery address lock is held.
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).
632 persistent_isns_addr_next(void **v
, entry_t
*e
)
634 char name
[INET6_ADDRSTRLEN
];
636 ASSERT(mutex_owned(&isns_addr_data_lock
));
638 return (nvf_data_next(ISNS_SERVER_ADDR_ID
, v
, name
,
639 (void *)e
, sizeof (*e
)));
643 * persistent_disc_addr_clear -- remove IP address and port information from
644 * the configured SendTargets discovery nodes.
647 persistent_isns_addr_clear(entry_t
*e
)
649 char name
[INET6_ADDRSTRLEN
];
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.
657 if (e
->e_insize
== sizeof (struct in_addr
))
658 iscsi_inet_ntop(AF_INET
, &e
->e_u
.u_in4
, name
);
660 iscsi_inet_ntop(AF_INET6
, &e
->e_u
.u_in6
, name
);
662 mutex_enter(&static_addr_data_lock
);
663 rval
= nvf_data_clear(ISNS_SERVER_ADDR_ID
, name
);
664 mutex_exit(&static_addr_data_lock
);
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
677 persistent_isns_addr_lock(void)
679 mutex_enter(&isns_addr_data_lock
);
683 * persistent_disc_addr_unlock -- unlock access to discovery addresses.
686 persistent_isns_addr_unlock(void)
688 mutex_exit(&isns_addr_data_lock
);
692 * +--------------------------------------------------------------------+
693 * | Discovery Address Interfaces |
694 * +--------------------------------------------------------------------+
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.
703 persistent_disc_addr_set(entry_t
*e
)
705 char name
[INET6_ADDRSTRLEN
];
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.
713 if (e
->e_insize
== sizeof (struct in_addr
))
714 iscsi_inet_ntop(AF_INET
, &e
->e_u
.u_in4
, name
);
716 iscsi_inet_ntop(AF_INET6
, &e
->e_u
.u_in6
, name
);
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
);
727 * persistent_disc_addr_next -- get the next iSCSI discovery node's address
728 * and port information.
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.
734 * This function assumes the associated disccovery address lock is held.
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).
741 persistent_disc_addr_next(void **v
, entry_t
*e
)
743 char name
[INET6_ADDRSTRLEN
];
745 ASSERT(mutex_owned(&disc_addr_data_lock
));
747 return (nvf_data_next(DISCOVERY_ADDR_ID
, v
, name
,
748 (void *)e
, sizeof (*e
)));
752 * persistent_disc_addr_clear -- remove IP address and port information from
753 * the configured SendTargets discovery nodes.
756 persistent_disc_addr_clear(entry_t
*e
)
758 char name
[INET6_ADDRSTRLEN
];
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.
766 if (e
->e_insize
== sizeof (struct in_addr
))
767 iscsi_inet_ntop(AF_INET
, &e
->e_u
.u_in4
, name
);
769 iscsi_inet_ntop(AF_INET6
, &e
->e_u
.u_in6
, name
);
771 mutex_enter(&static_addr_data_lock
);
772 rval
= nvf_data_clear(DISCOVERY_ADDR_ID
, name
);
773 mutex_exit(&static_addr_data_lock
);
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
786 persistent_disc_addr_lock(void)
788 mutex_enter(&disc_addr_data_lock
);
792 * persistent_disc_addr_unlock -- unlock access to discovery addresses.
795 persistent_disc_addr_unlock(void)
797 mutex_exit(&disc_addr_data_lock
);
802 * +--------------------------------------------------------------------+
803 * | Login Parameter Interfaces |
804 * +--------------------------------------------------------------------+
808 * persistent_param_set -- store login parameters for a specific target
811 persistent_param_set(char *node
, persistent_param_t
*param
)
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
);
824 * persistent_param_get -- obtain login parameters for a specific target
827 persistent_param_get(char *node
, persistent_param_t
*param
)
829 return (nvf_data_get(LOGIN_PARAMS_ID
, node
,
830 (void *)param
, sizeof (*param
)));
834 * persistent_param_next -- get the next target's login parameters.
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.
840 * This function assumes the associated login parameter lock is held.
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).
846 persistent_param_next(void **v
, char *node
, persistent_param_t
*param
)
848 ASSERT(mutex_owned(¶m_data_lock
));
850 return (nvf_data_next(LOGIN_PARAMS_ID
, v
, node
,
851 (void *)param
, sizeof (*param
)));
855 * persistent_param_clear -- remove login parameters for a specific target
858 persistent_param_clear(char *node
)
860 boolean_t rval1
, rval2
, rval3
;
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
);
868 return (((rval1
== B_TRUE
) || (rval2
== B_TRUE
) || (rval3
== B_TRUE
))
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.
878 persistent_param_lock(void)
880 mutex_enter(¶m_data_lock
);
884 * persistent_param_unlock -- unlock access to login parameters.
887 persistent_param_unlock(void)
889 mutex_exit(¶m_data_lock
);
893 * +--------------------------------------------------------------------+
894 * | Session Config Interfaces |
895 * +--------------------------------------------------------------------+
900 * persistent_set_config_session -- store configured sessions
901 * for a specific target
904 persistent_set_config_session(char *node
, iscsi_config_sess_t
*ics
)
910 * Make ics_out match ics_in. Since when someone gets
911 * this information the in value becomes the out.
913 ics
->ics_out
= ics
->ics_in
;
916 size
= ISCSI_SESSION_CONFIG_SIZE(ics
->ics_in
);
918 mutex_enter(¶m_data_lock
);
919 rval
= nvf_data_set(SESSION_PARAMS_ID
, node
, (void *)ics
, size
);
920 mutex_exit(¶m_data_lock
);
926 * persistent_get_config_session -- obtain configured sessions
927 * for a specific target
930 persistent_get_config_session(char *node
, iscsi_config_sess_t
*ics
)
936 ASSERT(ics
->ics_in
>= 1);
938 /* record caller buffer size */
941 /* Get base config_sess information */
942 size
= ISCSI_SESSION_CONFIG_SIZE(in
);
943 status
= nvf_data_get(SESSION_PARAMS_ID
, node
,
946 /* reset the in size */
953 * persistent_get_tunable_param -- obtain tunable parameters
954 * for a specific target
957 persistent_get_tunable_param(char *node
, persistent_tunable_param_t
*tpsg
)
959 return (nvf_data_get(TUNABLE_PARAMS_ID
, node
,
960 (void *)tpsg
, sizeof (persistent_tunable_param_t
)));
964 * persistent_set_tunable_param -- store tunable parameters
965 * for a specific target
968 persistent_set_tunable_param(char *node
, persistent_tunable_param_t
*tpss
)
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
);
979 * +--------------------------------------------------------------------+
980 * | CHAP Parameter Interfaces |
981 * +--------------------------------------------------------------------+
985 * persistent_chap_set -- store CHAP parameters for a specific target
988 persistent_chap_set(char *node
, iscsi_chap_props_t
*chap
)
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
);
1001 * persistent_chap_get -- obtain CHAP parameters for a specific target
1004 persistent_chap_get(char *node
, iscsi_chap_props_t
*chap
)
1006 return (nvf_data_get(CHAP_PARAMS_ID
, node
,
1007 (void *)chap
, sizeof (*chap
)));
1011 * persistent_chap_next -- copy the next target's chap parameters.
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.
1017 * This function assumes the associated chap parameter lock is held.
1019 * Returns B_TRUE when data in *param is valid. B_FALSE returned when no
1020 * more data is available.
1023 persistent_chap_next(void **v
, char *node
, iscsi_chap_props_t
*chap
)
1025 ASSERT(mutex_owned(&chap_data_lock
));
1027 return (nvf_data_next(CHAP_PARAMS_ID
, v
, node
,
1028 (void *)chap
, sizeof (*chap
)));
1032 * persistent_chap_clear -- remove CHAP parameters for a specific target
1035 persistent_chap_clear(char *node
)
1039 mutex_enter(&chap_data_lock
);
1040 rval
= nvf_data_clear(CHAP_PARAMS_ID
, node
);
1041 mutex_exit(&chap_data_lock
);
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.
1052 persistent_chap_lock(void)
1054 mutex_enter(&chap_data_lock
);
1058 * persistent_chap_unlock -- unlock access to chap parameters.
1061 persistent_chap_unlock(void)
1063 mutex_exit(&chap_data_lock
);
1068 * +--------------------------------------------------------------------+
1069 * | RADIUS Configuration Interfaces |
1070 * +--------------------------------------------------------------------+
1074 * persistent_radius_set -- stores the RADIUS configuration info
1077 persistent_radius_set(iscsi_radius_props_t
*radius
)
1079 return (nvf_node_data_set(RADIUS_PARAMS_ID
, (void *)radius
,
1080 sizeof (iscsi_radius_props_t
)));
1084 * persistent_radius_get -- obtain the RADIUS configuration info
1086 iscsi_nvfile_status_t
1087 persistent_radius_get(iscsi_radius_props_t
*radius
)
1089 return (nvf_node_data_get(RADIUS_PARAMS_ID
,
1090 (void *)radius
, sizeof (*radius
)));
1095 * +--------------------------------------------------------------------+
1096 * | Authentication Configuration Interface |
1097 * +--------------------------------------------------------------------+
1101 * persistent_auth_set -- stores the bidirectional authentication settings
1102 * for a specific target
1105 persistent_auth_set(char *node
, iscsi_auth_props_t
*auth
)
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
);
1118 * persistent_auth_get -- gets the bidirectional authentication settings
1119 * for a specific target
1122 persistent_auth_get(char *node
, iscsi_auth_props_t
*auth
)
1124 return (nvf_data_get(BIDIR_AUTH_PARAMS_ID
, node
,
1125 (void *)auth
, sizeof (*auth
)));
1129 * persistent_auth_next -- get the next target's bidirectional authentication
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.
1136 * This function assumes the associated bidirectional authentication lock is
1139 * Returns B_TRUE when data in *param is valid. B_FALSE returned when no
1140 * more data is available.
1143 persistent_auth_next(void **v
, char *node
, iscsi_auth_props_t
*auth
)
1145 ASSERT(mutex_owned(&auth_data_lock
));
1147 return (nvf_data_next(BIDIR_AUTH_PARAMS_ID
, v
, node
,
1148 (void *)auth
, sizeof (*auth
)));
1152 * persistent_auth_clear -- remove bidirectional authentication parameters for
1156 persistent_auth_clear(char *node
)
1160 mutex_enter(&auth_data_lock
);
1161 rval
= nvf_data_clear(BIDIR_AUTH_PARAMS_ID
, node
);
1162 mutex_exit(&auth_data_lock
);
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.
1174 persistent_auth_lock(void)
1176 mutex_enter(&auth_data_lock
);
1180 * persistent_auth_unlock -- unlock access to bidirectional authentication
1184 persistent_auth_unlock(void)
1186 mutex_exit(&auth_data_lock
);
1191 * +--------------------------------------------------------------------+
1192 * | Debug Functions |
1193 * +--------------------------------------------------------------------+
1196 #define BITBUF_LEN 128
1199 * persistent_dump_data -- dump contents of persistent store
1202 persistent_dump_data(void)
1206 iSCSIDiscoveryMethod_t methods
;
1208 iscsi_radius_props_t
*radius
;
1212 persistent_param_t
*param
;
1215 iscsi_chap_props_t
*chap
;
1216 iscsi_auth_props_t
*auth
;
1218 name
= kmem_alloc(ISCSI_MAX_NAME_LEN
, KM_SLEEP
);
1219 addr_buf
= kmem_alloc(INET6_ADDRSTRLEN
, KM_SLEEP
);
1220 bitbuf
= kmem_alloc(BITBUF_LEN
, KM_SLEEP
);
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
);
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
);
1232 methods
= persistent_disc_meth_get();
1233 if (methods
!= iSCSIDiscoveryMethodUnknown
) {
1234 cmn_err(CE_CONT
, " Methods: <%s>\n",
1236 "\003SendTarget\002iSNS\001SLP\000Static",
1237 bitbuf
, BITBUF_LEN
));
1240 radius
= (iscsi_radius_props_t
*)kmem_alloc(sizeof (*radius
),
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
);
1248 (void) inet_ntop(AF_INET6
, &radius
->r_addr
.u_in6
,
1249 addr_buf
, INET6_ADDRSTRLEN
);
1251 cmn_err(CE_CONT
, " IP: %s, port %d\n", addr_buf
,
1254 kmem_free(radius
, sizeof (*radius
));
1256 entry
= (entry_t
*)kmem_alloc(sizeof (*entry
), KM_SLEEP
);
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
);
1268 (void) inet_ntop(AF_INET6
, &entry
->e_u
.u_in6
,
1269 addr_buf
, INET6_ADDRSTRLEN
);
1272 " IP: %s, port %d\n", addr_buf
, entry
->e_port
);
1274 persistent_static_addr_unlock();
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
);
1285 (void) inet_ntop(AF_INET6
, &entry
->e_u
.u_in6
,
1286 addr_buf
, INET6_ADDRSTRLEN
);
1289 " IP: %s, port %d\n", addr_buf
, entry
->e_port
);
1291 persistent_disc_addr_unlock();
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
);
1302 (void) inet_ntop(AF_INET6
, &entry
->e_u
.u_in6
,
1303 addr_buf
, INET6_ADDRSTRLEN
);
1306 " IP: %s, port %d\n", addr_buf
, entry
->e_port
);
1308 persistent_isns_addr_unlock();
1309 kmem_free(entry
, sizeof (*entry
));
1311 param
= (persistent_param_t
*)kmem_alloc(sizeof (*param
), KM_SLEEP
);
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
;
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";
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
) ?
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
) ?
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
) ?
1349 case ISCSI_LOGIN_PARAM_HEADER_DIGEST
:
1350 cmn_err(CE_CONT
, " %s = %d",
1351 param_name
, param
->p_params
.
1354 case ISCSI_LOGIN_PARAM_DATA_DIGEST
:
1355 cmn_err(CE_CONT
, " %s = %d",
1356 param_name
, param
->p_params
.
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
);
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
);
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
);
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
);
1379 case ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH
:
1380 cmn_err(CE_CONT
, " %s = %d",
1381 param_name
, param
->p_params
.
1384 case ISCSI_LOGIN_PARAM_MAX_CONNECTIONS
:
1385 cmn_err(CE_CONT
, " %s = %d",
1386 param_name
, param
->p_params
.
1389 case ISCSI_LOGIN_PARAM_OUTSTANDING_R2T
:
1390 cmn_err(CE_CONT
, " %s = %d",
1391 param_name
, param
->p_params
.
1392 max_outstanding_r2t
);
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
);
1405 persistent_param_unlock();
1406 kmem_free(param
, sizeof (*param
));
1408 chap
= (iscsi_chap_props_t
*)kmem_alloc(sizeof (*chap
), KM_SLEEP
);
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
);
1417 persistent_chap_unlock();
1418 kmem_free(chap
, sizeof (*chap
));
1420 auth
= (iscsi_auth_props_t
*)kmem_alloc(sizeof (*auth
), KM_SLEEP
);
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");
1429 persistent_auth_unlock();
1430 kmem_free(auth
, sizeof (*auth
));
1433 kmem_free(bitbuf
, BITBUF_LEN
);
1434 kmem_free(addr_buf
, INET6_ADDRSTRLEN
);
1435 kmem_free(name
, ISCSI_MAX_NAME_LEN
);