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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <arpa/inet.h>
26 #include <sys/socket.h>
27 #include <sys/types.h>
39 #include <libdevinfo.h>
41 #include <sys/scsi/adapters/iscsi_if.h>
42 #include <sys/scsi/adapters/iscsi_door.h>
43 #include <sys/iscsi_protocol.h>
48 #define LIBRARY_PROPERTY_SUPPORTED_IMA_VERSION 1
49 #define LIBRARY_PROPERTY_IMPLEMENTATION_VERSION L"1.0.0"
50 #define LIBRARY_PROPERTY_VENDOR L"Sun Microsystems, Inc."
51 #define DEFAULT_NODE_NAME_FORMAT "iqn.2003-13.com.ima.%s"
52 #define PLUGIN_OWNER 1
53 #define MAX_CHAP_SECRET_LEN 16
55 /* LINTED E_STATIC_UNUSED */
56 static IMA_INT32 number_of_plugins
= -1;
57 /* LINTED E_STATIC_UNUSED */
58 static IMA_NODE_NAME sharedNodeName
;
59 /* LINTED E_STATIC_UNUSED */
60 static IMA_NODE_ALIAS sharedNodeAlias
;
61 /* LINTED E_STATIC_UNUSED */
62 static IMA_PLUGIN_PROPERTIES PluginProperties
;
64 /* LINTED E_STATIC_UNUSED */
65 static IMA_OID pluginOid
;
66 static IMA_OID lhbaObjectId
;
67 /* LINTED E_STATIC_UNUSED */
68 static boolean_t pluginInit
= B_FALSE
;
70 /* Forward declaration */
72 #define MIN_MAX_PARAM 2
74 #define PARAM_OP_FAILED 1
76 static int open_driver(int *fd
);
77 static IMA_STATUS
getISCSINodeParameter(int paramType
,
81 static IMA_STATUS
setISCSINodeParameter(int paramType
,
85 static IMA_STATUS
getDigest(IMA_OID oid
, int ioctlCmd
,
86 SUN_IMA_DIGEST_ALGORITHM_VALUE
*algorithm
);
87 static IMA_STATUS
setAuthMethods(IMA_OID oid
, IMA_UINT
*pMethodCount
,
88 const IMA_AUTHMETHOD
*pMethodList
);
89 static IMA_STATUS
getAuthMethods(IMA_OID oid
, IMA_UINT
*pMethodCount
,
90 IMA_AUTHMETHOD
*pMethodList
);
91 IMA_STATUS
getNegotiatedDigest(int digestType
,
92 SUN_IMA_DIGEST_ALGORITHM_VALUE
*algorithm
,
93 SUN_IMA_CONN_PROPERTIES
*connProps
);
96 #define DISC_ADDR_OK 0
97 /* Incorrect IP address */
98 #define DISC_ADDR_INTEGRITY_ERROR 1
99 /* Error converting text IP address to numeric binary form */
100 #define DISC_ADDR_IP_CONV_ERROR 2
101 static int prepare_discovery_entry(SUN_IMA_TARGET_ADDRESS discoveryAddress
,
103 static int prepare_discovery_entry_IMA(IMA_TARGET_ADDRESS discoveryAddress
,
106 /* LINTED E_STATIC_UNUSED */
107 static IMA_STATUS
configure_discovery_method(IMA_BOOL enable
,
108 iSCSIDiscoveryMethod_t method
);
110 static IMA_STATUS
get_target_oid_list(uint32_t targetListType
,
111 IMA_OID_LIST
**ppList
);
113 static IMA_STATUS
get_target_lun_oid_list(IMA_OID
* targetOid
,
114 iscsi_lun_list_t
**ppLunList
);
116 static int get_lun_devlink(di_devlink_t link
, void *arg
);
118 static IMA_STATUS
getConnOidList(
120 iscsi_conn_list_t
**ppConnList
);
122 static IMA_STATUS
getConnProps(
123 iscsi_if_conn_t
*pConn
,
124 iscsi_conn_props_t
**ppConnProps
);
126 /* LINTED E_STATIC_UNUSED */
127 static void libSwprintf(wchar_t *wcs
, const wchar_t *lpszFormat
, ...)
130 va_start(args
, lpszFormat
);
131 (void) vswprintf(wcs
, 255, lpszFormat
, args
);
140 while (t
!= NULL
&& *t
) {
141 if (*t
>= 'A' && *t
<= 'Z')
148 /* LINTED E_STATIC_UNUSED */
149 static void GetBuildTime(IMA_DATETIME
* pdatetime
)
151 #if defined(BUILD_DATE)
152 if (strptime(BUILD_DATE
, "%Y/%m/%d %T %Z", pdatetime
) == NULL
) {
153 (void) memset(pdatetime
, 0, sizeof (IMA_DATETIME
));
156 (void) memset(pdatetime
, 0, sizeof (IMA_DATETIME
));
161 * Non-IMA defined function.
163 IMA_API IMA_STATUS
SUN_IMA_GetDiscoveryAddressPropertiesList(
164 SUN_IMA_DISC_ADDR_PROP_LIST
**ppList
167 char discovery_addr_str
[256];
170 int discovery_addr_list_size
;
173 iscsi_addr_list_t
*ialp
;
174 /* LINTED E_FUNC_SET_NOT_USED */
175 IMA_IP_ADDRESS
*ipAddr
;
177 if ((status
= open_driver(&fd
))) {
178 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
181 ialp
= (iscsi_addr_list_t
*)calloc(1, sizeof (iscsi_addr_list_t
));
184 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
187 ialp
->al_vers
= ISCSI_INTERFACE_VERSION
;
188 ialp
->al_in_cnt
= ialp
->al_out_cnt
= 1;
191 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl
192 * We have allocated space for one entry, if more than one
193 * address is going to be returned, we will re-issue the ioctl
195 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_LIST_GET
, ialp
) != 0) {
197 syslog(LOG_USER
|LOG_DEBUG
,
198 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d",
200 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
203 if (ialp
->al_out_cnt
> 1) {
205 * we need to allocate more space, save off the out_cnt
208 out_cnt
= ialp
->al_out_cnt
;
211 discovery_addr_list_size
= sizeof (iscsi_addr_list_t
);
212 discovery_addr_list_size
+= (sizeof (iscsi_addr_t
) *
214 ialp
= (iscsi_addr_list_t
*)calloc(1, discovery_addr_list_size
);
217 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
219 ialp
->al_vers
= ISCSI_INTERFACE_VERSION
;
220 ialp
->al_in_cnt
= out_cnt
;
223 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl again to obtain all
224 * the discovery addresses.
226 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_LIST_GET
, ialp
) != 0) {
227 #define ERROR_STR "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno :%d"
230 syslog(LOG_USER
|LOG_DEBUG
,
232 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
238 *ppList
= (SUN_IMA_DISC_ADDR_PROP_LIST
*)calloc(1,
239 sizeof (SUN_IMA_DISC_ADDR_PROP_LIST
) +
240 ialp
->al_out_cnt
* sizeof (IMA_DISCOVERY_ADDRESS_PROPERTIES
));
241 if (*ppList
== NULL
) {
244 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
246 (*ppList
)->discAddrCount
= ialp
->al_out_cnt
;
248 for (i
= 0; i
< ialp
->al_out_cnt
; i
++) {
249 if (ialp
->al_addrs
[i
].a_addr
.i_insize
==
250 sizeof (struct in_addr
)) {
252 (*ppList
)->props
[i
].discoveryAddress
.hostnameIpAddress
.
253 id
.ipAddress
.ipv4Address
= IMA_TRUE
;
255 } else if (ialp
->al_addrs
[i
].a_addr
.i_insize
==
256 sizeof (struct in6_addr
)) {
258 (*ppList
)->props
[i
].discoveryAddress
.hostnameIpAddress
.
259 id
.ipAddress
.ipv4Address
= IMA_FALSE
;
262 (void) strlcpy(discovery_addr_str
, "unknown",
263 sizeof (discovery_addr_str
));
266 ipAddr
= &(*ppList
)->props
[i
].discoveryAddress
.
267 hostnameIpAddress
.id
.ipAddress
;
269 bcopy(&ialp
->al_addrs
[i
].a_addr
.i_addr
,
270 (*ppList
)->props
[i
].discoveryAddress
.hostnameIpAddress
.id
.
272 sizeof (ipAddr
->ipAddress
));
274 (*ppList
)->props
[i
].discoveryAddress
.portNumber
=
275 ialp
->al_addrs
[i
].a_port
;
280 return (IMA_STATUS_SUCCESS
);
283 IMA_API IMA_STATUS
SUN_IMA_GetStaticTargetProperties(
284 IMA_OID staticTargetOid
,
285 SUN_IMA_STATIC_TARGET_PROPERTIES
*pProps
290 iscsi_static_property_t prop
;
292 IMA_IP_ADDRESS
*ipAddr
;
294 if ((status
= open_driver(&fd
))) {
295 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
298 (void) memset(&prop
, 0, sizeof (iscsi_static_property_t
));
299 prop
.p_vers
= ISCSI_INTERFACE_VERSION
;
300 prop
.p_oid
= (uint32_t)staticTargetOid
.objectSequenceNumber
;
301 if (ioctl(fd
, ISCSI_STATIC_GET
, &prop
) != 0) {
304 syslog(LOG_USER
|LOG_DEBUG
,
305 "ISCSI_STATIC_GET ioctl failed, errno: %d", status
);
306 if (status
== ENOENT
) {
307 return (IMA_ERROR_OBJECT_NOT_FOUND
);
309 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
314 (void) mbstowcs(pProps
->staticTarget
.targetName
, (char *)prop
.p_name
,
315 sizeof (pProps
->staticTarget
.targetName
)/sizeof (IMA_WCHAR
));
317 if (prop
.p_addr_list
.al_addrs
[0].a_addr
.i_insize
==
318 sizeof (struct in_addr
)) {
320 pProps
->staticTarget
.targetAddress
.imaStruct
.hostnameIpAddress
.
321 id
.ipAddress
.ipv4Address
= IMA_TRUE
;
322 } else if (prop
.p_addr_list
.al_addrs
[0].a_addr
.i_insize
==
323 sizeof (struct in6_addr
)) {
325 pProps
->staticTarget
.targetAddress
.imaStruct
.hostnameIpAddress
.
326 id
.ipAddress
.ipv4Address
= IMA_FALSE
;
328 /* Should not happen */
329 syslog(LOG_USER
|LOG_DEBUG
,
330 "ISCSI_STATIC_GET returned bad address");
331 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
334 ipAddr
= &pProps
->staticTarget
.targetAddress
.imaStruct
.
335 hostnameIpAddress
.id
.ipAddress
;
337 bcopy(&prop
.p_addr_list
.al_addrs
[0].a_addr
.i_addr
,
338 pProps
->staticTarget
.targetAddress
.imaStruct
.hostnameIpAddress
.id
.
339 ipAddress
.ipAddress
, sizeof (ipAddr
->ipAddress
));
341 pProps
->staticTarget
.targetAddress
.imaStruct
.portNumber
=
342 prop
.p_addr_list
.al_addrs
[0].a_port
;
345 if (prop
.p_addr_list
.al_tpgt
== (uint32_t)ISCSI_DEFAULT_TPGT
) {
346 pProps
->staticTarget
.targetAddress
.defaultTpgt
= IMA_TRUE
;
347 pProps
->staticTarget
.targetAddress
.tpgt
= 0;
349 pProps
->staticTarget
.targetAddress
.defaultTpgt
= IMA_FALSE
;
350 pProps
->staticTarget
.targetAddress
.tpgt
=
351 prop
.p_addr_list
.al_tpgt
;
354 return (IMA_STATUS_SUCCESS
);
358 IMA_API IMA_STATUS
SUN_IMA_AddStaticTarget(
360 const SUN_IMA_STATIC_DISCOVERY_TARGET staticConfig
,
364 iscsi_target_entry_t target
;
366 int target_in_addr_size
;
369 struct in_addr u_in4
;
370 struct in6_addr u_in6
;
374 * staticConfig.address may come in with port number at its trailer.
375 * Parse it to separate the IP address and port number.
376 * Also translate the hostname to IP address if needed.
379 if (staticConfig
.targetAddress
.imaStruct
.hostnameIpAddress
.id
.ipAddress
.
380 ipv4Address
== IMA_FALSE
) {
382 bcopy(staticConfig
.targetAddress
.imaStruct
.hostnameIpAddress
.
383 id
.ipAddress
.ipAddress
, &target_in
.u_in6
,
384 sizeof (target_in
.u_in6
));
386 target_in_addr_size
= sizeof (struct in6_addr
);
389 bcopy(staticConfig
.targetAddress
.imaStruct
.hostnameIpAddress
.
390 id
.ipAddress
.ipAddress
, &target_in
.u_in4
,
391 sizeof (target_in
.u_in4
));
393 target_in_addr_size
= sizeof (struct in_addr
);
396 (void) memset(&target
, 0, sizeof (iscsi_target_entry_t
));
397 target
.te_entry
.e_vers
= ISCSI_INTERFACE_VERSION
;
398 target
.te_entry
.e_oid
= ISCSI_OID_NOTSET
;
400 (void) wcstombs((char *)target
.te_name
, staticConfig
.targetName
,
403 target
.te_entry
.e_insize
= target_in_addr_size
;
404 if (target
.te_entry
.e_insize
== sizeof (struct in_addr
)) {
405 target
.te_entry
.e_u
.u_in4
.s_addr
= target_in
.u_in4
.s_addr
;
406 } else if (target
.te_entry
.e_insize
== sizeof (struct in6_addr
)) {
407 bcopy(target_in
.u_in6
.s6_addr
,
408 target
.te_entry
.e_u
.u_in6
.s6_addr
,
409 sizeof (struct in6_addr
));
411 return (IMA_ERROR_INVALID_PARAMETER
);
414 target
.te_entry
.e_port
=
415 staticConfig
.targetAddress
.imaStruct
.portNumber
;
417 if (staticConfig
.targetAddress
.defaultTpgt
== IMA_TRUE
) {
418 target
.te_entry
.e_tpgt
= ISCSI_DEFAULT_TPGT
;
420 target
.te_entry
.e_tpgt
= staticConfig
.targetAddress
.tpgt
;
423 if ((status
= open_driver(&fd
))) {
424 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
427 if (ioctl(fd
, ISCSI_STATIC_SET
, &target
)) {
429 * Encountered problem setting the IP address and port for
430 * the target just added.
432 syslog(LOG_USER
|LOG_DEBUG
,
433 "ISCSI_STATIC_SET ioctl failed, errno: %d", errno
);
435 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
438 pTargetOid
->objectType
= IMA_OBJECT_TYPE_TARGET
;
439 pTargetOid
->ownerId
= 1;
440 pTargetOid
->objectSequenceNumber
= target
.te_entry
.e_oid
;
443 return (IMA_STATUS_SUCCESS
);
446 IMA_API IMA_STATUS
SUN_IMA_GetTargetProperties(
448 SUN_IMA_TARGET_PROPERTIES
*pProps
453 iscsi_property_t prop
;
455 if ((status
= open_driver(&fd
))) {
456 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
459 (void) memset(&prop
, 0, sizeof (iscsi_property_t
));
460 prop
.p_vers
= ISCSI_INTERFACE_VERSION
;
461 prop
.p_oid
= (uint32_t)targetId
.objectSequenceNumber
;
463 if (ioctl(fd
, ISCSI_TARGET_PROPS_GET
, &prop
) != 0) {
464 syslog(LOG_USER
|LOG_DEBUG
,
465 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno
);
467 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
470 (void) mbstowcs(pProps
->imaProps
.name
,
471 (char *)prop
.p_name
, IMA_NODE_NAME_LEN
);
472 (void) memset(pProps
->imaProps
.alias
, 0,
473 (sizeof (IMA_WCHAR
) * SUN_IMA_NODE_ALIAS_LEN
));
474 if (prop
.p_alias_len
> 0) {
475 (void) mbstowcs(pProps
->imaProps
.alias
, (char *)prop
.p_alias
,
476 SUN_IMA_NODE_ALIAS_LEN
);
479 /* Initialize the discovery method to unknown method. */
480 pProps
->imaProps
.discoveryMethodFlags
=
481 IMA_TARGET_DISCOVERY_METHOD_UNKNOWN
;
482 if (!((prop
.p_discovery
& iSCSIDiscoveryMethodStatic
) ^
483 iSCSIDiscoveryMethodStatic
)) {
484 pProps
->imaProps
.discoveryMethodFlags
|=
485 IMA_TARGET_DISCOVERY_METHOD_STATIC
;
488 if (!((prop
.p_discovery
& iSCSIDiscoveryMethodSLP
) ^
489 iSCSIDiscoveryMethodSLP
)) {
490 pProps
->imaProps
.discoveryMethodFlags
|=
491 IMA_TARGET_DISCOVERY_METHOD_SLP
;
494 if (!((prop
.p_discovery
& iSCSIDiscoveryMethodISNS
) ^
495 iSCSIDiscoveryMethodISNS
)) {
496 pProps
->imaProps
.discoveryMethodFlags
|=
497 iSCSIDiscoveryMethodISNS
;
500 if (!((prop
.p_discovery
& iSCSIDiscoveryMethodSendTargets
) ^
501 iSCSIDiscoveryMethodSendTargets
)) {
502 pProps
->imaProps
.discoveryMethodFlags
|=
503 iSCSIDiscoveryMethodSendTargets
;
506 if (prop
.p_tpgt_conf
== ISCSI_DEFAULT_TPGT
) {
507 pProps
->defaultTpgtConf
= IMA_TRUE
;
508 pProps
->tpgtConf
= 0;
510 pProps
->defaultTpgtConf
= IMA_FALSE
;
511 pProps
->tpgtConf
= prop
.p_tpgt_conf
;
514 if (prop
.p_tpgt_nego
== ISCSI_DEFAULT_TPGT
) {
515 pProps
->defaultTpgtNego
= IMA_TRUE
;
516 pProps
->tpgtNego
= 0;
518 pProps
->defaultTpgtNego
= IMA_FALSE
;
519 pProps
->tpgtNego
= prop
.p_tpgt_nego
;
522 bcopy(prop
.p_isid
, pProps
->isid
, ISCSI_ISID_LEN
);
525 return (IMA_STATUS_SUCCESS
);
529 * This function only sets CHAP params since we only support CHAP for now.
531 IMA_STATUS
SUN_IMA_SetTargetAuthParams(
533 IMA_AUTHMETHOD method
,
534 const IMA_INITIATOR_AUTHPARMS
*pParms
538 iscsi_chap_props_t chap_p
;
540 if (method
!= IMA_AUTHMETHOD_CHAP
)
541 return (IMA_ERROR_INVALID_PARAMETER
);
543 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
544 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
545 ISCSI_DRIVER_DEVCTL
, errno
);
546 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
549 (void) memset(&chap_p
, 0, sizeof (iscsi_chap_props_t
));
550 chap_p
.c_vers
= ISCSI_INTERFACE_VERSION
;
551 chap_p
.c_oid
= (uint32_t)targetOid
.objectSequenceNumber
;
554 pParms
->chapParms
.nameLength
;
555 (void) memcpy(chap_p
.c_user
,
556 pParms
->chapParms
.name
, chap_p
.c_user_len
);
558 chap_p
.c_secret_len
=
559 pParms
->chapParms
.challengeSecretLength
;
560 (void) memcpy(chap_p
.c_secret
,
561 pParms
->chapParms
.challengeSecret
,
562 chap_p
.c_secret_len
);
564 if (ioctl(fd
, ISCSI_CHAP_SET
, &chap_p
) != 0) {
565 syslog(LOG_USER
|LOG_DEBUG
,
566 "ISCSI_CHAP_SET ioctl failed, errno: %d", errno
);
568 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
571 return (IMA_STATUS_SUCCESS
);
574 IMA_STATUS
SUN_IMA_GetTargetAuthMethods(
577 IMA_UINT
*pMethodCount
,
578 IMA_AUTHMETHOD
*pMethodList
581 if (getAuthMethods(targetOid
, pMethodCount
, pMethodList
)
582 != IMA_STATUS_SUCCESS
) {
583 return (getAuthMethods(lhbaOid
, pMethodCount
, pMethodList
));
585 return (IMA_STATUS_SUCCESS
);
588 IMA_STATUS
SUN_IMA_SetInitiatorRadiusConfig(
590 SUN_IMA_RADIUS_CONFIG
*config
596 iscsi_radius_props_t radius
;
598 struct in_addr u_in4
;
599 struct in6_addr u_in6
;
602 if ((status
= open_driver(&fd
))) {
603 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
606 (void) memset(&radius
, 0, sizeof (iscsi_radius_props_t
));
607 radius
.r_vers
= ISCSI_INTERFACE_VERSION
;
608 radius
.r_oid
= (uint32_t)lhbaOid
.objectSequenceNumber
;
609 /* Get first because other data fields may already exist */
610 if (ioctl(fd
, ISCSI_RADIUS_GET
, &radius
) != 0) {
612 /* It's fine if other data fields are not there. */
615 if (config
->isIpv6
== IMA_TRUE
) {
621 if (inet_pton(af
, config
->hostnameIpAddress
, &radius_in
.u_in4
) != 1) {
622 return (IMA_ERROR_INVALID_PARAMETER
);
627 radius
.r_addr
.u_in4
.s_addr
= radius_in
.u_in4
.s_addr
;
628 radius
.r_insize
= sizeof (struct in_addr
);
631 (void) memcpy(radius
.r_addr
.u_in6
.s6_addr
,
632 radius_in
.u_in6
.s6_addr
, 16);
633 radius
.r_insize
= sizeof (struct in6_addr
);
636 radius
.r_port
= config
->port
;
637 radius
.r_radius_config_valid
= B_TRUE
;
638 /* Allow resetting the RADIUS shared secret to NULL */
639 if (config
->sharedSecretValid
== IMA_TRUE
) {
640 radius
.r_shared_secret_len
= config
->sharedSecretLength
;
641 (void) memset(&radius
.r_shared_secret
[0], 0,
642 MAX_RAD_SHARED_SECRET_LEN
);
643 (void) memcpy(&radius
.r_shared_secret
[0], config
->sharedSecret
,
644 config
->sharedSecretLength
);
647 if (ioctl(fd
, ISCSI_RADIUS_SET
, &radius
) != 0) {
648 syslog(LOG_USER
|LOG_DEBUG
,
649 "ISCSI_RADIUS_SET ioctl failed, errno: %d", errno
);
651 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
655 return (IMA_STATUS_SUCCESS
);
658 IMA_STATUS
SUN_IMA_GetInitiatorRadiusConfig(
660 SUN_IMA_RADIUS_CONFIG
*config
666 iscsi_radius_props_t radius
;
668 if ((status
= open_driver(&fd
))) {
669 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
672 (void) memset(&radius
, 0, sizeof (iscsi_radius_props_t
));
673 radius
.r_vers
= ISCSI_INTERFACE_VERSION
;
674 radius
.r_oid
= (uint32_t)lhbaOid
.objectSequenceNumber
;
676 if (ioctl(fd
, ISCSI_RADIUS_GET
, &radius
) != 0) {
678 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
681 (void) memset(config
, 0, sizeof (SUN_IMA_RADIUS_CONFIG
));
682 if (radius
.r_insize
== sizeof (struct in_addr
)) {
685 } else if (radius
.r_insize
== sizeof (struct in6_addr
)) {
690 * It's legitimate that the existing RADIUS record does not
691 * have configuration data.
693 config
->hostnameIpAddress
[0] = '\0';
696 return (IMA_STATUS_SUCCESS
);
698 (void) inet_ntop(af
, (void *)&radius
.r_addr
.u_in4
,
699 config
->hostnameIpAddress
, 256);
700 config
->port
= radius
.r_port
;
701 (void) memcpy(config
->sharedSecret
, &radius
.r_shared_secret
[0],
702 radius
.r_shared_secret_len
);
703 config
->sharedSecretLength
= radius
.r_shared_secret_len
;
704 config
->sharedSecretValid
= B_TRUE
;
707 return (IMA_STATUS_SUCCESS
);
710 IMA_STATUS
SUN_IMA_SetInitiatorRadiusAccess(
712 IMA_BOOL radiusAccess
717 iscsi_radius_props_t radius
;
719 if ((status
= open_driver(&fd
))) {
720 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
723 (void) memset(&radius
, 0, sizeof (iscsi_radius_props_t
));
724 radius
.r_vers
= ISCSI_INTERFACE_VERSION
;
725 radius
.r_oid
= (uint32_t)lhbaOid
.objectSequenceNumber
;
726 /* Get first because other data fields may already exist */
727 if (ioctl(fd
, ISCSI_RADIUS_GET
, &radius
) != 0) {
728 if (radiusAccess
== IMA_TRUE
) {
730 * Cannot enable RADIUS if no RADIUS configuration
733 syslog(LOG_USER
|LOG_DEBUG
,
734 "RADIUS config data not found - "
735 "cannot enable RADIUS, errno: %d", errno
);
737 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
740 /* Otherwise it's fine to disable RADIUS */
744 if ((radius
.r_insize
!= sizeof (struct in_addr
)) &&
745 (radius
.r_insize
!= sizeof (struct in6_addr
))) {
747 * Cannot enable RADIUS if no RADIUS configuration
750 if (radiusAccess
== IMA_TRUE
) {
751 syslog(LOG_USER
|LOG_DEBUG
,
752 "RADIUS config data not found - "
753 "cannot enable RADIUS");
755 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
759 radius
.r_radius_access
= (radiusAccess
== IMA_TRUE
) ?
762 if (ioctl(fd
, ISCSI_RADIUS_SET
, &radius
) != 0) {
763 syslog(LOG_USER
|LOG_DEBUG
,
764 "ISCSI_RADIUS_SET ioctl failed, errno: %d", errno
);
766 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
770 return (IMA_STATUS_SUCCESS
);
773 IMA_STATUS
SUN_IMA_GetInitiatorRadiusAccess(
775 IMA_BOOL
*radiusAccess
780 iscsi_radius_props_t radius
;
782 if ((status
= open_driver(&fd
))) {
783 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
786 (void) memset(&radius
, 0, sizeof (iscsi_radius_props_t
));
787 radius
.r_vers
= ISCSI_INTERFACE_VERSION
;
788 radius
.r_oid
= (uint32_t)lhbaOid
.objectSequenceNumber
;
790 if (ioctl(fd
, ISCSI_RADIUS_GET
, &radius
) != 0) {
792 if (errno
== ENOENT
) {
793 return (IMA_ERROR_OBJECT_NOT_FOUND
);
795 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
799 *radiusAccess
= (radius
.r_radius_access
== B_TRUE
) ?
800 IMA_TRUE
: IMA_FALSE
;
803 return (IMA_STATUS_SUCCESS
);
806 IMA_STATUS
SUN_IMA_SendTargets(
807 IMA_NODE_NAME nodeName
,
808 IMA_TARGET_ADDRESS address
,
809 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
**ppList
813 char discAddrStr
[256];
814 char nodeNameStr
[ISCSI_MAX_NAME_LEN
];
819 iscsi_sendtgts_list_t
*stl_hdr
= NULL
;
820 IMA_BOOL retry
= IMA_TRUE
;
822 IMA_IP_ADDRESS
*ipAddr
;
824 #define SENDTGTS_DEFAULT_NUM_TARGETS 10
826 stl_sz
= sizeof (*stl_hdr
) + ((SENDTGTS_DEFAULT_NUM_TARGETS
- 1) *
827 sizeof (iscsi_sendtgts_entry_t
));
828 stl_hdr
= (iscsi_sendtgts_list_t
*)calloc(1, stl_sz
);
829 if (stl_hdr
== NULL
) {
830 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
832 stl_hdr
->stl_entry
.e_vers
= ISCSI_INTERFACE_VERSION
;
833 stl_hdr
->stl_in_cnt
= SENDTGTS_DEFAULT_NUM_TARGETS
;
835 (void) wcstombs(nodeNameStr
, nodeName
, ISCSI_MAX_NAME_LEN
);
837 colonPos
= strchr(discAddrStr
, ':');
838 if (colonPos
== NULL
) {
840 stl_hdr
->stl_entry
.e_insize
= sizeof (struct in_addr
);
843 stl_hdr
->stl_entry
.e_insize
= sizeof (struct in6_addr
);
846 ipAddr
= &address
.hostnameIpAddress
.id
.ipAddress
;
848 bcopy(address
.hostnameIpAddress
.id
.ipAddress
.ipAddress
,
849 &stl_hdr
->stl_entry
.e_u
, sizeof (ipAddr
->ipAddress
));
851 stl_hdr
->stl_entry
.e_port
= address
.portNumber
;
853 if ((status
= open_driver(&fd
))) {
854 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
859 * Issue ioctl to obtain the SendTargets list
861 if (ioctl(fd
, ISCSI_SENDTGTS_GET
, stl_hdr
) != 0) {
862 syslog(LOG_USER
|LOG_DEBUG
,
863 "ISCSI_SENDTGTS_GET ioctl failed, errno: %d", errno
);
866 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
869 /* check if all targets received */
870 if (stl_hdr
->stl_in_cnt
< stl_hdr
->stl_out_cnt
) {
871 if (retry
== IMA_TRUE
) {
872 stl_sz
= sizeof (*stl_hdr
) +
873 ((stl_hdr
->stl_out_cnt
- 1) *
874 sizeof (iscsi_sendtgts_entry_t
));
875 stl_hdr
= (iscsi_sendtgts_list_t
*)
876 realloc(stl_hdr
, stl_sz
);
877 if (stl_hdr
== NULL
) {
879 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
881 stl_hdr
->stl_in_cnt
= stl_hdr
->stl_out_cnt
;
886 * don't retry after 2 attempts. The target list
887 * shouldn't continue to growing. Justs continue
888 * on and display what was found.
890 syslog(LOG_USER
|LOG_DEBUG
,
891 "ISCSI_SENDTGTS_GET overflow: "
892 "failed to obtain all targets");
893 stl_hdr
->stl_out_cnt
= stl_hdr
->stl_in_cnt
;
899 /* allocate for caller return buffer */
900 *ppList
= (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
*)calloc(1,
901 sizeof (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
) +
902 stl_hdr
->stl_out_cnt
* sizeof (SUN_IMA_DISC_ADDRESS_KEY
));
903 if (*ppList
== NULL
) {
905 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
908 (*ppList
)->keyCount
= stl_hdr
->stl_out_cnt
;
910 for (ctr
= 0; ctr
< stl_hdr
->stl_out_cnt
; ctr
++) {
911 (void) mbstowcs((*ppList
)->keys
[ctr
].name
,
912 (char *)stl_hdr
->stl_list
[ctr
].ste_name
,
915 (*ppList
)->keys
[ctr
].tpgt
= stl_hdr
->stl_list
[ctr
].ste_tpgt
;
917 (*ppList
)->keys
[ctr
].address
.portNumber
=
918 stl_hdr
->stl_list
[ctr
].ste_ipaddr
.a_port
;
920 if (stl_hdr
->stl_list
[ctr
].ste_ipaddr
.a_addr
.i_insize
==
921 sizeof (struct in_addr
)) {
922 (*ppList
)->keys
[ctr
].address
.ipAddress
.ipv4Address
=
924 } else if (stl_hdr
->stl_list
[ctr
].ste_ipaddr
.a_addr
.i_insize
==
925 sizeof (struct in6_addr
)) {
926 (*ppList
)->keys
[ctr
].address
.ipAddress
.ipv4Address
=
930 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
933 (void) memcpy(&(*ppList
)->keys
[ctr
].address
.ipAddress
.ipAddress
,
934 &(stl_hdr
->stl_list
[ctr
].ste_ipaddr
.a_addr
.i_addr
),
935 stl_hdr
->stl_list
[ctr
].ste_ipaddr
.a_addr
.i_insize
);
939 return (IMA_STATUS_SUCCESS
);
942 IMA_STATUS
SUN_IMA_SetTargetBidirAuthFlag(
944 IMA_BOOL
*bidirAuthFlag
949 iscsi_auth_props_t auth
;
951 if ((status
= open_driver(&fd
))) {
952 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
955 (void) memset(&auth
, 0, sizeof (iscsi_auth_props_t
));
956 auth
.a_vers
= ISCSI_INTERFACE_VERSION
;
957 auth
.a_oid
= (uint32_t)targetOid
.objectSequenceNumber
;
958 /* Get first because other data fields may already exist */
959 if (ioctl(fd
, ISCSI_AUTH_GET
, &auth
) != 0) {
961 /* It is fine if there is no other data fields. */
963 auth
.a_bi_auth
= (*bidirAuthFlag
== IMA_TRUE
) ? B_TRUE
: B_FALSE
;
964 if (ioctl(fd
, ISCSI_AUTH_SET
, &auth
) != 0) {
965 syslog(LOG_USER
|LOG_DEBUG
,
966 "ISCSI_AUTH_SET ioctl failed, errno: %d", errno
);
968 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
972 return (IMA_STATUS_SUCCESS
);
975 IMA_STATUS
SUN_IMA_GetTargetBidirAuthFlag(
977 IMA_BOOL
*bidirAuthFlag
982 iscsi_auth_props_t auth
;
984 if ((status
= open_driver(&fd
))) {
985 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
988 (void) memset(&auth
, 0, sizeof (iscsi_auth_props_t
));
989 auth
.a_vers
= ISCSI_INTERFACE_VERSION
;
990 auth
.a_oid
= (uint32_t)targetOid
.objectSequenceNumber
;
992 if (ioctl(fd
, ISCSI_AUTH_GET
, &auth
) != 0) {
994 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
997 *bidirAuthFlag
= (auth
.a_bi_auth
== B_TRUE
) ?
998 IMA_TRUE
: IMA_FALSE
;
1001 return (IMA_STATUS_SUCCESS
);
1004 IMA_STATUS
SUN_IMA_CreateTargetOid(
1005 IMA_NODE_NAME targetName
,
1013 if ((status
= open_driver(&fd
))) {
1014 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
1017 (void) memset(&oid
, 0, sizeof (iscsi_oid_t
));
1018 (void) wcstombs((char *)oid
.o_name
, targetName
, ISCSI_MAX_NAME_LEN
);
1019 oid
.o_tpgt
= ISCSI_DEFAULT_TPGT
;
1020 oid
.o_vers
= ISCSI_INTERFACE_VERSION
;
1021 if (ioctl(fd
, ISCSI_CREATE_OID
, &oid
) == -1) {
1022 syslog(LOG_USER
|LOG_DEBUG
,
1023 "ISCSI_CREATE_OID ioctl failed, errno: %d", errno
);
1025 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1028 targetOid
->objectType
= IMA_OBJECT_TYPE_TARGET
;
1029 targetOid
->ownerId
= 1;
1030 targetOid
->objectSequenceNumber
= oid
.o_oid
;
1033 return (IMA_STATUS_SUCCESS
);
1036 IMA_STATUS
SUN_IMA_RemoveTargetParam(
1043 iscsi_auth_props_t auth_p
;
1044 iscsi_chap_props_t chap_p
;
1046 if ((status
= open_driver(&fd
))) {
1047 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
1050 (void) memset(&entry
, 0, sizeof (entry_t
));
1051 entry
.e_vers
= ISCSI_INTERFACE_VERSION
;
1052 entry
.e_oid
= (uint32_t)targetOid
.objectSequenceNumber
;
1053 if (ioctl(fd
, ISCSI_TARGET_PARAM_CLEAR
, &entry
)) {
1055 * It could be that the target exists but the associated
1056 * target_param does not, and that is legitimate.
1058 syslog(LOG_USER
|LOG_DEBUG
,
1059 "ISCSI_TARGET_PARAM_CLEAR ioctl failed, errno: %d", errno
);
1062 /* Issue ISCSI_CHAP_CLEAR ioctl */
1063 (void) memset(&chap_p
, 0, sizeof (iscsi_chap_props_t
));
1064 chap_p
.c_vers
= ISCSI_INTERFACE_VERSION
;
1065 chap_p
.c_oid
= (uint32_t)targetOid
.objectSequenceNumber
;
1066 if (ioctl(fd
, ISCSI_CHAP_CLEAR
, &chap_p
) != 0) {
1068 * It could be that the CHAP of this target has never
1071 syslog(LOG_USER
|LOG_DEBUG
,
1072 "ISCSI_CHAP_CLEAR ioctl failed, errno: %d", errno
);
1076 * Issue ISCSI_AUTH_CLEAR ioctl, in which the authentication information
1077 * is removed and the target that is not discovered by initiator
1078 * is removed from the memory. So this ioctl should be called at last
1080 (void) memset(&auth_p
, 0, sizeof (iscsi_auth_props_t
));
1081 auth_p
.a_vers
= ISCSI_INTERFACE_VERSION
;
1082 auth_p
.a_oid
= (uint32_t)targetOid
.objectSequenceNumber
;
1083 if (ioctl(fd
, ISCSI_AUTH_CLEAR
, &auth_p
) != 0) {
1085 * It could be that the auth data of this target has
1088 syslog(LOG_USER
|LOG_DEBUG
,
1089 "ISCSI_AUTH_CLEAR ioctl failed, errno: %d", errno
);
1093 return (IMA_STATUS_SUCCESS
);
1096 IMA_API IMA_STATUS
SUN_IMA_SetHeaderDigest(
1098 IMA_UINT algorithmCount
,
1099 const SUN_IMA_DIGEST_ALGORITHM
*algorithmList
1102 IMA_MIN_MAX_VALUE mv
;
1103 uint32_t digest_algorithm
;
1105 /* We only support one preference of digest algorithm. */
1106 if (algorithmCount
> 1) {
1107 syslog(LOG_USER
|LOG_DEBUG
,
1108 "More than one digest algorithm specified.");
1109 return (IMA_ERROR_NOT_SUPPORTED
);
1111 switch (algorithmList
[0]) {
1112 case SUN_IMA_DIGEST_NONE
:
1113 digest_algorithm
= ISCSI_DIGEST_NONE
;
1115 case SUN_IMA_DIGEST_CRC32
:
1116 digest_algorithm
= ISCSI_DIGEST_CRC32C
;
1119 digest_algorithm
= ISCSI_DIGEST_NONE
;
1122 mv
.currentValue
= digest_algorithm
;
1123 return (setISCSINodeParameter(MIN_MAX_PARAM
, &oid
, &mv
,
1124 ISCSI_LOGIN_PARAM_HEADER_DIGEST
));
1127 IMA_API IMA_STATUS
SUN_IMA_SetDataDigest(
1129 IMA_UINT algorithmCount
,
1130 const SUN_IMA_DIGEST_ALGORITHM
*algorithmList
1133 IMA_MIN_MAX_VALUE mv
;
1134 uint32_t digest_algorithm
;
1136 /* We only support one preference of digest algorithm. */
1137 if (algorithmCount
> 1) {
1138 syslog(LOG_USER
|LOG_DEBUG
,
1139 "More than one digest algorithm specified.");
1140 return (IMA_ERROR_NOT_SUPPORTED
);
1142 switch (algorithmList
[0]) {
1143 case SUN_IMA_DIGEST_NONE
:
1144 digest_algorithm
= ISCSI_DIGEST_NONE
;
1146 case SUN_IMA_DIGEST_CRC32
:
1147 digest_algorithm
= ISCSI_DIGEST_CRC32C
;
1150 digest_algorithm
= ISCSI_DIGEST_NONE
;
1153 mv
.currentValue
= digest_algorithm
;
1154 return (setISCSINodeParameter(MIN_MAX_PARAM
, &oid
, &mv
,
1155 ISCSI_LOGIN_PARAM_DATA_DIGEST
));
1158 IMA_API IMA_STATUS
SUN_IMA_GetHeaderDigest(
1160 SUN_IMA_DIGEST_ALGORITHM_VALUE
*algorithm
1163 return (getDigest(oid
, ISCSI_LOGIN_PARAM_HEADER_DIGEST
, algorithm
));
1166 IMA_API IMA_STATUS
SUN_IMA_GetDataDigest(
1168 SUN_IMA_DIGEST_ALGORITHM_VALUE
*algorithm
1171 return (getDigest(oid
, ISCSI_LOGIN_PARAM_DATA_DIGEST
, algorithm
));
1174 typedef struct walk_devlink
{
1180 IMA_STATUS
SUN_IMA_GetLuProperties(
1182 SUN_IMA_LU_PROPERTIES
*pProps
1186 iscsi_lun_list_t
*pLunList
;
1188 IMA_BOOL lunMatch
= IMA_FALSE
;
1191 iscsi_lun_props_t lun
;
1192 di_devlink_handle_t hdl
;
1193 walk_devlink_t warg
;
1194 char *minor_path
, *devlinkp
, lunpath
[MAXPATHLEN
];
1196 if (luId
.objectType
!= IMA_OBJECT_TYPE_LU
) {
1197 return (IMA_ERROR_INCORRECT_OBJECT_TYPE
);
1201 * get list of lun oids for all targets
1203 status
= get_target_lun_oid_list(NULL
, &pLunList
);
1204 if (!IMA_SUCCESS(status
)) {
1207 for (j
= 0; j
< pLunList
->ll_out_cnt
; j
++) {
1209 * for each lun, check if match is found
1211 if (pLunList
->ll_luns
[j
].l_oid
== luId
.objectSequenceNumber
) {
1213 * match found, break out of lun loop
1215 lunMatch
= IMA_TRUE
;
1220 if (lunMatch
== IMA_TRUE
) {
1221 (void) memset(&lun
, 0, sizeof (iscsi_lun_props_t
));
1222 lun
.lp_vers
= ISCSI_INTERFACE_VERSION
;
1223 lun
.lp_tgt_oid
= pLunList
->ll_luns
[j
].l_tgt_oid
;
1224 lun
.lp_oid
= pLunList
->ll_luns
[j
].l_oid
;
1229 if (lunMatch
== IMA_FALSE
) {
1230 return (IMA_ERROR_OBJECT_NOT_FOUND
);
1234 * get lun properties
1236 if ((openStatus
= open_driver(&fd
))) {
1237 return (SUN_IMA_ERROR_SYSTEM_ERROR
| openStatus
);
1240 if (ioctl(fd
, ISCSI_LUN_PROPS_GET
, &lun
)) {
1241 syslog(LOG_USER
|LOG_DEBUG
,
1242 "ISCSI_LUN_PROPS_GET ioctl failed, errno: %d", errno
);
1243 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1249 * set property values
1251 pProps
->imaProps
.associatedTargetOid
.objectType
=
1252 IMA_OBJECT_TYPE_TARGET
;
1253 pProps
->imaProps
.associatedTargetOid
.ownerId
= 1;
1254 pProps
->imaProps
.associatedTargetOid
.objectSequenceNumber
= lun
.lp_oid
;
1255 pProps
->imaProps
.targetLun
= (IMA_UINT64
)lun
.lp_num
;
1256 (void) strncpy(pProps
->vendorId
, lun
.lp_vid
, SUN_IMA_LU_VENDOR_ID_LEN
);
1257 (void) strncpy(pProps
->productId
, lun
.lp_pid
,
1258 SUN_IMA_LU_PRODUCT_ID_LEN
);
1260 * lun.lp_status is defined as
1262 * LunDoesNotExist = 1
1263 * IMA_LU_PROPS.exposedtoOS is defined as an IMA_BOOL
1267 pProps
->imaProps
.exposedToOs
= !lun
.lp_status
;
1268 if (gmtime_r(&lun
.lp_time_online
, &pProps
->imaProps
.timeExposedToOs
)
1270 (void) memset(&pProps
->imaProps
.timeExposedToOs
, 0,
1271 sizeof (pProps
->imaProps
.timeExposedToOs
));
1274 if (lun
.lp_status
== LunValid
) {
1275 if ((strlen(lun
.lp_pathname
) + strlen("/devices")) >
1278 * lun.lp_pathname length too long
1280 pProps
->imaProps
.osDeviceNameValid
= IMA_FALSE
;
1281 pProps
->imaProps
.osParallelIdsValid
= IMA_FALSE
;
1282 return (IMA_STATUS_SUCCESS
);
1284 if ((strstr(lun
.lp_pathname
, "st@") != NULL
) ||
1285 (strstr(lun
.lp_pathname
, "tape@") != NULL
)) {
1286 (void) strlcat(lun
.lp_pathname
, ":n", MAXPATHLEN
);
1287 } else if ((strstr(lun
.lp_pathname
, "sd@") != NULL
) ||
1288 (strstr(lun
.lp_pathname
, "ssd@") != NULL
) ||
1289 (strstr(lun
.lp_pathname
, "disk@") != NULL
)) {
1291 * modify returned pathname to obtain the 2nd slice
1294 (void) strlcat(lun
.lp_pathname
, ":c,raw", MAXPATHLEN
);
1295 } else if ((strstr(lun
.lp_pathname
, "ses@") != NULL
) ||
1296 (strstr(lun
.lp_pathname
, "enclosure@") != NULL
)) {
1297 (void) strlcat(lun
.lp_pathname
, ":0", MAXPATHLEN
);
1300 (void) snprintf(lunpath
, sizeof (lun
.lp_pathname
),
1301 "/devices%s", lun
.lp_pathname
);
1302 if (strchr(lunpath
, ':')) {
1303 minor_path
= lunpath
;
1304 if (strstr(minor_path
, "/devices") != NULL
) {
1305 minor_path
= lunpath
+
1308 minor_path
= lunpath
;
1313 warg
.len
= strlen(lunpath
);
1314 warg
.path
= lunpath
;
1317 warg
.linkpp
= &devlinkp
;
1320 * Pathname returned by driver is the physical device path.
1321 * This name needs to be converted to the OS device name.
1323 if (hdl
= di_devlink_init(lun
.lp_pathname
, DI_MAKE_LINK
)) {
1324 pProps
->imaProps
.osDeviceName
[0] = L
'\0';
1325 (void) di_devlink_walk(hdl
, NULL
, minor_path
,
1326 DI_PRIMARY_LINK
, (void *)&warg
, get_lun_devlink
);
1327 if (devlinkp
!= NULL
) {
1328 (void) mbstowcs(pProps
->imaProps
.osDeviceName
,
1329 devlinkp
, MAXPATHLEN
);
1331 pProps
->imaProps
.osDeviceNameValid
= IMA_TRUE
;
1333 /* OS device name is asynchronously made */
1334 pProps
->imaProps
.osDeviceNameValid
= IMA_FALSE
;
1337 (void) di_devlink_fini(&hdl
);
1340 pProps
->imaProps
.osDeviceNameValid
= IMA_FALSE
;
1344 pProps
->imaProps
.osDeviceNameValid
= IMA_FALSE
;
1347 pProps
->imaProps
.osParallelIdsValid
= IMA_FALSE
;
1349 return (IMA_STATUS_SUCCESS
);
1353 get_lun_devlink(di_devlink_t link
, void *arg
)
1355 walk_devlink_t
*warg
= (walk_devlink_t
*)arg
;
1357 char *content
= (char *)di_devlink_content(link
);
1358 char *start
= strstr(content
, "/devices");
1359 if (start
== NULL
||
1360 strncmp(start
, warg
->path
, warg
->len
) != 0 ||
1361 start
[warg
->len
] != ':')
1362 return (DI_WALK_CONTINUE
);
1365 *(warg
->linkpp
) = strdup(di_devlink_path(link
));
1366 return (DI_WALK_TERMINATE
);
1371 * SUN_IMA_GetConnectionOidList -
1373 * Non-IMA defined function.
1375 IMA_API IMA_STATUS
SUN_IMA_GetConnOidList(
1377 IMA_OID_LIST
**ppList
1380 IMA_STATUS imaStatus
;
1381 IMA_OID_LIST
*imaOidList
;
1382 iscsi_conn_list_t
*iscsiConnList
= NULL
;
1386 if ((lhbaObjectId
.objectType
== oid
->objectType
) &&
1387 (lhbaObjectId
.ownerId
== oid
->ownerId
) &&
1388 (lhbaObjectId
.objectSequenceNumber
== oid
->objectSequenceNumber
)) {
1389 imaStatus
= getConnOidList(NULL
, &iscsiConnList
);
1391 if (oid
->objectType
== IMA_OBJECT_TYPE_TARGET
) {
1392 imaStatus
= getConnOidList(oid
, &iscsiConnList
);
1394 return (IMA_ERROR_INCORRECT_OBJECT_TYPE
);
1397 if (imaStatus
!= IMA_STATUS_SUCCESS
) {
1402 * Based on the results a SUN_IMA_CONN_LIST structure is allocated.
1404 allocLen
= iscsiConnList
->cl_out_cnt
* sizeof (IMA_OID
);
1405 allocLen
+= sizeof (IMA_OID_LIST
) - sizeof (IMA_OID
);
1406 imaOidList
= (IMA_OID_LIST
*)calloc(1, allocLen
);
1408 if (imaOidList
== NULL
) {
1409 free(iscsiConnList
);
1410 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
1413 /* The data is transfered from iscsiConnList to imaConnList. */
1414 imaOidList
->oidCount
= iscsiConnList
->cl_out_cnt
;
1415 for (i
= 0; i
< iscsiConnList
->cl_out_cnt
; i
++) {
1416 imaOidList
->oids
[i
].objectType
= SUN_IMA_OBJECT_TYPE_CONN
;
1417 imaOidList
->oids
[i
].ownerId
= 1;
1418 imaOidList
->oids
[i
].objectSequenceNumber
=
1419 iscsiConnList
->cl_list
[i
].c_oid
;
1421 /* The pointer to the SUN_IMA_CONN_LIST structure is returned. */
1422 *ppList
= imaOidList
;
1424 free(iscsiConnList
);
1425 return (IMA_STATUS_SUCCESS
);
1429 * SUN_IMA_GetConnProperties -
1431 * Non-IMA defined function.
1433 IMA_API IMA_STATUS
SUN_IMA_GetConnProperties(
1435 SUN_IMA_CONN_PROPERTIES
**pProps
1438 iscsi_conn_list_t
*pConnList
;
1439 iscsi_conn_props_t
*pConnProps
;
1441 struct sockaddr_in6
*addrIn6
;
1443 struct sockaddr_in
*addrIn
;
1444 SUN_IMA_CONN_PROPERTIES
*pImaConnProps
;
1445 IMA_STATUS imaStatus
;
1448 /* If there is any error *pProps should be set to NULL */
1451 pImaConnProps
= (SUN_IMA_CONN_PROPERTIES
*)calloc(1,
1452 sizeof (SUN_IMA_CONN_PROPERTIES
));
1454 if (pImaConnProps
== NULL
) {
1455 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
1458 imaStatus
= getConnOidList(NULL
, &pConnList
);
1460 if (imaStatus
!= IMA_STATUS_SUCCESS
) {
1461 free(pImaConnProps
);
1466 * Walk the list returned to find our connection.
1468 for (i
= 0; i
< pConnList
->cl_out_cnt
; i
++) {
1470 if (pConnList
->cl_list
[i
].c_oid
==
1471 (uint32_t)connOid
->objectSequenceNumber
) {
1473 /* This is our connection. */
1474 imaStatus
= getConnProps(&pConnList
->cl_list
[i
],
1477 if (imaStatus
!= IMA_STATUS_SUCCESS
) {
1479 free(pImaConnProps
);
1482 pImaConnProps
->connectionID
= pConnProps
->cp_cid
;
1487 if (pConnProps
->cp_local
.soa4
.sin_family
== AF_INET
) {
1489 pImaConnProps
->local
.ipAddress
.ipv4Address
=
1491 pImaConnProps
->local
.portNumber
=
1492 pConnProps
->cp_local
.soa4
.sin_port
;
1493 addrIn
= &(pConnProps
->cp_local
.soa4
);
1494 bcopy(&pConnProps
->cp_local
.soa4
.sin_addr
,
1495 pImaConnProps
->local
.ipAddress
.ipAddress
,
1496 sizeof (addrIn
->sin_addr
));
1499 pImaConnProps
->local
.ipAddress
.ipv4Address
=
1501 pImaConnProps
->local
.portNumber
=
1502 pConnProps
->cp_local
.soa6
.sin6_port
;
1503 addrIn6
= &(pConnProps
->cp_local
.soa6
);
1504 bcopy(&pConnProps
->cp_local
.soa6
.sin6_addr
,
1505 pImaConnProps
->local
.ipAddress
.ipAddress
,
1506 sizeof (addrIn6
->sin6_addr
));
1513 if (pConnProps
->cp_peer
.soa4
.sin_family
== AF_INET
) {
1515 pImaConnProps
->peer
.ipAddress
.ipv4Address
=
1517 pImaConnProps
->peer
.portNumber
=
1518 pConnProps
->cp_peer
.soa4
.sin_port
;
1519 addrIn
= &(pConnProps
->cp_local
.soa4
);
1520 bcopy(&pConnProps
->cp_peer
.soa4
.sin_addr
,
1521 pImaConnProps
->peer
.ipAddress
.ipAddress
,
1522 sizeof (addrIn
->sin_addr
));
1525 pImaConnProps
->peer
.ipAddress
.ipv4Address
=
1527 pImaConnProps
->peer
.portNumber
=
1528 pConnProps
->cp_peer
.soa6
.sin6_port
;
1530 addrIn6
= &pConnProps
->cp_local
.soa6
;
1531 bcopy(&pConnProps
->cp_peer
.soa6
.sin6_addr
,
1532 pImaConnProps
->peer
.ipAddress
.ipAddress
,
1533 sizeof (addrIn6
->sin6_addr
));
1537 pImaConnProps
->valuesValid
=
1538 pConnProps
->cp_params_valid
;
1539 pImaConnProps
->defaultTime2Retain
=
1540 pConnProps
->cp_params
.default_time_to_retain
;
1541 pImaConnProps
->defaultTime2Wait
=
1542 pConnProps
->cp_params
.default_time_to_wait
;
1543 pImaConnProps
->errorRecoveryLevel
=
1544 pConnProps
->cp_params
.error_recovery_level
;
1545 pImaConnProps
->firstBurstLength
=
1546 pConnProps
->cp_params
.first_burst_length
;
1547 pImaConnProps
->maxBurstLength
=
1548 pConnProps
->cp_params
.max_burst_length
;
1549 pImaConnProps
->maxConnections
=
1550 pConnProps
->cp_params
.max_connections
;
1551 pImaConnProps
->maxOutstandingR2T
=
1552 pConnProps
->cp_params
.max_outstanding_r2t
;
1553 pImaConnProps
->maxRecvDataSegmentLength
=
1554 pConnProps
->cp_params
.max_recv_data_seg_len
;
1556 pImaConnProps
->dataPduInOrder
=
1557 pConnProps
->cp_params
.data_pdu_in_order
;
1558 pImaConnProps
->dataSequenceInOrder
=
1559 pConnProps
->cp_params
.data_sequence_in_order
;
1560 pImaConnProps
->immediateData
=
1561 pConnProps
->cp_params
.immediate_data
;
1562 pImaConnProps
->initialR2T
=
1563 pConnProps
->cp_params
.initial_r2t
;
1565 pImaConnProps
->headerDigest
=
1566 pConnProps
->cp_params
.header_digest
;
1567 pImaConnProps
->dataDigest
=
1568 pConnProps
->cp_params
.data_digest
;
1575 *pProps
= pImaConnProps
;
1576 return (IMA_STATUS_SUCCESS
);
1581 * SUN_IMA_GetConfigSessions -
1583 * Non-IMA defined function.
1585 IMA_API IMA_STATUS
SUN_IMA_GetConfigSessions(
1587 SUN_IMA_CONFIG_SESSIONS
**pConfigSessions
1592 iscsi_config_sess_t
*ics
;
1595 /* Allocate and setup initial buffer */
1596 size
= sizeof (*ics
);
1597 ics
= (iscsi_config_sess_t
*)calloc(1, size
);
1599 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
1601 ics
->ics_ver
= ISCSI_INTERFACE_VERSION
;
1602 ics
->ics_oid
= targetOid
.objectSequenceNumber
;
1605 /* Open driver devctl for ioctl */
1606 if ((status
= open_driver(&fd
))) {
1607 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
1610 /* Issue ioctl request */
1611 if (ioctl(fd
, ISCSI_GET_CONFIG_SESSIONS
, ics
) != 0) {
1612 syslog(LOG_USER
|LOG_DEBUG
,
1613 "ISCSI_GET_CONFIG_SESSIONS ioctl failed, errno: %d",
1617 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1620 /* Check if we need to collect more information */
1624 /* Free old buffer and reallocate re-sized buffer */
1626 size
= ISCSI_SESSION_CONFIG_SIZE(idx
);
1627 ics
= (iscsi_config_sess_t
*)calloc(1, size
);
1629 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
1631 ics
->ics_ver
= ISCSI_INTERFACE_VERSION
;
1632 ics
->ics_oid
= targetOid
.objectSequenceNumber
;
1635 /* Issue ioctl request */
1636 if (ioctl(fd
, ISCSI_GET_CONFIG_SESSIONS
, ics
) != 0) {
1637 syslog(LOG_USER
|LOG_DEBUG
,
1638 "ISCSI_GET_CONFIG_SESSIONS ioctl failed, errno: %d",
1642 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1647 /* Allocate output buffer */
1648 size
= sizeof (SUN_IMA_CONFIG_SESSIONS
) +
1649 ((ics
->ics_out
- 1) * sizeof (IMA_ADDRESS_KEY
));
1650 *pConfigSessions
= (SUN_IMA_CONFIG_SESSIONS
*)calloc(1, size
);
1651 if ((*pConfigSessions
) == NULL
) {
1652 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
1655 /* Copy output information */
1656 (*pConfigSessions
)->bound
=
1657 (ics
->ics_bound
== B_TRUE
? IMA_TRUE
: IMA_FALSE
);
1658 (*pConfigSessions
)->in
= ics
->ics_in
;
1659 (*pConfigSessions
)->out
= ics
->ics_out
;
1660 for (idx
= 0; idx
< ics
->ics_in
; idx
++) {
1661 if (ics
->ics_bindings
[idx
].i_insize
==
1662 sizeof (struct in_addr
)) {
1663 (*pConfigSessions
)->bindings
[idx
].ipAddress
.
1664 ipv4Address
= IMA_TRUE
;
1665 bcopy(&ics
->ics_bindings
[idx
].i_addr
.in4
,
1666 (*pConfigSessions
)->bindings
[idx
].ipAddress
.
1667 ipAddress
, sizeof (struct in_addr
));
1669 (*pConfigSessions
)->bindings
[idx
].ipAddress
.
1670 ipv4Address
= IMA_FALSE
;
1671 bcopy(&ics
->ics_bindings
[idx
].i_addr
.in6
,
1672 (*pConfigSessions
)->bindings
[idx
].ipAddress
.
1673 ipAddress
, sizeof (struct in6_addr
));
1678 return (IMA_STATUS_SUCCESS
);
1682 * SUN_IMA_SetConfigSessions -
1684 * Non-IMA defined function.
1686 IMA_API IMA_STATUS
SUN_IMA_SetConfigSessions(
1688 SUN_IMA_CONFIG_SESSIONS
*pConfigSessions
1693 iscsi_config_sess_t
*ics
;
1696 /* verify allowed range of sessions */
1697 if ((pConfigSessions
->in
< ISCSI_MIN_CONFIG_SESSIONS
) ||
1698 (pConfigSessions
->in
> ISCSI_MAX_CONFIG_SESSIONS
)) {
1699 return (IMA_ERROR_INVALID_PARAMETER
);
1702 /* allocate record config_sess size */
1703 size
= ISCSI_SESSION_CONFIG_SIZE(pConfigSessions
->in
);
1704 ics
= (iscsi_config_sess_t
*)malloc(size
);
1706 /* setup config_sess information */
1707 (void) memset(ics
, 0, sizeof (iscsi_config_sess_t
));
1708 ics
->ics_ver
= ISCSI_INTERFACE_VERSION
;
1709 ics
->ics_oid
= targetOid
.objectSequenceNumber
;
1711 (pConfigSessions
->bound
== IMA_TRUE
? B_TRUE
: B_FALSE
);
1712 ics
->ics_in
= pConfigSessions
->in
;
1713 for (idx
= 0; idx
< ics
->ics_in
; idx
++) {
1714 if (pConfigSessions
->bindings
[idx
].ipAddress
.
1715 ipv4Address
== IMA_TRUE
) {
1716 ics
->ics_bindings
[idx
].i_insize
=
1717 sizeof (struct in_addr
);
1718 bcopy(pConfigSessions
->bindings
[idx
].
1719 ipAddress
.ipAddress
,
1720 &ics
->ics_bindings
[idx
].i_addr
.in4
,
1721 sizeof (struct in_addr
));
1723 ics
->ics_bindings
[idx
].i_insize
=
1724 sizeof (struct in6_addr
);
1725 bcopy(pConfigSessions
->bindings
[idx
].
1726 ipAddress
.ipAddress
,
1727 &ics
->ics_bindings
[idx
].i_addr
.in6
,
1728 sizeof (struct in6_addr
));
1733 if ((status
= open_driver(&fd
))) {
1735 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
1738 /* issue ioctl request */
1739 if (ioctl(fd
, ISCSI_SET_CONFIG_SESSIONS
, ics
) != 0) {
1740 syslog(LOG_USER
|LOG_DEBUG
,
1741 "ISCSI_SET_CONFIG_SESSIONS ioctl failed, errno: %d",
1745 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1749 return (IMA_STATUS_SUCCESS
);
1752 /* A helper function to obtain iSCSI node parameters. */
1754 getISCSINodeParameter(
1763 iscsi_param_get_t pg
;
1765 if ((status
= open_driver(&fd
))) {
1766 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
1769 (void) memset(&pg
, 0, sizeof (iscsi_param_get_t
));
1770 pg
.g_vers
= ISCSI_INTERFACE_VERSION
;
1771 pg
.g_oid
= (uint32_t)oid
->objectSequenceNumber
;
1772 pg
.g_param
= paramIndex
;
1773 pg
.g_param_type
= ISCSI_SESS_PARAM
;
1775 if (ioctl(fd
, ISCSI_PARAM_GET
, &pg
) != 0) {
1776 syslog(LOG_USER
|LOG_DEBUG
,
1777 "ISCSI_PARAM_GET ioctl failed, errno: %d", errno
);
1779 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1782 switch (paramType
) {
1784 IMA_MIN_MAX_VALUE
*mp
;
1787 mp
= (IMA_MIN_MAX_VALUE
*)pProps
;
1789 mp
->currentValueValid
=
1790 (pg
.g_value
.v_valid
== B_TRUE
) ?
1791 IMA_TRUE
: IMA_FALSE
;
1792 mp
->currentValue
= pg
.g_value
.v_integer
.i_current
;
1793 mp
->defaultValue
= pg
.g_value
.v_integer
.i_default
;
1794 mp
->minimumValue
= pg
.g_value
.v_integer
.i_min
;
1795 mp
->maximumValue
= pg
.g_value
.v_integer
.i_max
;
1796 mp
->incrementValue
= pg
.g_value
.v_integer
.i_incr
;
1800 bp
= (IMA_BOOL_VALUE
*)pProps
;
1801 bp
->currentValueValid
=
1802 (pg
.g_value
.v_valid
== B_TRUE
) ?
1803 IMA_TRUE
: IMA_FALSE
;
1804 bp
->currentValue
= pg
.g_value
.v_bool
.b_current
;
1805 bp
->defaultValue
= pg
.g_value
.v_bool
.b_default
;
1812 /* Issue ISCSI_PARAM_GET ioctl again to obtain connection parameters. */
1813 pg
.g_param_type
= ISCSI_CONN_PARAM
;
1814 if (ioctl(fd
, ISCSI_PARAM_GET
, &pg
) != 0) {
1815 syslog(LOG_USER
|LOG_DEBUG
,
1816 "ISCSI_PARAM_GET ioctl failed, errno: %d", errno
);
1818 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1822 return (IMA_STATUS_SUCCESS
);
1825 /* A helper function to set iSCSI node parameters. */
1827 setISCSINodeParameter(
1836 iscsi_param_set_t ps
;
1838 if ((status
= open_driver(&fd
))) {
1839 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
1842 (void) memset(&ps
, 0, sizeof (iscsi_param_set_t
));
1843 ps
.s_vers
= ISCSI_INTERFACE_VERSION
;
1844 ps
.s_oid
= (uint32_t)oid
->objectSequenceNumber
;
1845 ps
.s_param
= paramIndex
;
1847 switch (paramType
) {
1849 IMA_MIN_MAX_VALUE
*mp
;
1852 mp
= (IMA_MIN_MAX_VALUE
*)pProp
;
1853 ps
.s_value
.v_integer
= mp
->currentValue
;
1856 bp
= (IMA_BOOL_VALUE
*)pProp
;
1858 (bp
->currentValue
== IMA_TRUE
) ?
1865 if (ioctl(fd
, ISCSI_PARAM_SET
, &ps
)) {
1867 syslog(LOG_USER
|LOG_DEBUG
,
1868 "ISCSI_PARAM_SET ioctl failed, errno: %d", errno
);
1869 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1873 return (IMA_STATUS_SUCCESS
);
1877 prepare_discovery_entry(
1878 SUN_IMA_TARGET_ADDRESS discoveryAddress
,
1882 return (prepare_discovery_entry_IMA(discoveryAddress
.imaStruct
, entry
));
1886 prepare_discovery_entry_IMA(
1887 IMA_TARGET_ADDRESS discoveryAddress
,
1891 (void) memset(entry
, 0, sizeof (entry_t
));
1892 entry
->e_vers
= ISCSI_INTERFACE_VERSION
;
1893 entry
->e_oid
= ISCSI_OID_NOTSET
;
1895 if (discoveryAddress
.hostnameIpAddress
.id
.ipAddress
.
1896 ipv4Address
== IMA_FALSE
) {
1898 bcopy(discoveryAddress
.hostnameIpAddress
.id
.ipAddress
.
1899 ipAddress
, entry
->e_u
.u_in6
.s6_addr
,
1900 sizeof (entry
->e_u
.u_in6
.s6_addr
));
1902 entry
->e_insize
= sizeof (struct in6_addr
);
1905 bcopy(discoveryAddress
.hostnameIpAddress
.id
.ipAddress
.
1906 ipAddress
, &entry
->e_u
.u_in4
.s_addr
,
1907 sizeof (entry
->e_u
.u_in4
.s_addr
));
1909 entry
->e_insize
= sizeof (struct in_addr
);
1912 entry
->e_port
= discoveryAddress
.portNumber
;
1914 return (DISC_ADDR_OK
);
1917 static IMA_STATUS
configure_discovery_method(
1919 iSCSIDiscoveryMethod_t method
1924 if ((status
= open_driver(&fd
))) {
1925 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
1928 if (enable
== IMA_FALSE
) {
1929 if (ioctl(fd
, ISCSI_DISCOVERY_CLEAR
, &method
)) {
1932 syslog(LOG_USER
|LOG_DEBUG
,
1933 "ISCSI_DISCOVERY_CLEAR ioctl failed, errno: %d",
1935 if (status
== EBUSY
) {
1936 return (IMA_ERROR_LU_IN_USE
);
1938 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1943 return (IMA_STATUS_SUCCESS
);
1945 /* Set the discovery method */
1946 if (ioctl(fd
, ISCSI_DISCOVERY_SET
, &method
)) {
1949 syslog(LOG_USER
|LOG_DEBUG
,
1950 "ISCSI_DISCOVERY_SET ioctl failed, errno: %d",
1952 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1956 return (IMA_STATUS_SUCCESS
);
1960 /* LINTED E_STATIC_UNUSED */
1961 static IMA_BOOL
authMethodMatch(
1962 IMA_AUTHMETHOD matchingMethod
,
1963 IMA_AUTHMETHOD
*methodList
,
1969 for (i
= 0; i
< maxEntries
; i
++) {
1970 if (methodList
[i
] == matchingMethod
) {
1978 static IMA_STATUS
get_target_oid_list(
1979 uint32_t targetListType
,
1980 IMA_OID_LIST
**ppList
)
1984 int target_list_size
;
1987 iscsi_target_list_t
*idlp
;
1989 if ((status
= open_driver(&fd
))) {
1990 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
1993 idlp
= (iscsi_target_list_t
*)calloc(1, sizeof (iscsi_target_list_t
));
1996 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
1998 idlp
->tl_vers
= ISCSI_INTERFACE_VERSION
;
1999 idlp
->tl_in_cnt
= idlp
->tl_out_cnt
= 1;
2000 idlp
->tl_tgt_list_type
= targetListType
;
2003 * Issue ioctl. Space has been allocted for one entry.
2004 * If more than one entry should be returned, we will re-issue the
2005 * entry with the right amount of space allocted
2007 if (ioctl(fd
, ISCSI_TARGET_OID_LIST_GET
, idlp
) != 0) {
2009 syslog(LOG_USER
|LOG_DEBUG
,
2010 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
2011 targetListType
, errno
);
2012 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2014 if (idlp
->tl_out_cnt
> 1) {
2015 out_cnt
= idlp
->tl_out_cnt
;
2018 target_list_size
= sizeof (iscsi_target_list_t
);
2019 target_list_size
+= (sizeof (uint32_t) * out_cnt
- 1);
2020 idlp
= (iscsi_target_list_t
*)calloc(1, target_list_size
);
2023 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2025 idlp
->tl_vers
= ISCSI_INTERFACE_VERSION
;
2026 idlp
->tl_in_cnt
= out_cnt
;
2027 idlp
->tl_tgt_list_type
= targetListType
;
2029 /* Issue the same ioctl again to obtain all the OIDs. */
2030 if (ioctl(fd
, ISCSI_TARGET_OID_LIST_GET
, idlp
) != 0) {
2031 #define ERROR_STR "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno :%d"
2034 syslog(LOG_USER
|LOG_DEBUG
,
2035 ERROR_STR
, targetListType
, errno
);
2036 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2042 *ppList
= (IMA_OID_LIST
*)calloc(1, sizeof (IMA_OID_LIST
) +
2043 idlp
->tl_out_cnt
* sizeof (IMA_OID
));
2044 (*ppList
)->oidCount
= idlp
->tl_out_cnt
;
2045 for (i
= 0; i
< idlp
->tl_out_cnt
; i
++) {
2046 (*ppList
)->oids
[i
].objectType
= IMA_OBJECT_TYPE_TARGET
;
2047 (*ppList
)->oids
[i
].ownerId
= 1;
2048 (*ppList
)->oids
[i
].objectSequenceNumber
= idlp
->tl_oid_list
[i
];
2053 return (IMA_STATUS_SUCCESS
);
2056 static IMA_STATUS
get_target_lun_oid_list(
2057 IMA_OID
* targetOid
,
2058 iscsi_lun_list_t
**ppLunList
)
2061 iscsi_lun_list_t
*illp
, *illp_saved
;
2065 if ((status
= open_driver(&fd
))) {
2066 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
2069 illp
= (iscsi_lun_list_t
*)calloc(1, sizeof (iscsi_lun_list_t
));
2072 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2074 illp
->ll_vers
= ISCSI_INTERFACE_VERSION
;
2075 if (targetOid
== NULL
) {
2076 /* get lun oid list for all targets */
2077 illp
->ll_all_tgts
= B_TRUE
;
2079 /* get lun oid list for single target */
2080 illp
->ll_all_tgts
= B_FALSE
;
2081 illp
->ll_tgt_oid
= (uint32_t)targetOid
->objectSequenceNumber
;
2083 illp
->ll_in_cnt
= illp
->ll_out_cnt
= 1;
2086 * Issue ioctl to retrieve the target luns. Space has been allocted
2087 * for one entry. If more than one entry should be returned, we
2088 * will re-issue the entry with the right amount of space allocted
2090 if (ioctl(fd
, ISCSI_LUN_OID_LIST_GET
, illp
) != 0) {
2092 syslog(LOG_USER
|LOG_DEBUG
,
2093 "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", errno
);
2094 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2097 if (illp
->ll_out_cnt
> 1) {
2099 lun_list_size
= sizeof (iscsi_lun_list_t
);
2100 lun_list_size
+= (sizeof (iscsi_if_lun_t
) *
2101 (illp
->ll_out_cnt
- 1));
2102 illp
= (iscsi_lun_list_t
*)calloc(1, lun_list_size
);
2105 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2107 illp
->ll_vers
= ISCSI_INTERFACE_VERSION
;
2108 illp
->ll_all_tgts
= illp_saved
->ll_all_tgts
;
2109 illp
->ll_tgt_oid
= illp_saved
->ll_tgt_oid
;
2110 illp
->ll_in_cnt
= illp_saved
->ll_out_cnt
;
2114 /* Issue the same ioctl again to get all the target LUN list */
2115 if (ioctl(fd
, ISCSI_LUN_OID_LIST_GET
, illp
) != 0) {
2118 syslog(LOG_USER
|LOG_DEBUG
,
2119 "ISCSI_LUN_LIST_GET ioctl failed, errno: %d",
2121 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2129 return (IMA_STATUS_SUCCESS
);
2132 /* A helper function to obtain digest algorithms. */
2137 SUN_IMA_DIGEST_ALGORITHM_VALUE
*algorithm
2140 IMA_MIN_MAX_VALUE pProps
;
2143 if ((status
= getISCSINodeParameter(MIN_MAX_PARAM
, &oid
, &pProps
,
2144 ioctlCmd
)) != IMA_STATUS_SUCCESS
) {
2148 switch (pProps
.defaultValue
) {
2149 case ISCSI_DIGEST_NONE
:
2150 algorithm
->defaultAlgorithms
[0] = ISCSI_DIGEST_NONE
;
2151 algorithm
->defaultAlgorithmCount
= 1;
2153 case ISCSI_DIGEST_CRC32C
:
2154 algorithm
->defaultAlgorithms
[0] = ISCSI_DIGEST_CRC32C
;
2155 algorithm
->defaultAlgorithmCount
= 1;
2158 case ISCSI_DIGEST_CRC32C_NONE
:
2159 algorithm
->defaultAlgorithms
[0] = ISCSI_DIGEST_CRC32C
;
2160 algorithm
->defaultAlgorithms
[1] = ISCSI_DIGEST_NONE
;
2161 algorithm
->defaultAlgorithmCount
= 2;
2163 case ISCSI_DIGEST_NONE_CRC32C
:
2164 algorithm
->defaultAlgorithms
[0] = ISCSI_DIGEST_NONE
;
2165 algorithm
->defaultAlgorithms
[1] = ISCSI_DIGEST_CRC32C
;
2166 algorithm
->defaultAlgorithmCount
= 2;
2170 syslog(LOG_USER
|LOG_DEBUG
,
2171 "Invalid default digest: %d", pProps
.defaultValue
);
2172 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2175 /* The configured value */
2176 if (pProps
.currentValueValid
== IMA_TRUE
) {
2177 algorithm
->currentValid
= IMA_TRUE
;
2179 switch (pProps
.currentValue
) {
2180 case ISCSI_DIGEST_NONE
:
2181 algorithm
->currentAlgorithms
[0] =
2183 algorithm
->currentAlgorithmCount
= 1;
2185 case ISCSI_DIGEST_CRC32C
:
2186 algorithm
->currentAlgorithms
[0] =
2187 ISCSI_DIGEST_CRC32C
;
2188 algorithm
->currentAlgorithmCount
= 1;
2191 case ISCSI_DIGEST_CRC32C_NONE
:
2192 algorithm
->currentAlgorithms
[0] =
2193 ISCSI_DIGEST_CRC32C
;
2194 algorithm
->currentAlgorithms
[1] =
2196 algorithm
->currentAlgorithmCount
= 2;
2198 case ISCSI_DIGEST_NONE_CRC32C
:
2199 algorithm
->currentAlgorithms
[0] =
2201 algorithm
->currentAlgorithms
[1] =
2202 ISCSI_DIGEST_CRC32C
;
2203 algorithm
->currentAlgorithmCount
= 2;
2207 syslog(LOG_USER
|LOG_DEBUG
,
2208 "Invalid configured digest: %d",
2209 pProps
.defaultValue
);
2210 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2214 algorithm
->currentValid
= IMA_FALSE
;
2217 return (IMA_STATUS_SUCCESS
);
2223 static IMA_STATUS
getConnOidList(
2225 iscsi_conn_list_t
**ppConnList
2228 iscsi_conn_list_t
*iscsiConnList
= NULL
;
2234 /* Preset it to NULL to prepare for the case of failure */
2237 /* We try to open the driver now. */
2238 if ((status
= open_driver(&fd
))) {
2239 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
2242 iscsiConnList
= (iscsi_conn_list_t
*)calloc(1,
2243 sizeof (iscsi_conn_list_t
));
2244 if (iscsiConnList
== NULL
) {
2246 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2248 iscsiConnList
->cl_vers
= ISCSI_INTERFACE_VERSION
;
2249 iscsiConnList
->cl_in_cnt
= iscsiConnList
->cl_out_cnt
= 1;
2250 if (sessOid
== NULL
) {
2251 iscsiConnList
->cl_all_sess
= B_TRUE
;
2253 iscsiConnList
->cl_all_sess
= B_FALSE
;
2254 iscsiConnList
->cl_sess_oid
=
2255 (uint32_t)sessOid
->objectSequenceNumber
;
2258 * Issue ioctl to retrieve the connection OIDs. Space has been
2259 * allocated for one entry. If more than one entry should be
2260 * returned, we will re-issue the entry with the right amount of
2263 if (ioctl(fd
, ISCSI_CONN_OID_LIST_GET
, iscsiConnList
) != 0) {
2264 syslog(LOG_USER
|LOG_DEBUG
,
2265 "ISCSI_CONN_OID_LIST_GET ioctl failed, errno: %d", errno
);
2268 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2270 if (iscsiConnList
->cl_out_cnt
> 1) {
2271 out_cnt
= iscsiConnList
->cl_out_cnt
;
2272 free(iscsiConnList
);
2274 allocLen
= sizeof (iscsi_conn_list_t
);
2275 allocLen
+= (sizeof (iscsi_if_conn_t
) * out_cnt
- 1);
2276 iscsiConnList
= (iscsi_conn_list_t
*)calloc(1, allocLen
);
2277 if (iscsiConnList
== NULL
) {
2280 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2282 iscsiConnList
->cl_vers
= ISCSI_INTERFACE_VERSION
;
2283 iscsiConnList
->cl_in_cnt
= out_cnt
;
2284 if (sessOid
== NULL
) {
2285 iscsiConnList
->cl_all_sess
= B_TRUE
;
2287 iscsiConnList
->cl_all_sess
= B_FALSE
;
2288 iscsiConnList
->cl_sess_oid
=
2289 (uint32_t)sessOid
->objectSequenceNumber
;
2291 /* Issue the same ioctl again to obtain all the OIDs */
2292 if (ioctl(fd
, ISCSI_CONN_OID_LIST_GET
, iscsiConnList
) != 0) {
2294 syslog(LOG_USER
|LOG_DEBUG
,
2295 "ISCSI_CONN_OID_LIST_GET ioctl failed, errno: %d",
2298 free(iscsiConnList
);
2300 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2304 if (out_cnt
< iscsiConnList
->cl_out_cnt
) {
2306 * The connection list grew between the first and second
2309 syslog(LOG_USER
|LOG_DEBUG
,
2310 "The connection list has grown. There could be "
2311 "more connections than listed.");
2317 *ppConnList
= iscsiConnList
;
2318 return (IMA_STATUS_SUCCESS
);
2324 static IMA_STATUS
getConnProps(
2325 iscsi_if_conn_t
*pConn
,
2326 iscsi_conn_props_t
**ppConnProps
2329 iscsi_conn_props_t
*iscsiConnProps
;
2333 /* We try to open the driver. */
2334 if ((status
= open_driver(&fd
))) {
2335 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
2338 iscsiConnProps
= (iscsi_conn_props_t
*)calloc(1,
2339 sizeof (*iscsiConnProps
));
2341 if (iscsiConnProps
== NULL
) {
2343 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2346 iscsiConnProps
->cp_vers
= ISCSI_INTERFACE_VERSION
;
2347 iscsiConnProps
->cp_oid
= pConn
->c_oid
;
2348 iscsiConnProps
->cp_cid
= pConn
->c_cid
;
2349 iscsiConnProps
->cp_sess_oid
= pConn
->c_sess_oid
;
2351 /* The IOCTL is submitted. */
2352 if (ioctl(fd
, ISCSI_CONN_PROPS_GET
, iscsiConnProps
) != 0) {
2354 syslog(LOG_USER
|LOG_DEBUG
,
2355 "ISCSI_AUTH_CLEAR ioctl failed, errno: %d", errno
);
2356 free(iscsiConnProps
);
2358 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2361 *ppConnProps
= iscsiConnProps
;
2362 return (IMA_STATUS_SUCCESS
);
2365 /* A helper function to set authentication method. */
2369 IMA_UINT
*pMethodCount
,
2370 const IMA_AUTHMETHOD
*pMethodList
2376 iscsi_auth_props_t auth
;
2378 if ((status
= open_driver(&fd
))) {
2379 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
2381 (void) memset(&auth
, 0, sizeof (iscsi_auth_props_t
));
2382 auth
.a_vers
= ISCSI_INTERFACE_VERSION
;
2383 auth
.a_oid
= (uint32_t)oid
.objectSequenceNumber
;
2386 * Get the current auth fields so they don't need to be reset
2389 if (ioctl(fd
, ISCSI_AUTH_GET
, &auth
) != 0) {
2391 /* Initializing auth structure with current settings */
2393 auth
.a_auth_method
= authMethodNone
;
2395 for (i
= 0; i
< *pMethodCount
; i
++) {
2396 switch (pMethodList
[i
]) {
2397 case IMA_AUTHMETHOD_CHAP
:
2398 auth
.a_auth_method
|= authMethodCHAP
;
2405 if (ioctl(fd
, ISCSI_AUTH_SET
, &auth
) != 0) {
2406 syslog(LOG_USER
|LOG_DEBUG
,
2407 "ISCSI_AUTH_SET failed, errno: %d", errno
);
2409 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2413 return (IMA_STATUS_SUCCESS
);
2416 /* A helper function to set authentication method. */
2417 static IMA_STATUS
getAuthMethods(
2419 IMA_UINT
*pMethodCount
,
2420 IMA_AUTHMETHOD
*pMethodList
2425 iscsi_auth_props_t auth
;
2427 if ((status
= open_driver(&fd
))) {
2428 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
2431 (void) memset(&auth
, 0, sizeof (iscsi_auth_props_t
));
2432 auth
.a_vers
= ISCSI_INTERFACE_VERSION
;
2433 auth
.a_oid
= (uint32_t)oid
.objectSequenceNumber
;
2435 if (ioctl(fd
, ISCSI_AUTH_GET
, &auth
) != 0) {
2436 syslog(LOG_USER
|LOG_DEBUG
,
2437 "ISCSI_AUTH_GET failed, errno: %d", errno
);
2439 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2442 if (auth
.a_auth_method
== authMethodNone
) {
2443 pMethodList
[0] = IMA_AUTHMETHOD_NONE
;
2447 if (!((auth
.a_auth_method
& authMethodCHAP
)^authMethodCHAP
)) {
2448 pMethodList
[i
++] = IMA_AUTHMETHOD_CHAP
;
2454 return (IMA_STATUS_SUCCESS
);
2457 /* Helper function to open driver */
2463 if ((*fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
2465 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
2466 ISCSI_DRIVER_DEVCTL
, ret
);
2472 * Iscsi driver does not support OID for discovery address. Create
2473 * a modified version of IMA_RemoveDiscoveryAddress that takes
2474 * discoveryAddress (instead of an OID) as input argument.
2476 IMA_API IMA_STATUS
SUN_IMA_RemoveDiscoveryAddress(
2477 SUN_IMA_TARGET_ADDRESS discoveryAddress
2482 int status
, i
, addr_list_size
, insize
;
2483 iscsi_addr_list_t
*idlp
, al_info
;
2484 iscsi_addr_t
*matched_addr
= NULL
;
2486 if ((status
= open_driver(&fd
))) {
2487 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
2490 if (prepare_discovery_entry(discoveryAddress
, &entry
) !=
2493 return (IMA_ERROR_INVALID_PARAMETER
);
2496 (void) memset(&al_info
, 0, sizeof (al_info
));
2497 al_info
.al_vers
= ISCSI_INTERFACE_VERSION
;
2498 al_info
.al_in_cnt
= 0;
2500 * Issue ioctl to get the number of discovery address.
2502 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_LIST_GET
, &al_info
) != 0) {
2503 syslog(LOG_USER
|LOG_DEBUG
,
2504 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
2505 ISCSI_DISCOVERY_ADDR_LIST_GET
, errno
);
2507 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2510 if (al_info
.al_out_cnt
== 0) {
2512 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2515 addr_list_size
= sizeof (iscsi_addr_list_t
);
2516 if (al_info
.al_out_cnt
> 1) {
2517 addr_list_size
+= (sizeof (iscsi_addr_t
) *
2518 (al_info
.al_out_cnt
- 1));
2521 idlp
= (iscsi_addr_list_t
*)calloc(1, addr_list_size
);
2524 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2527 idlp
->al_vers
= ISCSI_INTERFACE_VERSION
;
2528 idlp
->al_in_cnt
= al_info
.al_out_cnt
;
2530 /* issue the same ioctl to get all the discovery addresses */
2531 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_LIST_GET
, idlp
) != 0) {
2532 syslog(LOG_USER
|LOG_DEBUG
,
2533 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
2534 ISCSI_DISCOVERY_ADDR_LIST_GET
, errno
);
2537 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2541 * find the matched discovery address
2543 for (i
= 0; i
< idlp
->al_out_cnt
; i
++) {
2544 insize
= idlp
->al_addrs
[i
].a_addr
.i_insize
;
2545 if (insize
!= entry
.e_insize
) {
2548 if (insize
== sizeof (struct in_addr
)) {
2549 if (idlp
->al_addrs
[i
].a_addr
.i_addr
.in4
.s_addr
==
2550 entry
.e_u
.u_in4
.s_addr
) {
2551 matched_addr
= &(idlp
->al_addrs
[i
]);
2555 if (insize
== sizeof (struct in6_addr
)) {
2556 if (bcmp(entry
.e_u
.u_in6
.s6_addr
,
2557 idlp
->al_addrs
[i
].a_addr
.i_addr
.in6
.s6_addr
,
2559 matched_addr
= &(idlp
->al_addrs
[i
]);
2567 if (matched_addr
== NULL
) {
2569 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2572 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_CLEAR
, &entry
)) {
2575 syslog(LOG_USER
|LOG_DEBUG
,
2576 "ISCSI_DISCOVERY_ADDR_CLEAR ioctl failed, errno: %d",
2578 if (status
== EBUSY
) {
2579 return (IMA_ERROR_LU_IN_USE
);
2581 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2586 return (IMA_STATUS_SUCCESS
);
2589 IMA_STATUS
SUN_IMA_SetTargetAuthMethods(
2591 IMA_UINT
*methodCount
,
2592 const IMA_AUTHMETHOD
*pMethodList
2595 return (setAuthMethods(targetOid
, methodCount
, pMethodList
));
2598 IMA_STATUS
getNegotiatedDigest(
2600 SUN_IMA_DIGEST_ALGORITHM_VALUE
*algorithm
,
2601 SUN_IMA_CONN_PROPERTIES
*connProps
) {
2605 if (connProps
->valuesValid
== IMA_TRUE
) {
2606 algorithm
->negotiatedValid
= IMA_TRUE
;
2608 if (digestType
== ISCSI_LOGIN_PARAM_HEADER_DIGEST
) {
2609 digest
= connProps
->headerDigest
;
2611 digest
= connProps
->dataDigest
;
2615 case ISCSI_DIGEST_NONE
:
2616 algorithm
->negotiatedAlgorithms
[0] =
2618 algorithm
->negotiatedAlgorithmCount
= 1;
2620 case ISCSI_DIGEST_CRC32C
:
2621 algorithm
->negotiatedAlgorithms
[0] =
2622 ISCSI_DIGEST_CRC32C
;
2623 algorithm
->negotiatedAlgorithmCount
= 1;
2626 case ISCSI_DIGEST_CRC32C_NONE
:
2627 algorithm
->negotiatedAlgorithms
[0] =
2628 ISCSI_DIGEST_CRC32C
;
2629 algorithm
->negotiatedAlgorithms
[1] =
2631 algorithm
->negotiatedAlgorithmCount
= 2;
2633 case ISCSI_DIGEST_NONE_CRC32C
:
2634 algorithm
->negotiatedAlgorithms
[0] =
2636 algorithm
->negotiatedAlgorithms
[1] =
2637 ISCSI_DIGEST_CRC32C
;
2638 algorithm
->negotiatedAlgorithmCount
= 2;
2641 syslog(LOG_USER
|LOG_DEBUG
,
2642 "Invalid negotiated digest: %d",
2644 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2647 algorithm
->negotiatedValid
= IMA_FALSE
;
2649 return (IMA_STATUS_SUCCESS
);
2653 * Non-IMA defined function.
2655 IMA_API IMA_STATUS
SUN_IMA_GetISNSServerAddressPropertiesList(
2656 SUN_IMA_DISC_ADDR_PROP_LIST
**ppList
2659 char isns_server_addr_str
[256];
2662 int isns_server_addr_list_size
;
2665 iscsi_addr_list_t
*ialp
;
2667 IMA_IP_ADDRESS
*ipAddr
;
2669 if ((status
= open_driver(&fd
))) {
2670 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
2673 ialp
= (iscsi_addr_list_t
*)calloc(1, sizeof (iscsi_addr_list_t
));
2676 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2678 ialp
->al_vers
= ISCSI_INTERFACE_VERSION
;
2679 ialp
->al_in_cnt
= ialp
->al_out_cnt
= 1;
2682 * Issue ioctl to retrieve the isns server addresses. Space has been
2683 * allocted for one entry. If more than one entry should be returned,
2684 * we will re-issue the entry with the right amount of space allocted
2686 if (ioctl(fd
, ISCSI_ISNS_SERVER_ADDR_LIST_GET
, ialp
) != 0) {
2688 syslog(LOG_USER
|LOG_DEBUG
,
2689 "ISCSI_ISNS_SERVER_ADDR_LIST_GET ioctl failed, errno: %d",
2691 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2694 isns_server_addr_list_size
= sizeof (iscsi_addr_list_t
);
2695 if (ialp
->al_out_cnt
> 1) {
2696 out_cnt
= ialp
->al_out_cnt
;
2699 isns_server_addr_list_size
+= (sizeof (iscsi_addr_t
) *
2701 ialp
= (iscsi_addr_list_t
*)calloc(1,
2702 isns_server_addr_list_size
);
2705 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2707 ialp
->al_vers
= ISCSI_INTERFACE_VERSION
;
2708 ialp
->al_in_cnt
= out_cnt
;
2711 * Issue ISCSI_ISNS_SERVER_ADDR_LIST_GET ioctl again to obtain
2712 * the list of all the iSNS server addresses
2714 if (ioctl(fd
, ISCSI_ISNS_SERVER_ADDR_LIST_GET
, ialp
) != 0) {
2717 syslog(LOG_USER
|LOG_DEBUG
,
2718 "ISCSI_ISNS_SERVER_ADDR_LIST_GET ioctl failed, "
2719 "errno: %d", errno
);
2720 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2725 *ppList
= (SUN_IMA_DISC_ADDR_PROP_LIST
*)calloc(1,
2726 sizeof (SUN_IMA_DISC_ADDR_PROP_LIST
) +
2727 ialp
->al_out_cnt
* sizeof (IMA_DISCOVERY_ADDRESS_PROPERTIES
));
2728 if (*ppList
== NULL
) {
2731 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2733 (*ppList
)->discAddrCount
= ialp
->al_out_cnt
;
2735 for (i
= 0; i
< ialp
->al_out_cnt
; i
++) {
2736 if (ialp
->al_addrs
[i
].a_addr
.i_insize
==
2737 sizeof (struct in_addr
)) {
2738 (*ppList
)->props
[i
].discoveryAddress
.hostnameIpAddress
.
2739 id
.ipAddress
.ipv4Address
= IMA_TRUE
;
2740 } else if (ialp
->al_addrs
[i
].a_addr
.i_insize
==
2741 sizeof (struct in6_addr
)) {
2742 (*ppList
)->props
[i
].discoveryAddress
.hostnameIpAddress
.
2743 id
.ipAddress
.ipv4Address
= IMA_FALSE
;
2745 (void) strlcpy(isns_server_addr_str
, "unknown",
2746 sizeof (isns_server_addr_str
));
2749 ipAddr
= &(*ppList
)->props
[i
].discoveryAddress
.
2750 hostnameIpAddress
.id
.ipAddress
;
2751 bcopy(&ialp
->al_addrs
[i
].a_addr
.i_addr
,
2752 (*ppList
)->props
[i
].discoveryAddress
.hostnameIpAddress
.id
.
2753 ipAddress
.ipAddress
,
2754 sizeof (ipAddr
->ipAddress
));
2755 (*ppList
)->props
[i
].discoveryAddress
.portNumber
=
2756 ialp
->al_addrs
[i
].a_port
;
2761 return (IMA_STATUS_SUCCESS
);
2766 * Remove iSNS Server Address
2768 IMA_API IMA_STATUS
SUN_IMA_RemoveISNSServerAddress(
2769 SUN_IMA_TARGET_ADDRESS isnsServerAddress
2775 if ((status
= open_driver(&fd
))) {
2776 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
2779 if (prepare_discovery_entry(isnsServerAddress
, &entry
) !=
2782 return (IMA_ERROR_INVALID_PARAMETER
);
2785 if (ioctl(fd
, ISCSI_ISNS_SERVER_ADDR_CLEAR
, &entry
)) {
2788 syslog(LOG_USER
|LOG_DEBUG
,
2789 "ISCSI_ISNS_SERVER_ADDR_CLEAR ioctl failed, errno: %d",
2791 if (status
== EBUSY
) {
2792 return (IMA_ERROR_LU_IN_USE
);
2794 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2799 return (IMA_STATUS_SUCCESS
);
2803 IMA_API IMA_STATUS
SUN_IMA_AddISNSServerAddress(
2804 const SUN_IMA_TARGET_ADDRESS isnsServerAddress
2811 if ((status
= open_driver(&fd
))) {
2812 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
2815 if (prepare_discovery_entry(isnsServerAddress
, &entry
) !=
2818 return (IMA_ERROR_INVALID_PARAMETER
);
2821 if (ioctl(fd
, ISCSI_ISNS_SERVER_ADDR_SET
, &entry
)) {
2823 * Encountered problem setting the discovery address.
2826 syslog(LOG_USER
|LOG_DEBUG
,
2827 "ISCSI_ISNS_SERVER_ADDR_SET ioctl failed, errno: %d",
2829 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2833 return (IMA_STATUS_SUCCESS
);
2836 IMA_STATUS
SUN_IMA_RetrieveISNSServerTargets(
2837 IMA_TARGET_ADDRESS serverAddress
,
2838 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
**ppList
2843 int server_pg_list_sz
;
2845 isns_server_portal_group_list_t
*server_pg_list
= NULL
;
2846 isns_portal_group_list_t
*pg_list
= NULL
;
2847 IMA_BOOL retry
= IMA_TRUE
;
2850 #define ISNS_SERVER_DEFAULT_NUM_TARGETS 50
2852 server_pg_list_sz
= sizeof (*server_pg_list
) +
2853 ((ISNS_SERVER_DEFAULT_NUM_TARGETS
- 1) *
2854 sizeof (isns_portal_group_t
));
2856 server_pg_list
= (isns_server_portal_group_list_t
*)calloc(1,
2858 if (server_pg_list
== NULL
) {
2859 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2861 server_pg_list
->addr_port_list
.pg_in_cnt
=
2862 ISNS_SERVER_DEFAULT_NUM_TARGETS
;
2864 if ((prepare_discovery_entry_IMA(serverAddress
, &entry
)
2866 free(server_pg_list
);
2867 return (IMA_ERROR_INVALID_PARAMETER
);
2869 server_pg_list
->addr
.a_port
= entry
.e_port
;
2870 server_pg_list
->addr
.a_addr
.i_insize
= entry
.e_insize
;
2871 if (entry
.e_insize
== sizeof (struct in_addr
)) {
2872 server_pg_list
->addr
.a_addr
.i_addr
.in4
.s_addr
=
2873 (entry
.e_u
.u_in4
.s_addr
);
2874 } else if (entry
.e_insize
== sizeof (struct in6_addr
)) {
2875 bcopy(&entry
.e_u
.u_in6
.s6_addr
,
2876 server_pg_list
->addr
.a_addr
.i_addr
.in6
.s6_addr
, 16);
2879 if ((status
= open_driver(&fd
))) {
2880 free(server_pg_list
);
2881 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
2886 * Issue ioctl to obtain the ISNS Portal Group List list
2888 if (ioctl(fd
, ISCSI_ISNS_SERVER_GET
, server_pg_list
) != 0) {
2889 int tmp_errno
= errno
;
2890 IMA_STATUS return_status
;
2892 syslog(LOG_USER
|LOG_DEBUG
,
2893 "ISCSI_ISNS_SERVER_GET ioctl failed, errno: %d", tmp_errno
);
2894 if (tmp_errno
== EACCES
) {
2895 return_status
= IMA_ERROR_OBJECT_NOT_FOUND
;
2897 return_status
= IMA_ERROR_UNEXPECTED_OS_ERROR
;
2900 free(server_pg_list
);
2901 return (return_status
);
2903 pg_list
= &server_pg_list
->addr_port_list
;
2905 /* check if all targets received */
2906 if (pg_list
->pg_in_cnt
< pg_list
->pg_out_cnt
) {
2907 if (retry
== IMA_TRUE
) {
2908 server_pg_list_sz
= sizeof (*server_pg_list
) +
2909 ((pg_list
->pg_out_cnt
- 1) *
2910 sizeof (isns_server_portal_group_list_t
));
2911 server_pg_list
= (isns_server_portal_group_list_t
*)
2912 realloc(server_pg_list
, server_pg_list_sz
);
2913 if (server_pg_list
== NULL
) {
2915 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2917 pg_list
= &server_pg_list
->addr_port_list
;
2918 pg_list
->pg_in_cnt
= pg_list
->pg_out_cnt
;
2923 * don't retry after 2 attempts. The target list
2924 * shouldn't continue growing. Just continue
2925 * on and display what was found.
2927 syslog(LOG_USER
|LOG_DEBUG
,
2928 "ISCSI_SENDTGTS_GET overflow: "
2929 "failed to obtain all targets");
2930 pg_list
->pg_out_cnt
= pg_list
->pg_in_cnt
;
2936 /* allocate for caller return buffer */
2937 *ppList
= (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
*)calloc(1,
2938 sizeof (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
) +
2939 pg_list
->pg_out_cnt
* sizeof (SUN_IMA_DISC_ADDRESS_KEY
));
2940 if (*ppList
== NULL
) {
2941 free(server_pg_list
);
2942 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2945 (*ppList
)->keyCount
= pg_list
->pg_out_cnt
;
2947 for (ctr
= 0; ctr
< pg_list
->pg_out_cnt
; ctr
++) {
2948 (void) mbstowcs((*ppList
)->keys
[ctr
].name
,
2949 (char *)pg_list
->pg_list
[ctr
].pg_iscsi_name
,
2952 (*ppList
)->keys
[ctr
].tpgt
= pg_list
->pg_list
[ctr
].pg_tag
;
2954 (*ppList
)->keys
[ctr
].address
.portNumber
=
2955 pg_list
->pg_list
[ctr
].pg_port
;
2957 if (pg_list
->pg_list
[ctr
].insize
== sizeof (struct in_addr
)) {
2958 (*ppList
)->keys
[ctr
].address
.ipAddress
.ipv4Address
=
2960 } else if (pg_list
->pg_list
[ctr
].insize
==
2961 sizeof (struct in6_addr
)) {
2962 (*ppList
)->keys
[ctr
].address
.ipAddress
.ipv4Address
=
2966 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2969 (void) memcpy(&(*ppList
)->keys
[ctr
].address
.ipAddress
.ipAddress
,
2970 &(pg_list
->pg_list
[ctr
].pg_ip_addr
),
2971 pg_list
->pg_list
[ctr
].insize
);
2973 free(server_pg_list
);
2975 return (IMA_STATUS_SUCCESS
);
2979 IMA_STATUS
SUN_IMA_GetSessionOidList(
2980 IMA_OID initiatorOid
,
2981 IMA_OID_LIST
**ppList
2984 return (get_target_oid_list(ISCSI_TGT_OID_LIST
, ppList
));
2988 IMA_API IMA_STATUS
SUN_IMA_GetTargetAuthParms(
2990 IMA_AUTHMETHOD method
,
2991 IMA_INITIATOR_AUTHPARMS
*pParms
2995 iscsi_chap_props_t chap_p
;
2997 if (pParms
== NULL
) {
2998 return (IMA_ERROR_INVALID_PARAMETER
);
3001 if (oid
.objectType
!= IMA_OBJECT_TYPE_TARGET
) {
3002 return (IMA_ERROR_INCORRECT_OBJECT_TYPE
);
3005 if (method
!= IMA_AUTHMETHOD_CHAP
) {
3006 return (IMA_ERROR_INVALID_PARAMETER
);
3009 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
3010 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
3011 ISCSI_DRIVER_DEVCTL
, errno
);
3012 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3015 (void) memset(&chap_p
, 0, sizeof (iscsi_chap_props_t
));
3016 chap_p
.c_vers
= ISCSI_INTERFACE_VERSION
;
3017 chap_p
.c_oid
= (uint32_t)oid
.objectSequenceNumber
;
3019 if (ioctl(fd
, ISCSI_CHAP_GET
, &chap_p
) != 0) {
3020 syslog(LOG_USER
|LOG_DEBUG
,
3022 "ISCSI_CHAP_GET ioctl failed, errno: %d",
3025 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3028 (void) memcpy(pParms
->chapParms
.name
, chap_p
.c_user
,
3031 pParms
->chapParms
.nameLength
= chap_p
.c_user_len
;
3032 (void) memcpy(pParms
->chapParms
.challengeSecret
, chap_p
.c_secret
,
3033 chap_p
.c_secret_len
);
3035 pParms
->chapParms
.challengeSecretLength
= chap_p
.c_secret_len
;
3037 return (IMA_STATUS_SUCCESS
);
3040 IMA_API IMA_STATUS
SUN_IMA_GetBootTargetName(
3041 IMA_NODE_NAME tgtName
3046 iscsi_boot_property_t bootProp
;
3048 bootProp
.tgt_name
.n_name
[0] = '\0';
3049 bootProp
.tgt_chap
.c_user
[0] = '\0';
3051 rtn
= IMA_ERROR_UNEXPECTED_OS_ERROR
;
3052 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
3053 syslog(LOG_USER
|LOG_DEBUG
, "Unable to open %s (%d)",
3054 ISCSI_DRIVER_DEVCTL
, errno
);
3055 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3058 if (ioctl(fd
, ISCSI_BOOTPROP_GET
, &bootProp
) != 0) {
3059 syslog(LOG_USER
|LOG_DEBUG
,
3060 "ISCSI_BOOTPROP_GET ioctl failed, errno: %d",
3063 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3066 if ((bootProp
.tgt_name
.n_name
[0] != '\0') && (tgtName
!= NULL
)) {
3067 if (mbstowcs(tgtName
, (const char *)bootProp
.tgt_name
.n_name
,
3068 IMA_NODE_NAME_LEN
) == (size_t)-1) {
3069 syslog(LOG_USER
|LOG_DEBUG
,
3070 "ISCSI Target name covert to WCHAR fail");
3071 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3073 rtn
= IMA_STATUS_SUCCESS
;
3080 IMA_API IMA_STATUS
SUN_IMA_GetBootTargetAuthParams(
3081 IMA_INITIATOR_AUTHPARMS
*pTgtCHAP
3086 iscsi_boot_property_t bootProp
;
3088 bootProp
.tgt_name
.n_name
[0] = '\0';
3089 bootProp
.tgt_chap
.c_user
[0] = '\0';
3090 bootProp
.tgt_chap
.c_secret
[0] = '\0';
3091 rtn
= IMA_ERROR_UNEXPECTED_OS_ERROR
;
3092 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
3093 syslog(LOG_USER
|LOG_DEBUG
, "Unable to open %s (%d)",
3094 ISCSI_DRIVER_DEVCTL
, errno
);
3095 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3098 if (ioctl(fd
, ISCSI_BOOTPROP_GET
, &bootProp
) != 0) {
3099 syslog(LOG_USER
|LOG_DEBUG
,
3100 "ISCSI_BOOTPROP_GET ioctl failed, errno: %d",
3103 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3106 if (pTgtCHAP
!= NULL
) {
3107 if (bootProp
.tgt_chap
.c_user
[0] != '\0') {
3108 (void) memcpy(pTgtCHAP
->chapParms
.name
,
3109 bootProp
.tgt_chap
.c_user
, ISCSI_MAX_NAME_LEN
);
3111 pTgtCHAP
->chapParms
.name
[0] = '\0';
3113 if (bootProp
.tgt_chap
.c_secret
[0] != '\0') {
3114 (void) memcpy(pTgtCHAP
->chapParms
.challengeSecret
,
3115 bootProp
.tgt_chap
.c_secret
, MAX_CHAP_SECRET_LEN
);
3117 pTgtCHAP
->chapParms
.challengeSecret
[0] = '\0';
3119 rtn
= IMA_STATUS_SUCCESS
;
3124 IMA_STATUS
SUN_IMA_GetBootMpxio(
3125 IMA_BOOL
*pMpxioEnabled
3129 iscsi_boot_property_t bootProp
;
3131 bootProp
.hba_mpxio_enabled
= B_FALSE
;
3132 *pMpxioEnabled
= IMA_UNKNOWN
;
3134 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
3135 syslog(LOG_USER
|LOG_DEBUG
, "Unable to open %s (%d)",
3136 ISCSI_DRIVER_DEVCTL
, errno
);
3137 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3140 if (ioctl(fd
, ISCSI_BOOTPROP_GET
, &bootProp
) != 0) {
3141 syslog(LOG_USER
|LOG_DEBUG
,
3142 "ISCSI_BOOTPROP_GET ioctl failed, errno: %d",
3145 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3148 if (bootProp
.hba_mpxio_enabled
) {
3149 *pMpxioEnabled
= IMA_TRUE
;
3151 *pMpxioEnabled
= IMA_FALSE
;
3155 return (IMA_STATUS_SUCCESS
);
3158 IMA_STATUS
SUN_IMA_GetBootIscsi(
3159 IMA_BOOL
*pIscsiBoot
3163 iscsi_boot_property_t bootProp
;
3165 bootProp
.iscsiboot
= 0;
3168 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
3169 syslog(LOG_USER
|LOG_DEBUG
, "Unable to open %s (%d)",
3170 ISCSI_DRIVER_DEVCTL
, errno
);
3171 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3174 if (ioctl(fd
, ISCSI_BOOTPROP_GET
, &bootProp
) != 0) {
3175 syslog(LOG_USER
|LOG_DEBUG
,
3176 "ISCSI_BOOTPROP_GET ioctl failed, errno: %d",
3179 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3182 *pIscsiBoot
= bootProp
.iscsiboot
;
3185 return (IMA_STATUS_SUCCESS
);
3188 IMA_STATUS
SUN_IMA_GetSvcStatus(
3189 IMA_BOOL
*pSvcEnabled
)
3192 uint32_t status
= ISCSI_SERVICE_DISABLED
;
3194 if (pSvcEnabled
== NULL
)
3195 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3198 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
3199 syslog(LOG_USER
|LOG_DEBUG
, "Unable to open %s (%d)",
3200 ISCSI_DRIVER_DEVCTL
, errno
);
3201 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3204 if (ioctl(fd
, ISCSI_SMF_GET
, &status
) != 0) {
3205 syslog(LOG_USER
|LOG_DEBUG
,
3206 "ISCSI_SVC_GET ioctl failed, errno: %d",
3209 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3212 if (status
== ISCSI_SERVICE_ENABLED
) {
3217 return (IMA_STATUS_SUCCESS
);
3220 IMA_STATUS
SUN_IMA_ReEnumeration(
3228 reet
.re_ver
= ISCSI_INTERFACE_VERSION
;
3229 reet
.re_oid
= (uint32_t)targetId
.objectSequenceNumber
;
3231 if ((status
= open_driver(&fd
))) {
3232 return (SUN_IMA_ERROR_SYSTEM_ERROR
| status
);
3235 (void) ioctl(fd
, ISCSI_TARGET_REENUM
, &reet
);
3239 return (IMA_STATUS_SUCCESS
);