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.
26 #include <arpa/inet.h>
27 #include <sys/socket.h>
28 #include <sys/types.h>
38 #include <libsysevent.h>
39 #include <sys/nvpair.h>
43 #include <libdevinfo.h>
44 #include <sys/scsi/generic/commands.h>
45 #include <sys/scsi/generic/status.h>
46 #include <sys/scsi/adapters/iscsi_if.h>
47 #include <sys/iscsi_protocol.h>
49 #include <libsun_ima.h>
51 #define LIBRARY_PROPERTY_IMPLEMENTATION_VERSION L"1.0.0"
52 #define LIBRARY_PROPERTY_VENDOR L"Sun Microsystems, Inc."
53 #define OS_DEVICE_NAME "/devices/iscsi"
54 #define LIBRARY_FILE_NAME L"libsun_ima.so"
56 #define OS_DEVICE_NAME_LEN 256
57 #define USCSI_TIMEOUT_IN_SEC 10
58 #define MAX_AUTHMETHODS 10
59 #define NUM_SUPPORTED_AUTH_METHODS 2
60 #define SUN_IMA_MAX_DIGEST_ALGORITHMS 2 /* NONE and CRC 32 */
61 #define SUN_IMA_IP_ADDRESS_LEN 256
62 #define SUN_IMA_IP_PORT_LEN 64
63 #define SUN_IMA_MAX_RADIUS_SECRET_LEN 128
64 #define MAX_LONG_LONG_STRING_LEN 10
65 #define MAX_INQUIRY_BUFFER_LEN 0xffff
66 #define MAX_REPORT_LUNS_BUFFER_LEN 0xffffffff
67 #define MAX_READ_CAPACITY16_BUFFER_LEN 0xffffffff
69 /* Forward declaration */
71 #define MIN_MAX_PARAM 2
74 #define DISC_ADDR_OK 0
75 /* Incorrect IP address */
76 #define DISC_ADDR_INTEGRITY_ERROR 1
77 /* Error converting text IP address to numeric binary form */
78 #define DISC_ADDR_IP_CONV_ERROR 2
80 /* Currently not defined in IMA_TARGET_DISCOVERY_METHOD enum */
81 #define IMA_TARGET_DISCOVERY_METHOD_UNKNOWN 0
83 static IMA_OID lhbaObjectId
;
84 static IMA_UINT32 pluginOwnerId
;
85 static sysevent_handle_t
*shp
;
90 * Custom struct to allow tgpt to be specified.
92 typedef struct _SUN_IMA_DISC_ADDRESS_KEY
95 IMA_ADDRESS_KEY address
;
97 } SUN_IMA_DISC_ADDRESS_KEY
;
100 * Custom struct to allow tgpt to be specified.
102 typedef struct _SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
105 SUN_IMA_DISC_ADDRESS_KEY keys
[1];
106 } SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
;
109 * Custom struct to allow tgpt to be specified.
111 typedef struct _SUN_IMA_DISC_ADDR_PROP_LIST
113 IMA_UINT discAddrCount
;
114 IMA_DISCOVERY_ADDRESS_PROPERTIES props
[1];
115 } SUN_IMA_DISC_ADDR_PROP_LIST
;
118 static IMA_OBJECT_VISIBILITY_FN pObjectVisibilityCallback
= NULL
;
119 static IMA_OBJECT_PROPERTY_FN pObjectPropertyCallback
= NULL
;
121 static IMA_STATUS
getISCSINodeParameter(int paramType
, IMA_OID
*oid
,
122 void *pProps
, uint32_t paramIndex
);
123 static IMA_STATUS
setISCSINodeParameter(int paramType
, IMA_OID
*oid
,
124 void *pProps
, uint32_t paramIndex
);
125 static IMA_STATUS
setAuthMethods(IMA_OID oid
, IMA_UINT
*pMethodCount
,
126 const IMA_AUTHMETHOD
*pMethodList
);
127 static IMA_STATUS
getAuthMethods(IMA_OID oid
, IMA_UINT
*pMethodCount
,
128 IMA_AUTHMETHOD
*pMethodList
);
130 static int prepare_discovery_entry(IMA_TARGET_ADDRESS discoveryAddress
,
132 static IMA_STATUS
configure_discovery_method(IMA_BOOL enable
,
133 iSCSIDiscoveryMethod_t method
);
134 static IMA_STATUS
get_target_oid_list(uint32_t targetListType
,
135 IMA_OID_LIST
**ppList
);
136 static IMA_STATUS
get_target_lun_oid_list(IMA_OID
* targetOid
,
137 iscsi_lun_list_t
**ppLunList
);
138 static int get_lun_devlink(di_devlink_t link
, void *osDeviceName
);
139 static IMA_STATUS
getDiscoveryAddressPropertiesList(
140 SUN_IMA_DISC_ADDR_PROP_LIST
**ppList
142 static IMA_STATUS
sendTargets(IMA_TARGET_ADDRESS address
,
143 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
**ppList
146 static IMA_STATUS
getSupportedAuthMethods(IMA_OID lhbaOid
,
147 IMA_BOOL getSettableMethods
, IMA_UINT
*pMethodCount
,
148 IMA_AUTHMETHOD
*pMethodList
);
149 static IMA_STATUS
getLuProperties(IMA_OID luId
, IMA_LU_PROPERTIES
*pProps
);
150 static IMA_STATUS
getTargetProperties(IMA_OID targetId
,
151 IMA_TARGET_PROPERTIES
*pProps
);
155 static void libSwprintf(wchar_t *wcs
, const wchar_t *lpszFormat
, ...)
158 va_start(args
, lpszFormat
);
159 (void) vswprintf(wcs
, OS_DEVICE_NAME_LEN
- 1, lpszFormat
, args
);
164 sysevent_handler(sysevent_t
*ev
)
167 IMA_BOOL becomingVisible
= IMA_FALSE
;
170 const char *visibility_subclasses
[] = {
171 ESC_ISCSI_STATIC_START
,
172 ESC_ISCSI_STATIC_END
,
173 ESC_ISCSI_SEND_TARGETS_START
,
174 ESC_ISCSI_SEND_TARGETS_END
,
177 ESC_ISCSI_ISNS_START
,
182 tmpOid
.ownerId
= pluginOwnerId
;
183 tmpOid
.objectType
= IMA_OBJECT_TYPE_TARGET
;
184 tmpOid
.objectSequenceNumber
= 0;
186 /* Make sure our event class matches what we are looking for */
187 if (strncmp(EC_ISCSI
, sysevent_get_class_name(ev
),
188 strlen(EC_ISCSI
)) != 0) {
193 /* Check for object property changes */
194 if ((strncmp(ESC_ISCSI_PROP_CHANGE
,
195 sysevent_get_subclass_name(ev
),
196 strlen(ESC_ISCSI_PROP_CHANGE
)) == 0)) {
197 if (pObjectPropertyCallback
!= NULL
)
198 pObjectPropertyCallback(tmpOid
);
201 while (visibility_subclasses
[i
] != NULL
) {
202 if ((strncmp(visibility_subclasses
[i
],
203 sysevent_get_subclass_name(ev
),
204 strlen(visibility_subclasses
[i
])) == 0) &&
205 pObjectVisibilityCallback
!= NULL
) {
206 becomingVisible
= IMA_TRUE
;
207 pObjectVisibilityCallback(becomingVisible
,
215 IMA_STATUS
init_sysevents() {
216 const char *subclass_list
[] = {
217 ESC_ISCSI_STATIC_START
,
218 ESC_ISCSI_STATIC_END
,
219 ESC_ISCSI_SEND_TARGETS_START
,
220 ESC_ISCSI_SEND_TARGETS_END
,
223 ESC_ISCSI_ISNS_START
,
225 ESC_ISCSI_PROP_CHANGE
,
228 /* Bind event handler and create subscriber handle */
229 shp
= sysevent_bind_handle(sysevent_handler
);
231 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
234 if (sysevent_subscribe_event(shp
, EC_ISCSI
, subclass_list
, 9) != 0) {
235 sysevent_unbind_handle(shp
);
236 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
238 return (IMA_STATUS_SUCCESS
);
241 IMA_STATUS
Initialize(IMA_UINT32 pluginOid
) {
242 pluginOwnerId
= pluginOid
;
243 return (init_sysevents());
248 sysevent_unsubscribe_event(shp
, EC_ISCSI
);
256 static void GetBuildTime(IMA_DATETIME
* pdatetime
)
258 (void) memset(pdatetime
, 0, sizeof (IMA_DATETIME
));
262 IMA_API IMA_STATUS
IMA_GetNodeProperties(
264 IMA_NODE_PROPERTIES
*pProps
268 iscsi_param_get_t pg
;
270 pProps
->runningInInitiatorMode
= IMA_TRUE
;
271 pProps
->runningInTargetMode
= IMA_FALSE
;
272 pProps
->nameAndAliasSettable
= IMA_FALSE
;
274 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
275 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
276 ISCSI_DRIVER_DEVCTL
, errno
);
277 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
280 (void) memset(&pg
, 0, sizeof (iscsi_param_get_t
));
281 pg
.g_vers
= ISCSI_INTERFACE_VERSION
;
282 pg
.g_param
= ISCSI_LOGIN_PARAM_INITIATOR_NAME
;
284 if (ioctl(fd
, ISCSI_PARAM_GET
, &pg
) == -1) {
285 pProps
->nameValid
= IMA_FALSE
;
287 if (strlen((char *)pg
.g_value
.v_name
) > 0) {
288 (void) mbstowcs(pProps
->name
,
289 (char *)pg
.g_value
.v_name
,
291 pProps
->nameValid
= IMA_TRUE
;
293 pProps
->nameValid
= IMA_FALSE
;
297 (void) memset(&pg
, 0, sizeof (iscsi_param_get_t
));
298 pg
.g_vers
= ISCSI_INTERFACE_VERSION
;
299 pg
.g_param
= ISCSI_LOGIN_PARAM_INITIATOR_ALIAS
;
300 (void) memset(pProps
->alias
, 0,
301 sizeof (IMA_WCHAR
) * IMA_NODE_ALIAS_LEN
);
302 if (ioctl(fd
, ISCSI_PARAM_GET
, &pg
) == -1) {
303 pProps
->aliasValid
= IMA_FALSE
;
305 if (strlen((char *)pg
.g_value
.v_name
) > 0) {
306 (void) mbstowcs(pProps
->alias
,
307 (char *)pg
.g_value
.v_name
,
309 pProps
->aliasValid
= IMA_TRUE
;
314 return (IMA_STATUS_SUCCESS
);
317 IMA_API IMA_STATUS
IMA_SetNodeName(
319 const IMA_NODE_NAME newName
323 iscsi_param_set_t ps
;
325 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
326 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
327 ISCSI_DRIVER_DEVCTL
, errno
);
328 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
331 (void) memset(&ps
, 0, sizeof (iscsi_param_set_t
));
332 ps
.s_oid
= nodeOid
.objectSequenceNumber
;
333 ps
.s_vers
= ISCSI_INTERFACE_VERSION
;
334 ps
.s_param
= ISCSI_LOGIN_PARAM_INITIATOR_NAME
;
335 (void) wcstombs((char *)ps
.s_value
.v_name
, newName
, ISCSI_MAX_NAME_LEN
);
336 if (ioctl(fd
, ISCSI_INIT_NODE_NAME_SET
, &ps
)) {
337 syslog(LOG_USER
|LOG_DEBUG
,
338 "ISCSI_PARAM_SET ioctl failed, errno: %d", errno
);
340 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
344 return (IMA_STATUS_SUCCESS
);
347 IMA_API IMA_STATUS
IMA_SetNodeAlias(
349 const IMA_NODE_ALIAS newAlias
353 iscsi_param_set_t ps
;
355 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
356 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
357 ISCSI_DRIVER_DEVCTL
, errno
);
358 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
361 (void) memset(&ps
, 0, sizeof (iscsi_param_set_t
));
362 ps
.s_oid
= nodeOid
.objectSequenceNumber
;
363 ps
.s_vers
= ISCSI_INTERFACE_VERSION
;
364 ps
.s_param
= ISCSI_LOGIN_PARAM_INITIATOR_ALIAS
;
366 /* newAlias = NULL specifies that the alias should be deleted. */
367 if (newAlias
!= NULL
)
368 (void) wcstombs((char *)ps
.s_value
.v_name
, newAlias
,
371 (void) wcstombs((char *)ps
.s_value
.v_name
,
372 L
"", ISCSI_MAX_NAME_LEN
);
374 if (ioctl(fd
, ISCSI_PARAM_SET
, &ps
)) {
375 syslog(LOG_USER
|LOG_DEBUG
,
376 "ISCSI_PARAM_SET ioctl failed, errno: %d", errno
);
378 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
382 return (IMA_STATUS_SUCCESS
);
386 IMA_API IMA_STATUS
IMA_GetLhbaOidList(
387 IMA_OID_LIST
**ppList
390 /* Always return the same object ID for the lhba */
391 lhbaObjectId
.objectType
= IMA_OBJECT_TYPE_LHBA
;
392 lhbaObjectId
.ownerId
= pluginOwnerId
;
393 lhbaObjectId
.objectSequenceNumber
= ISCSI_INITIATOR_OID
;
395 *ppList
= (IMA_OID_LIST
*)calloc(1, sizeof (IMA_OID_LIST
));
396 if (*ppList
== NULL
) {
397 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
400 (*ppList
)->oidCount
= 1;
401 (void) memcpy(&(*ppList
)->oids
[0],
402 &lhbaObjectId
, sizeof (lhbaObjectId
));
403 return (IMA_STATUS_SUCCESS
);
408 * Get the discovery properties of the LHBA
411 IMA_API IMA_STATUS
IMA_GetDiscoveryProperties(
413 IMA_DISCOVERY_PROPERTIES
*pProps
417 iSCSIDiscoveryProperties_t discoveryProps
;
419 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
420 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
421 ISCSI_DRIVER_DEVCTL
, errno
);
422 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
425 (void) memset(&discoveryProps
, 0, sizeof (discoveryProps
));
426 discoveryProps
.vers
= ISCSI_INTERFACE_VERSION
;
428 if (ioctl(fd
, ISCSI_DISCOVERY_PROPS
, &discoveryProps
) != 0) {
429 syslog(LOG_USER
|LOG_DEBUG
,
430 "ISCSI_DISCOVERY_PROPS ioctl failed, errno: %d", errno
);
432 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
435 pProps
->iSnsDiscoverySettable
= discoveryProps
.iSNSDiscoverySettable
;
436 pProps
->iSnsDiscoveryEnabled
= discoveryProps
.iSNSDiscoveryEnabled
;
438 * Set the iSNS discovery method - The IMA specification indicates
439 * this field is valid only if iSNS discovery is enabled.
441 if (pProps
->iSnsDiscoveryEnabled
== IMA_TRUE
) {
442 switch (discoveryProps
.iSNSDiscoveryMethod
) {
443 case iSNSDiscoveryMethodStatic
:
444 pProps
->iSnsDiscoveryMethod
=
445 IMA_ISNS_DISCOVERY_METHOD_STATIC
;
447 case iSNSDiscoveryMethodDHCP
:
448 pProps
->iSnsDiscoveryMethod
=
449 IMA_ISNS_DISCOVERY_METHOD_DHCP
;
451 case iSNSDiscoveryMethodSLP
:
452 pProps
->iSnsDiscoveryMethod
=
453 IMA_ISNS_DISCOVERY_METHOD_SLP
;
457 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
460 (void) memcpy(pProps
->iSnsHost
.id
.hostname
,
461 discoveryProps
.iSNSDomainName
,
462 sizeof (pProps
->iSnsHost
.id
.hostname
));
463 pProps
->slpDiscoverySettable
= discoveryProps
.SLPDiscoverySettable
;
464 pProps
->slpDiscoveryEnabled
= discoveryProps
.SLPDiscoveryEnabled
;
465 pProps
->staticDiscoverySettable
=
466 discoveryProps
.StaticDiscoverySettable
;
467 pProps
->staticDiscoveryEnabled
= discoveryProps
.StaticDiscoveryEnabled
;
468 pProps
->sendTargetsDiscoverySettable
=
469 discoveryProps
.SendTargetsDiscoverySettable
;
470 pProps
->sendTargetsDiscoveryEnabled
=
471 discoveryProps
.SendTargetsDiscoveryEnabled
;
474 return (IMA_STATUS_SUCCESS
);
477 IMA_API IMA_STATUS
IMA_FreeMemory(
482 return (IMA_STATUS_SUCCESS
);
485 IMA_API IMA_STATUS
IMA_GetNonSharedNodeOidList(
486 IMA_OID_LIST
**ppList
490 return (IMA_ERROR_INVALID_PARAMETER
);
492 *ppList
= (IMA_OID_LIST
*) calloc(1, sizeof (IMA_OID_LIST
));
493 if (*ppList
== NULL
) {
494 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
496 (*ppList
)->oidCount
= 0;
498 return (IMA_STATUS_SUCCESS
);
501 IMA_API IMA_STATUS
IMA_GetFirstBurstLengthProperties(
503 IMA_MIN_MAX_VALUE
*pProps
506 return (getISCSINodeParameter(MIN_MAX_PARAM
, &Oid
, pProps
,
507 ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH
));
510 IMA_API IMA_STATUS
IMA_GetMaxBurstLengthProperties(
512 IMA_MIN_MAX_VALUE
*pProps
515 return (getISCSINodeParameter(MIN_MAX_PARAM
, &Oid
, pProps
,
516 ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH
));
519 IMA_API IMA_STATUS
IMA_GetMaxRecvDataSegmentLengthProperties(
521 IMA_MIN_MAX_VALUE
*pProps
524 return (getISCSINodeParameter(MIN_MAX_PARAM
, &Oid
, pProps
,
525 ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH
));
529 IMA_API IMA_STATUS
IMA_PluginIOCtl(
532 const void *pInputBuffer
,
533 IMA_UINT inputBufferLength
,
535 IMA_UINT
*pOutputBufferLength
538 return (IMA_ERROR_NOT_SUPPORTED
);
541 IMA_API IMA_STATUS
IMA_SetFirstBurstLength(
543 IMA_UINT firstBurstLength
546 IMA_MIN_MAX_VALUE mv
;
548 mv
.currentValue
= firstBurstLength
;
549 return (setISCSINodeParameter(MIN_MAX_PARAM
, &lhbaId
, &mv
,
550 ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH
));
553 IMA_API IMA_STATUS
IMA_SetMaxBurstLength(
555 IMA_UINT maxBurstLength
558 IMA_MIN_MAX_VALUE mv
;
560 mv
.currentValue
= maxBurstLength
;
561 return (setISCSINodeParameter(MIN_MAX_PARAM
, &lhbaId
, &mv
,
562 ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH
));
565 IMA_API IMA_STATUS
IMA_SetMaxRecvDataSegmentLength(
567 IMA_UINT maxRecvDataSegmentLength
570 IMA_MIN_MAX_VALUE mv
;
572 mv
.currentValue
= maxRecvDataSegmentLength
;
573 return (setISCSINodeParameter(MIN_MAX_PARAM
, &lhbaId
, &mv
,
574 ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH
));
577 IMA_API IMA_STATUS
IMA_GetMaxConnectionsProperties(
579 IMA_MIN_MAX_VALUE
*pProps
582 return (getISCSINodeParameter(MIN_MAX_PARAM
, &Oid
, pProps
,
583 ISCSI_LOGIN_PARAM_MAX_CONNECTIONS
));
586 IMA_API IMA_STATUS
IMA_SetMaxConnections(
588 IMA_UINT maxConnections
591 IMA_MIN_MAX_VALUE mv
;
593 mv
.currentValue
= maxConnections
;
594 return (setISCSINodeParameter(MIN_MAX_PARAM
, &lhbaId
, &mv
,
595 ISCSI_LOGIN_PARAM_MAX_CONNECTIONS
));
598 IMA_API IMA_STATUS
IMA_GetDefaultTime2RetainProperties(
600 IMA_MIN_MAX_VALUE
*pProps
603 return (getISCSINodeParameter(MIN_MAX_PARAM
, &lhbaId
, pProps
,
604 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN
));
607 IMA_API IMA_STATUS
IMA_SetDefaultTime2Retain(
609 IMA_UINT defaultTime2Retain
612 IMA_MIN_MAX_VALUE mv
;
614 mv
.currentValue
= defaultTime2Retain
;
615 return (setISCSINodeParameter(MIN_MAX_PARAM
, &lhbaId
, &mv
,
616 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN
));
619 IMA_API IMA_STATUS
IMA_GetDefaultTime2WaitProperties(
621 IMA_MIN_MAX_VALUE
*pProps
624 return (getISCSINodeParameter(MIN_MAX_PARAM
, &lhbaId
, pProps
,
625 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT
));
628 IMA_API IMA_STATUS
IMA_SetDefaultTime2Wait(
630 IMA_UINT defaultTime2Wait
633 IMA_MIN_MAX_VALUE mv
;
635 mv
.currentValue
= defaultTime2Wait
;
636 return (setISCSINodeParameter(MIN_MAX_PARAM
, &lhbaId
, &mv
,
637 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT
));
640 IMA_API IMA_STATUS
IMA_GetMaxOutstandingR2TProperties(
642 IMA_MIN_MAX_VALUE
*pProps
645 return (getISCSINodeParameter(MIN_MAX_PARAM
, &Oid
, pProps
,
646 ISCSI_LOGIN_PARAM_OUTSTANDING_R2T
));
649 IMA_API IMA_STATUS
IMA_SetMaxOutstandingR2T(
651 IMA_UINT maxOutstandingR2T
654 IMA_MIN_MAX_VALUE mv
;
656 mv
.currentValue
= maxOutstandingR2T
;
657 return (setISCSINodeParameter(MIN_MAX_PARAM
, &lhbaId
, &mv
,
658 ISCSI_LOGIN_PARAM_OUTSTANDING_R2T
));
662 IMA_API IMA_STATUS
IMA_GetErrorRecoveryLevelProperties(
664 IMA_MIN_MAX_VALUE
*pProps
667 return (getISCSINodeParameter(MIN_MAX_PARAM
, &Oid
, pProps
,
668 ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL
));
671 IMA_API IMA_STATUS
IMA_SetErrorRecoveryLevel(
673 IMA_UINT errorRecoveryLevel
676 IMA_MIN_MAX_VALUE mv
;
678 mv
.currentValue
= errorRecoveryLevel
;
679 return (setISCSINodeParameter(MIN_MAX_PARAM
, &Oid
, &mv
,
680 ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL
));
683 IMA_API IMA_STATUS
IMA_GetInitialR2TProperties(
685 IMA_BOOL_VALUE
*pProps
688 return (getISCSINodeParameter(BOOL_PARAM
, &Oid
, pProps
,
689 ISCSI_LOGIN_PARAM_INITIAL_R2T
));
692 IMA_API IMA_STATUS
IMA_SetInitialR2T(
699 bv
.currentValue
= initialR2T
;
700 return (setISCSINodeParameter(BOOL_PARAM
, &Oid
, &bv
,
701 ISCSI_LOGIN_PARAM_INITIAL_R2T
));
705 IMA_API IMA_STATUS
IMA_GetImmediateDataProperties(
707 IMA_BOOL_VALUE
*pProps
710 return (getISCSINodeParameter(BOOL_PARAM
, &Oid
, pProps
,
711 ISCSI_LOGIN_PARAM_IMMEDIATE_DATA
));
714 IMA_API IMA_STATUS
IMA_SetImmediateData(
716 IMA_BOOL immediateData
721 bv
.currentValue
= immediateData
;
722 return (setISCSINodeParameter(BOOL_PARAM
, &Oid
, &bv
,
723 ISCSI_LOGIN_PARAM_IMMEDIATE_DATA
));
726 IMA_API IMA_STATUS
IMA_GetDataPduInOrderProperties(
728 IMA_BOOL_VALUE
*pProps
731 return (getISCSINodeParameter(BOOL_PARAM
, &Oid
, pProps
,
732 ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER
));
735 IMA_API IMA_STATUS
IMA_SetDataPduInOrder(
737 IMA_BOOL dataPduInOrder
742 bv
.currentValue
= dataPduInOrder
;
743 return (setISCSINodeParameter(BOOL_PARAM
, &Oid
, &bv
,
744 ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER
));
747 IMA_API IMA_STATUS
IMA_GetDataSequenceInOrderProperties(
749 IMA_BOOL_VALUE
*pProps
752 return (getISCSINodeParameter(BOOL_PARAM
, &Oid
, pProps
,
753 ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER
));
756 IMA_API IMA_STATUS
IMA_SetDataSequenceInOrder(
758 IMA_BOOL dataSequenceInOrder
763 bv
.currentValue
= dataSequenceInOrder
;
764 return (setISCSINodeParameter(BOOL_PARAM
, &Oid
, &bv
,
765 ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER
));
770 IMA_API IMA_STATUS
IMA_SetStatisticsCollection(
772 IMA_BOOL enableStatisticsCollection
775 return (IMA_ERROR_NOT_SUPPORTED
);
780 IMA_API IMA_STATUS
IMA_GetDiscoveryAddressOidList(
782 IMA_OID_LIST
**ppList
785 int fd
, i
, addr_list_size
;
786 iscsi_addr_list_t
*idlp
, al_info
;
788 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
789 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
790 ISCSI_DRIVER_DEVCTL
, errno
);
791 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
794 (void) memset(&al_info
, 0, sizeof (al_info
));
795 al_info
.al_vers
= ISCSI_INTERFACE_VERSION
;
796 al_info
.al_in_cnt
= 0;
799 * Issue ioctl to obtain the number of targets.
801 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_LIST_GET
, &al_info
) != 0) {
802 syslog(LOG_USER
|LOG_DEBUG
,
803 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
804 ISCSI_DISCOVERY_ADDR_LIST_GET
, errno
);
806 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
809 addr_list_size
= sizeof (iscsi_addr_list_t
);
810 if (al_info
.al_out_cnt
> 1) {
811 addr_list_size
+= (sizeof (iscsi_addr_list_t
) *
812 al_info
.al_out_cnt
- 1);
815 idlp
= (iscsi_addr_list_t
*)calloc(1, addr_list_size
);
818 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
821 idlp
->al_vers
= ISCSI_INTERFACE_VERSION
;
822 idlp
->al_in_cnt
= al_info
.al_out_cnt
;
823 /* Issue the same ioctl again to obtain the OIDs. */
824 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_LIST_GET
, idlp
) != 0) {
825 syslog(LOG_USER
|LOG_DEBUG
,
826 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
827 ISCSI_DISCOVERY_ADDR_LIST_GET
, errno
);
830 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
833 *ppList
= (IMA_OID_LIST
*)calloc(1, sizeof (IMA_OID_LIST
) +
834 idlp
->al_out_cnt
* sizeof (IMA_OID
));
835 if (*ppList
== NULL
) {
838 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
840 (*ppList
)->oidCount
= idlp
->al_out_cnt
;
842 for (i
= 0; i
< idlp
->al_out_cnt
; i
++) {
843 (*ppList
)->oids
[i
].objectType
=
844 IMA_OBJECT_TYPE_DISCOVERY_ADDRESS
;
845 (*ppList
)->oids
[i
].ownerId
= pluginOwnerId
;
846 (*ppList
)->oids
[i
].objectSequenceNumber
=
847 idlp
->al_addrs
[i
].a_oid
;
853 return (IMA_STATUS_SUCCESS
);
858 IMA_API IMA_STATUS
IMA_GetStaticDiscoveryTargetOidList(
860 IMA_OID_LIST
**ppList
863 if (Oid
.objectType
== IMA_OBJECT_TYPE_PNP
) {
864 return (IMA_ERROR_OBJECT_NOT_FOUND
);
867 return (get_target_oid_list(ISCSI_STATIC_TGT_OID_LIST
, ppList
));
871 IMA_API IMA_STATUS
IMA_GetTargetOidList(
873 IMA_OID_LIST
**ppList
876 return (get_target_oid_list(ISCSI_TGT_PARAM_OID_LIST
, ppList
));
880 IMA_API IMA_STATUS
IMA_SetIsnsDiscovery(
882 IMA_BOOL enableIsnsDiscovery
,
883 IMA_ISNS_DISCOVERY_METHOD discoveryMethod
,
884 const IMA_HOST_ID
*iSnsHost
887 /* XXX need to set discovery Method and domaineName */
888 return (configure_discovery_method(enableIsnsDiscovery
,
889 iSCSIDiscoveryMethodISNS
));
894 IMA_API IMA_STATUS
IMA_SetSlpDiscovery(
896 IMA_BOOL enableSlpDiscovery
899 return (configure_discovery_method(enableSlpDiscovery
,
900 iSCSIDiscoveryMethodSLP
));
905 IMA_API IMA_STATUS
IMA_SetStaticDiscovery(
907 IMA_BOOL enableStaticDiscovery
910 return (configure_discovery_method(enableStaticDiscovery
,
911 iSCSIDiscoveryMethodStatic
));
915 IMA_API IMA_STATUS
IMA_SetSendTargetsDiscovery(
917 IMA_BOOL enableSendTargetsDiscovery
920 return (configure_discovery_method(enableSendTargetsDiscovery
,
921 iSCSIDiscoveryMethodSendTargets
));
925 IMA_API IMA_STATUS
IMA_RemoveDiscoveryAddress(
926 IMA_OID discoveryAddressOid
929 int status
, fd
, i
, addr_list_size
;
930 iscsi_addr_list_t
*idlp
, al_info
;
931 iscsi_addr_t
*matched_addr
= NULL
;
934 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
935 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
936 ISCSI_DRIVER_DEVCTL
, errno
);
937 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
940 (void) memset(&al_info
, 0, sizeof (al_info
));
941 al_info
.al_vers
= ISCSI_INTERFACE_VERSION
;
942 al_info
.al_in_cnt
= 0;
945 * Issue ioctl to obtain the number of discovery address.
947 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_LIST_GET
, &al_info
) != 0) {
948 syslog(LOG_USER
|LOG_DEBUG
,
949 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
950 ISCSI_DISCOVERY_ADDR_LIST_GET
, errno
);
952 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
955 if (al_info
.al_out_cnt
== 0) {
956 return (IMA_ERROR_OBJECT_NOT_FOUND
);
959 addr_list_size
= sizeof (iscsi_addr_list_t
);
960 if (al_info
.al_out_cnt
> 1) {
961 addr_list_size
+= (sizeof (iscsi_addr_list_t
) *
962 al_info
.al_out_cnt
- 1);
965 idlp
= (iscsi_addr_list_t
*)calloc(1, addr_list_size
);
968 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
971 idlp
->al_vers
= ISCSI_INTERFACE_VERSION
;
972 idlp
->al_in_cnt
= al_info
.al_out_cnt
;
974 /* Issue the same ioctl again to obtain the OIDs. */
975 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_LIST_GET
, idlp
) != 0) {
976 syslog(LOG_USER
|LOG_DEBUG
,
977 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
978 ISCSI_DISCOVERY_ADDR_LIST_GET
, errno
);
981 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
984 for (i
= 0; i
< idlp
->al_out_cnt
; i
++) {
985 if (discoveryAddressOid
.objectSequenceNumber
!=
986 idlp
->al_addrs
[i
].a_oid
)
988 matched_addr
= &(idlp
->al_addrs
[i
]);
991 if (matched_addr
== NULL
) {
992 return (IMA_ERROR_OBJECT_NOT_FOUND
);
996 (void) memset(&entry
, 0, sizeof (entry_t
));
997 entry
.e_vers
= ISCSI_INTERFACE_VERSION
;
998 entry
.e_oid
= discoveryAddressOid
.objectSequenceNumber
;
999 if (matched_addr
->a_addr
.i_insize
== sizeof (struct in_addr
)) {
1000 bcopy(&matched_addr
->a_addr
.i_addr
.in4
,
1001 &entry
.e_u
.u_in4
, sizeof (entry
.e_u
.u_in4
));
1002 entry
.e_insize
= sizeof (struct in_addr
);
1003 } else if (matched_addr
->a_addr
.i_insize
== sizeof (struct in6_addr
)) {
1004 bcopy(&matched_addr
->a_addr
.i_addr
.in6
,
1005 &entry
.e_u
.u_in6
, sizeof (entry
.e_u
.u_in6
));
1006 entry
.e_insize
= sizeof (struct in6_addr
);
1008 /* Should not happen */
1009 syslog(LOG_USER
|LOG_DEBUG
,
1010 "ISCSI_STATIC_GET returned bad address");
1011 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1014 entry
.e_port
= matched_addr
->a_port
;
1016 entry
.e_oid
= discoveryAddressOid
.objectSequenceNumber
;
1018 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_CLEAR
, &entry
)) {
1021 syslog(LOG_USER
|LOG_DEBUG
,
1022 "ISCSI_DISCOVERY_ADDR_CLEAR ioctl failed, errno: %d",
1024 if (status
== EBUSY
) {
1025 return (IMA_ERROR_LU_IN_USE
);
1027 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1033 return (IMA_STATUS_SUCCESS
);
1038 IMA_API IMA_STATUS
IMA_AddDiscoveryAddress(
1040 const IMA_TARGET_ADDRESS discoveryAddress
,
1041 IMA_OID
*pDiscoveryAddressOid
1047 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
1048 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
1049 ISCSI_DRIVER_DEVCTL
, errno
);
1050 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1053 if (prepare_discovery_entry(discoveryAddress
, &entry
) !=
1056 return (IMA_ERROR_INVALID_PARAMETER
);
1059 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_SET
, &entry
)) {
1060 syslog(LOG_USER
|LOG_DEBUG
,
1061 "ISCSI_DISCOVERY_ADDR_SET ioctl failed, errno: %d",
1064 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1067 pDiscoveryAddressOid
->ownerId
= pluginOwnerId
;
1068 pDiscoveryAddressOid
->objectType
= IMA_OBJECT_TYPE_DISCOVERY_ADDRESS
;
1069 pDiscoveryAddressOid
->objectSequenceNumber
= entry
.e_oid
;
1072 return (IMA_STATUS_SUCCESS
);
1075 IMA_API IMA_STATUS
IMA_GetStaticDiscoveryTargetProperties(
1076 IMA_OID staticTargetOid
,
1077 IMA_STATIC_DISCOVERY_TARGET_PROPERTIES
*pProps
1080 char static_target_addr_str
[SUN_IMA_IP_ADDRESS_LEN
];
1081 char static_target_addr_port_str
[SUN_IMA_IP_ADDRESS_LEN
];
1083 iscsi_static_property_t prop
;
1087 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
1088 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
1089 ISCSI_DRIVER_DEVCTL
, errno
);
1090 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1093 (void) memset(&prop
, 0, sizeof (iscsi_static_property_t
));
1094 prop
.p_vers
= ISCSI_INTERFACE_VERSION
;
1095 prop
.p_oid
= (uint32_t)staticTargetOid
.objectSequenceNumber
;
1096 if (ioctl(fd
, ISCSI_STATIC_GET
, &prop
) != 0) {
1099 syslog(LOG_USER
|LOG_DEBUG
,
1100 "ISCSI_STATIC_GET ioctl failed, errno: %d", status
);
1101 if (status
== ENOENT
) {
1102 return (IMA_ERROR_OBJECT_NOT_FOUND
);
1105 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1110 (void) mbstowcs(pProps
->staticTarget
.targetName
, (char *)prop
.p_name
,
1111 sizeof (pProps
->staticTarget
.targetName
)/sizeof (IMA_WCHAR
));
1113 if (prop
.p_addr_list
.al_addrs
[0].a_addr
.i_insize
==
1114 sizeof (struct in_addr
)) {
1117 } else if (prop
.p_addr_list
.al_addrs
[0].a_addr
.i_insize
==
1118 sizeof (struct in6_addr
)) {
1122 /* Should not happen */
1123 syslog(LOG_USER
|LOG_DEBUG
,
1124 "ISCSI_STATIC_GET returned bad address");
1125 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1128 if (inet_ntop(af
, &prop
.p_addr_list
.al_addrs
[0].a_addr
.i_addr
,
1129 static_target_addr_str
, sizeof (static_target_addr_str
)) == NULL
) {
1130 /* Should not happen */
1131 syslog(LOG_USER
|LOG_DEBUG
,
1132 "ISCSI_STATIC_GET returned address that cannot "
1134 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1136 if (af
== AF_INET
) {
1137 (void) snprintf(static_target_addr_port_str
,
1138 SUN_IMA_IP_ADDRESS_LEN
,
1140 static_target_addr_str
,
1141 prop
.p_addr_list
.al_addrs
[0].a_port
);
1143 (void) snprintf(static_target_addr_port_str
,
1144 SUN_IMA_IP_ADDRESS_LEN
,
1146 static_target_addr_str
,
1147 prop
.p_addr_list
.al_addrs
[0].a_port
);
1149 host
= &pProps
->staticTarget
.targetAddress
.hostnameIpAddress
;
1150 (void) mbstowcs(pProps
->staticTarget
.
1151 targetAddress
.hostnameIpAddress
.
1152 id
.hostname
, static_target_addr_port_str
,
1153 sizeof (host
->id
.hostname
) / sizeof (IMA_WCHAR
));
1156 return (IMA_STATUS_SUCCESS
);
1160 IMA_API IMA_STATUS
IMA_GetDiscoveryAddressProperties(
1161 IMA_OID discoveryAddressOid
,
1162 IMA_DISCOVERY_ADDRESS_PROPERTIES
*pProps
1168 iscsi_addr_list_t
*idlp
, al_info
;
1169 iscsi_addr_t
*matched_addr
= NULL
;
1171 IMA_TARGET_ADDRESS
*addr
;
1173 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
1174 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
1175 ISCSI_DRIVER_DEVCTL
, errno
);
1176 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1179 (void) memset(&al_info
, 0, sizeof (al_info
));
1180 al_info
.al_vers
= ISCSI_INTERFACE_VERSION
;
1181 al_info
.al_in_cnt
= 0;
1184 * Issue ioctl to obtain the number of discovery addresses.
1186 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_LIST_GET
, &al_info
) != 0) {
1188 syslog(LOG_USER
|LOG_DEBUG
,
1189 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
1190 ISCSI_DISCOVERY_ADDR_LIST_GET
, errno
);
1191 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1194 if (al_info
.al_out_cnt
== 0) {
1195 return (IMA_ERROR_OBJECT_NOT_FOUND
);
1198 addr_list_size
= sizeof (iscsi_addr_list_t
);
1199 if (al_info
.al_out_cnt
> 1) {
1200 addr_list_size
+= (sizeof (iscsi_addr_list_t
) *
1201 al_info
.al_out_cnt
- 1);
1204 idlp
= (iscsi_addr_list_t
*)calloc(1, addr_list_size
);
1207 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
1210 idlp
->al_vers
= ISCSI_INTERFACE_VERSION
;
1211 idlp
->al_in_cnt
= al_info
.al_out_cnt
;
1213 /* Issue the same ioctl again to obtain the OIDs. */
1214 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_LIST_GET
, idlp
) != 0) {
1217 syslog(LOG_USER
|LOG_DEBUG
,
1218 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
1219 ISCSI_DISCOVERY_ADDR_LIST_GET
, errno
);
1220 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1223 for (i
= 0; i
< idlp
->al_out_cnt
; i
++) {
1224 if (discoveryAddressOid
.objectSequenceNumber
!=
1225 idlp
->al_addrs
[i
].a_oid
)
1227 matched_addr
= &(idlp
->al_addrs
[i
]);
1230 if (matched_addr
== NULL
) {
1231 return (IMA_ERROR_OBJECT_NOT_FOUND
);
1234 if (matched_addr
->a_addr
.i_insize
== sizeof (struct in_addr
)) {
1235 pProps
->discoveryAddress
.hostnameIpAddress
.id
.
1236 ipAddress
.ipv4Address
= IMA_TRUE
;
1237 } else if (matched_addr
->a_addr
.i_insize
== sizeof (struct in6_addr
)) {
1238 pProps
->discoveryAddress
.hostnameIpAddress
.id
.
1239 ipAddress
.ipv4Address
= IMA_FALSE
;
1241 /* Should not happen */
1242 syslog(LOG_USER
|LOG_DEBUG
,
1243 "ISCSI_STATIC_GET returned bad address");
1244 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1247 addr
= &pProps
->discoveryAddress
;
1248 bcopy(&(matched_addr
->a_addr
.i_addr
), pProps
->discoveryAddress
.
1249 hostnameIpAddress
.id
.ipAddress
.ipAddress
,
1250 sizeof (addr
->hostnameIpAddress
.id
.ipAddress
.ipAddress
));
1252 pProps
->discoveryAddress
.portNumber
= matched_addr
->a_port
;
1254 pProps
->associatedLhbaOid
.objectType
= IMA_OBJECT_TYPE_LHBA
;
1255 pProps
->associatedLhbaOid
.ownerId
= pluginOwnerId
;
1256 pProps
->associatedLhbaOid
.objectSequenceNumber
= ISCSI_INITIATOR_OID
;
1261 return (IMA_STATUS_SUCCESS
);
1264 IMA_API IMA_STATUS
IMA_RemoveStaticDiscoveryTarget(
1265 IMA_OID staticTargetOid
1271 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
1272 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
1273 ISCSI_DRIVER_DEVCTL
, errno
);
1274 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1277 (void) memset(&entry
, 0, sizeof (entry_t
));
1278 entry
.e_vers
= ISCSI_INTERFACE_VERSION
;
1279 entry
.e_oid
= (uint32_t)staticTargetOid
.objectSequenceNumber
;
1281 if (ioctl(fd
, ISCSI_STATIC_CLEAR
, &entry
)) {
1284 syslog(LOG_USER
|LOG_DEBUG
,
1285 "ISCSI_STATIC_CLEAR ioctl failed, errno: %d", errno
);
1286 if (status
== EBUSY
) {
1287 return (IMA_ERROR_LU_IN_USE
);
1289 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1294 return (IMA_STATUS_SUCCESS
);
1298 IMA_API IMA_STATUS
IMA_AddStaticDiscoveryTarget(
1300 const IMA_STATIC_DISCOVERY_TARGET staticConfig
,
1304 char tmp_target_str
[SUN_IMA_IP_ADDRESS_LEN
];
1305 char target_addr_str
[SUN_IMA_IP_ADDRESS_LEN
];
1306 char target_port_str
[SUN_IMA_IP_PORT_LEN
];
1307 iscsi_target_entry_t target
;
1309 int target_in_addr_size
;
1312 struct in_addr u_in4
;
1313 struct in6_addr u_in6
;
1317 * staticConfig.address may come in with port number at its trailer.
1318 * Parse it to separate the IP address and port number.
1319 * Also translate the hostname to IP address if needed.
1321 (void) wcstombs(tmp_target_str
,
1322 staticConfig
.targetAddress
.hostnameIpAddress
.
1323 id
.hostname
, sizeof (tmp_target_str
));
1325 if (tmp_target_str
[0] == '[') {
1327 char *closeBracketPos
;
1328 closeBracketPos
= strchr(tmp_target_str
, ']');
1329 if (!closeBracketPos
) {
1330 return (IMA_ERROR_INVALID_PARAMETER
);
1333 *closeBracketPos
= '\0';
1334 (void) strlcpy(target_addr_str
, &tmp_target_str
[1],
1335 sizeof (target_addr_str
));
1337 if (inet_pton(AF_INET6
, target_addr_str
,
1338 &target_in
.u_in6
) != 1) {
1339 return (IMA_ERROR_INVALID_PARAMETER
);
1341 target_in_addr_size
= sizeof (struct in6_addr
);
1343 /* Extract the port number */
1345 if (*closeBracketPos
== ':') {
1348 if (*closeBracketPos
!= '\0') {
1349 (void) strlcpy(target_port_str
, closeBracketPos
,
1350 sizeof (target_port_str
));
1351 target_port
= atoi(target_port_str
);
1353 target_port
= ISCSI_LISTEN_PORT
;
1356 /* No port number specified; use default port */
1357 target_port
= ISCSI_LISTEN_PORT
;
1362 colonPos
= strchr(tmp_target_str
, ':');
1364 /* No port number specified; use default port */
1365 target_port
= ISCSI_LISTEN_PORT
;
1366 (void) strlcpy(target_addr_str
, tmp_target_str
,
1367 sizeof (target_addr_str
));
1370 (void) strlcpy(target_addr_str
, tmp_target_str
,
1371 sizeof (target_addr_str
));
1372 /* Extract the port number */
1374 if (*colonPos
!= '\0') {
1375 (void) strlcpy(target_port_str
, colonPos
,
1376 sizeof (target_port_str
));
1377 target_port
= atoi(target_port_str
);
1379 target_port
= ISCSI_LISTEN_PORT
;
1383 if (inet_pton(AF_INET
, target_addr_str
,
1384 &target_in
.u_in4
) != 1) {
1385 return (IMA_ERROR_INVALID_PARAMETER
);
1388 target_in_addr_size
= sizeof (struct in_addr
);
1392 (void) memset(&target
, 0, sizeof (iscsi_target_entry_t
));
1393 target
.te_entry
.e_vers
= ISCSI_INTERFACE_VERSION
;
1394 target
.te_entry
.e_oid
= ISCSI_OID_NOTSET
;
1395 target
.te_entry
.e_tpgt
= ISCSI_DEFAULT_TPGT
;
1397 (void) wcstombs((char *)target
.te_name
, staticConfig
.targetName
,
1398 ISCSI_MAX_NAME_LEN
);
1400 target
.te_entry
.e_insize
= target_in_addr_size
;
1401 if (target
.te_entry
.e_insize
== sizeof (struct in_addr
)) {
1402 target
.te_entry
.e_u
.u_in4
.s_addr
= target_in
.u_in4
.s_addr
;
1403 } else if (target
.te_entry
.e_insize
== sizeof (struct in6_addr
)) {
1404 bcopy(target_in
.u_in6
.s6_addr
,
1405 target
.te_entry
.e_u
.u_in6
.s6_addr
,
1406 sizeof (struct in6_addr
));
1408 /* Should not happen */
1409 syslog(LOG_USER
|LOG_DEBUG
,
1410 "ISCSI_STATIC_GET returned bad address");
1411 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1414 target
.te_entry
.e_port
= target_port
;
1416 /* No target portal group specified. Default to -1. */
1417 target
.te_entry
.e_tpgt
= ISCSI_DEFAULT_TPGT
;
1419 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
1420 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
1421 ISCSI_DRIVER_DEVCTL
, errno
);
1422 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1425 if (ioctl(fd
, ISCSI_STATIC_SET
, &target
)) {
1427 * Encountered problem setting the IP address and port for
1428 * the target just added.
1431 syslog(LOG_USER
|LOG_DEBUG
,
1432 "ISCSI_STATIC_SET ioctl failed, errno: %d", errno
);
1433 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1436 pTargetOid
->objectType
= IMA_OBJECT_TYPE_TARGET
;
1437 pTargetOid
->ownerId
= pluginOwnerId
;
1438 pTargetOid
->objectSequenceNumber
= target
.te_entry
.e_oid
;
1441 return (IMA_STATUS_SUCCESS
);
1444 IMA_API IMA_STATUS
IMA_GetTargetProperties(
1446 IMA_TARGET_PROPERTIES
*pProps
1449 return (getTargetProperties(targetId
, pProps
));
1452 static IMA_STATUS
getTargetProperties(
1454 IMA_TARGET_PROPERTIES
*pProps
1458 iscsi_property_t prop
;
1460 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
1461 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
1462 ISCSI_DRIVER_DEVCTL
, errno
);
1463 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1466 (void) memset(&prop
, 0, sizeof (iscsi_property_t
));
1467 prop
.p_vers
= ISCSI_INTERFACE_VERSION
;
1468 prop
.p_oid
= (uint32_t)targetId
.objectSequenceNumber
;
1470 if (ioctl(fd
, ISCSI_TARGET_PROPS_GET
, &prop
) != 0) {
1472 syslog(LOG_USER
|LOG_DEBUG
,
1473 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno
);
1474 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1477 (void) mbstowcs(pProps
->name
, (char *)prop
.p_name
, IMA_NODE_NAME_LEN
);
1478 (void) memset(pProps
->alias
, 0,
1479 sizeof (IMA_WCHAR
) * IMA_NODE_ALIAS_LEN
);
1480 if (prop
.p_alias_len
> 0) {
1481 (void) mbstowcs(pProps
->alias
, (char *)prop
.p_alias
,
1482 IMA_NODE_ALIAS_LEN
);
1485 /* Initialize the discovery method to unknown method. */
1486 pProps
->discoveryMethodFlags
= IMA_TARGET_DISCOVERY_METHOD_UNKNOWN
;
1487 if (!((prop
.p_discovery
& iSCSIDiscoveryMethodStatic
) ^
1488 iSCSIDiscoveryMethodStatic
)) {
1489 pProps
->discoveryMethodFlags
|=
1490 IMA_TARGET_DISCOVERY_METHOD_STATIC
;
1493 if (!((prop
.p_discovery
& iSCSIDiscoveryMethodSLP
) ^
1494 iSCSIDiscoveryMethodSLP
)) {
1495 pProps
->discoveryMethodFlags
|= IMA_TARGET_DISCOVERY_METHOD_SLP
;
1498 if (!((prop
.p_discovery
& iSCSIDiscoveryMethodISNS
) ^
1499 iSCSIDiscoveryMethodISNS
)) {
1500 pProps
->discoveryMethodFlags
|= iSCSIDiscoveryMethodISNS
;
1503 if (!((prop
.p_discovery
& iSCSIDiscoveryMethodSendTargets
) ^
1504 iSCSIDiscoveryMethodSendTargets
)) {
1505 pProps
->discoveryMethodFlags
|= iSCSIDiscoveryMethodSendTargets
;
1509 return (IMA_STATUS_SUCCESS
);
1513 IMA_API IMA_STATUS
IMA_GetTargetErrorStatistics(
1515 IMA_TARGET_ERROR_STATISTICS
*pStats
1518 return (IMA_ERROR_NOT_SUPPORTED
);
1521 IMA_API IMA_STATUS
IMA_GetLuOidList(
1523 IMA_OID_LIST
**ppList
1528 iscsi_lun_list_t
*pLunList
;
1530 if (oid
.objectType
== IMA_OBJECT_TYPE_LHBA
) {
1531 status
= get_target_lun_oid_list(NULL
, &pLunList
);
1533 status
= get_target_lun_oid_list(&oid
, &pLunList
);
1536 if (!IMA_SUCCESS(status
)) {
1540 *ppList
= (IMA_OID_LIST
*) calloc(1, (sizeof (IMA_OID_LIST
) +
1541 (pLunList
->ll_out_cnt
* sizeof (IMA_OID
))));
1542 if (*ppList
== NULL
) {
1543 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
1545 (*ppList
)->oidCount
= pLunList
->ll_out_cnt
;
1546 for (i
= 0; i
< pLunList
->ll_out_cnt
; i
++) {
1547 (*ppList
)->oids
[i
].objectType
= IMA_OBJECT_TYPE_LU
;
1548 (*ppList
)->oids
[i
].ownerId
= pluginOwnerId
;
1549 (*ppList
)->oids
[i
].objectSequenceNumber
=
1550 pLunList
->ll_luns
[i
].l_oid
;
1554 return (IMA_STATUS_SUCCESS
);
1557 IMA_API IMA_STATUS
IMA_GetLuOid(
1565 iscsi_lun_list_t
*pLunList
;
1567 status
= get_target_lun_oid_list(&targetId
, &pLunList
);
1568 if (!IMA_SUCCESS(status
)) {
1572 for (i
= 0; i
< pLunList
->ll_out_cnt
; i
++) {
1573 if (pLunList
->ll_luns
[i
].l_num
== lun
) {
1574 pluId
->objectType
= IMA_OBJECT_TYPE_LU
;
1575 pluId
->ownerId
= pluginOwnerId
;
1576 pluId
->objectSequenceNumber
=
1577 pLunList
->ll_luns
[i
].l_oid
;
1579 return (IMA_STATUS_SUCCESS
);
1584 return (IMA_ERROR_OBJECT_NOT_FOUND
);
1587 IMA_API IMA_STATUS
IMA_GetLuProperties(
1589 IMA_LU_PROPERTIES
*pProps
1592 return (getLuProperties(luId
, pProps
));
1595 static IMA_STATUS
getLuProperties(
1597 IMA_LU_PROPERTIES
*pProps
1601 iscsi_lun_list_t
*pLunList
;
1603 IMA_BOOL lunMatch
= IMA_FALSE
;
1605 iscsi_lun_props_t lun
;
1606 di_devlink_handle_t hdl
;
1608 if (luId
.objectType
!= IMA_OBJECT_TYPE_LU
) {
1609 return (IMA_ERROR_INCORRECT_OBJECT_TYPE
);
1613 * get list of lun oids for all targets
1615 status
= get_target_lun_oid_list(NULL
, &pLunList
);
1616 if (!IMA_SUCCESS(status
)) {
1619 for (j
= 0; j
< pLunList
->ll_out_cnt
; j
++) {
1621 * for each lun, check if match is found
1623 if (pLunList
->ll_luns
[j
].l_oid
== luId
.objectSequenceNumber
) {
1625 * match found, break out of lun loop
1627 lunMatch
= IMA_TRUE
;
1632 if (lunMatch
== IMA_TRUE
) {
1633 (void) memset(&lun
, 0, sizeof (iscsi_lun_props_t
));
1634 lun
.lp_vers
= ISCSI_INTERFACE_VERSION
;
1635 lun
.lp_tgt_oid
= pLunList
->ll_luns
[j
].l_tgt_oid
;
1636 lun
.lp_oid
= pLunList
->ll_luns
[j
].l_oid
;
1641 if (lunMatch
== IMA_FALSE
) {
1642 return (IMA_ERROR_OBJECT_NOT_FOUND
);
1646 * get lun properties
1648 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
1649 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
1650 ISCSI_DRIVER_DEVCTL
, errno
);
1651 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1654 if (ioctl(fd
, ISCSI_LUN_PROPS_GET
, &lun
)) {
1655 syslog(LOG_USER
|LOG_DEBUG
,
1656 "ISCSI_LUN_PROPS_GET ioctl failed, errno: %d", errno
);
1657 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1662 * set property values
1664 pProps
->associatedTargetOid
.objectType
= IMA_OBJECT_TYPE_TARGET
;
1665 pProps
->associatedTargetOid
.ownerId
= pluginOwnerId
;
1666 pProps
->associatedTargetOid
.objectSequenceNumber
= lun
.lp_tgt_oid
;
1667 pProps
->targetLun
= (IMA_UINT64
)lun
.lp_num
;
1668 pProps
->exposedToOs
= IMA_TRUE
;
1669 (void) memset(&pProps
->timeExposedToOs
, 0,
1670 sizeof (pProps
->timeExposedToOs
));
1672 if (lun
.lp_status
== LunValid
) {
1674 /* add minor device delimiter */
1675 (void) strcat(lun
.lp_pathname
, ":");
1677 if ((strstr(lun
.lp_pathname
, "sd@") != NULL
) ||
1678 (strstr(lun
.lp_pathname
, "ssd@") != NULL
) ||
1679 (strstr(lun
.lp_pathname
, "disk@") != NULL
)) {
1681 * modify returned pathname to obtain the 2nd slice
1684 (void) strcat(lun
.lp_pathname
, "c,raw");
1688 * Pathname returned by driver is the physical device path.
1689 * This name needs to be converted to the OS device name.
1691 if (hdl
= di_devlink_init(lun
.lp_pathname
, DI_MAKE_LINK
)) {
1692 pProps
->osDeviceName
[0] = L
'\0';
1693 (void) di_devlink_walk(hdl
, NULL
, lun
.lp_pathname
,
1694 DI_PRIMARY_LINK
, (void *)pProps
->osDeviceName
,
1696 if (pProps
->osDeviceName
[0] != L
'\0') {
1697 /* OS device name synchronously made */
1698 pProps
->osDeviceNameValid
= IMA_TRUE
;
1700 pProps
->osDeviceNameValid
= IMA_FALSE
;
1703 (void) di_devlink_fini(&hdl
);
1705 pProps
->osDeviceNameValid
= IMA_FALSE
;
1709 pProps
->osDeviceNameValid
= IMA_FALSE
;
1712 pProps
->osParallelIdsValid
= IMA_FALSE
;
1714 return (IMA_STATUS_SUCCESS
);
1718 IMA_API IMA_STATUS
IMA_GetStatisticsProperties(
1720 IMA_STATISTICS_PROPERTIES
*pProps
1723 return (IMA_ERROR_NOT_SUPPORTED
);
1727 IMA_API IMA_STATUS
IMA_GetDeviceStatistics(
1729 IMA_DEVICE_STATISTICS
*pStats
1732 return (IMA_ERROR_NOT_SUPPORTED
);
1735 IMA_API IMA_STATUS
IMA_LuInquiry(
1740 IMA_BYTE
*pOutputBuffer
,
1741 IMA_UINT
*pOutputBufferLength
,
1742 IMA_BYTE
*pSenseBuffer
,
1743 IMA_UINT
*pSenseBufferLength
1746 IMA_LU_PROPERTIES luProps
;
1748 unsigned char cmdblk
[CDB_GROUP0
];
1751 iscsi_uscsi_t uscsi
;
1753 (void) memset(&cmdblk
[0], 0, CDB_GROUP0
);
1754 cmdblk
[0] = SCMD_INQUIRY
;
1756 if (evpd
== IMA_TRUE
)
1758 if (cmddt
== IMA_TRUE
)
1761 cmdblk
[2] = pageCode
;
1763 if (*pOutputBufferLength
> MAX_INQUIRY_BUFFER_LEN
) {
1764 buflen
= MAX_INQUIRY_BUFFER_LEN
;
1766 buflen
= *pOutputBufferLength
;
1768 cmdblk
[3] = (buflen
& 0xff00) >> 8;
1769 cmdblk
[4] = (buflen
& 0x00ff);
1771 (void) memset(&uscsi
, 0, sizeof (iscsi_uscsi_t
));
1772 uscsi
.iu_vers
= ISCSI_INTERFACE_VERSION
;
1774 /* iu_oid is a session oid in the driver */
1775 if (deviceId
.objectType
== IMA_OBJECT_TYPE_TARGET
) {
1776 uscsi
.iu_oid
= deviceId
.objectSequenceNumber
;
1780 * Get LU properties and associated session oid
1781 * for this lun(deviceId) and put in uscsi.iu_oid
1783 status
= getLuProperties(deviceId
, &luProps
);
1784 if (status
!= IMA_STATUS_SUCCESS
) {
1787 uscsi
.iu_oid
= (uint32_t)luProps
.associatedTargetOid
.
1788 objectSequenceNumber
;
1789 uscsi
.iu_lun
= luProps
.targetLun
;
1792 uscsi
.iu_ucmd
.uscsi_flags
= USCSI_READ
;
1793 uscsi
.iu_ucmd
.uscsi_timeout
= USCSI_TIMEOUT_IN_SEC
;
1794 uscsi
.iu_ucmd
.uscsi_bufaddr
= (char *)pOutputBuffer
;
1795 uscsi
.iu_ucmd
.uscsi_buflen
= buflen
;
1796 uscsi
.iu_ucmd
.uscsi_rqbuf
= (char *)pSenseBuffer
;
1797 uscsi
.iu_ucmd
.uscsi_rqlen
= (pSenseBufferLength
!= NULL
) ?
1798 *pSenseBufferLength
: 0;
1799 uscsi
.iu_ucmd
.uscsi_cdb
= (char *)&cmdblk
[0];
1800 uscsi
.iu_ucmd
.uscsi_cdblen
= CDB_GROUP0
;
1802 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
1803 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
1804 ISCSI_DRIVER_DEVCTL
, errno
);
1805 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1808 if (ioctl(fd
, ISCSI_USCSI
, &uscsi
) != 0) {
1810 syslog(LOG_USER
|LOG_DEBUG
,
1811 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno
);
1812 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1815 if (uscsi
.iu_ucmd
.uscsi_status
== STATUS_CHECK
) {
1816 if (pSenseBufferLength
!= NULL
) {
1817 *pSenseBufferLength
-= uscsi
.iu_ucmd
.uscsi_rqresid
;
1819 return (IMA_ERROR_SCSI_STATUS_CHECK_CONDITION
);
1822 *pOutputBufferLength
= buflen
- uscsi
.iu_ucmd
.uscsi_resid
;
1823 return (IMA_STATUS_SUCCESS
);
1826 IMA_API IMA_STATUS
IMA_LuReadCapacity(
1829 IMA_BYTE
*pOutputBuffer
,
1830 IMA_UINT
*pOutputBufferLength
,
1832 IMA_BYTE
*pSenseBuffer
,
1833 IMA_UINT
*pSenseBufferLength
1836 IMA_LU_PROPERTIES luProps
;
1838 /* CDB_GROUP4 size is safe for both 10 and 16 byte CDBs */
1839 unsigned char cmdblk
[CDB_GROUP4
];
1842 iscsi_uscsi_t uscsi
;
1844 (void) memset(&cmdblk
[0], 0, CDB_GROUP4
);
1846 if (cdbLength
== CDB_GROUP1
) {
1847 /* Read Capacity (10) command. */
1848 cmdblk
[0] = SCMD_READ_CAPACITY
;
1849 buflen
= *pOutputBufferLength
;
1850 } else if (cdbLength
== CDB_GROUP4
) {
1852 * Read Capacity (16) is a Service Action In command. One
1853 * command byte (0x9E) is overloaded for multiple operations,
1854 * with the second CDB byte specifying the desired operation.
1856 cmdblk
[0] = SCMD_SVC_ACTION_IN_G4
;
1857 cmdblk
[1] = SSVC_ACTION_READ_CAPACITY_G4
;
1859 if (*pOutputBufferLength
> MAX_READ_CAPACITY16_BUFFER_LEN
) {
1860 buflen
= MAX_READ_CAPACITY16_BUFFER_LEN
;
1862 buflen
= *pOutputBufferLength
;
1864 cmdblk
[10] = (buflen
& 0xff000000) >> 24;
1865 cmdblk
[11] = (buflen
& 0x00ff0000) >> 16;
1866 cmdblk
[12] = (buflen
& 0x0000ff00) >> 8;
1867 cmdblk
[13] = (buflen
& 0x000000ff);
1869 /* only 10 and 16 byte CDB are supported */
1870 return (IMA_ERROR_NOT_SUPPORTED
);
1873 (void) memset(&uscsi
, 0, sizeof (iscsi_uscsi_t
));
1874 uscsi
.iu_vers
= ISCSI_INTERFACE_VERSION
;
1876 /* iu_oid is a session oid in the driver */
1877 if (deviceId
.objectType
== IMA_OBJECT_TYPE_TARGET
) {
1878 uscsi
.iu_oid
= deviceId
.objectSequenceNumber
;
1882 * Get LU properties and associated session oid
1883 * for this lun(deviceId) and put in uscsi.iu_oid
1885 status
= getLuProperties(deviceId
, &luProps
);
1886 if (status
!= IMA_STATUS_SUCCESS
) {
1889 uscsi
.iu_oid
= (uint32_t)luProps
.associatedTargetOid
.
1890 objectSequenceNumber
;
1891 uscsi
.iu_lun
= luProps
.targetLun
;
1894 uscsi
.iu_ucmd
.uscsi_flags
= USCSI_READ
;
1895 uscsi
.iu_ucmd
.uscsi_timeout
= USCSI_TIMEOUT_IN_SEC
;
1896 uscsi
.iu_ucmd
.uscsi_bufaddr
= (char *)pOutputBuffer
;
1897 uscsi
.iu_ucmd
.uscsi_buflen
= buflen
;
1898 uscsi
.iu_ucmd
.uscsi_rqbuf
= (char *)pSenseBuffer
;
1899 uscsi
.iu_ucmd
.uscsi_rqlen
= (pSenseBufferLength
!= NULL
) ?
1900 *pSenseBufferLength
: 0;
1901 uscsi
.iu_ucmd
.uscsi_cdb
= (char *)&cmdblk
[0];
1902 uscsi
.iu_ucmd
.uscsi_cdblen
= cdbLength
;
1904 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
1905 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
1906 ISCSI_DRIVER_DEVCTL
, errno
);
1907 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1910 if (ioctl(fd
, ISCSI_USCSI
, &uscsi
) != 0) {
1912 syslog(LOG_USER
|LOG_DEBUG
,
1913 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno
);
1914 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
1917 if (uscsi
.iu_ucmd
.uscsi_status
== STATUS_CHECK
) {
1918 if (pSenseBufferLength
!= NULL
) {
1919 *pSenseBufferLength
-= uscsi
.iu_ucmd
.uscsi_rqresid
;
1921 return (IMA_ERROR_SCSI_STATUS_CHECK_CONDITION
);
1924 *pOutputBufferLength
= buflen
- uscsi
.iu_ucmd
.uscsi_resid
;
1925 return (IMA_STATUS_SUCCESS
);
1928 IMA_API IMA_STATUS
IMA_LuReportLuns(
1930 IMA_BOOL sendToWellKnownLun
,
1931 IMA_BYTE selectReport
,
1933 IMA_BYTE
*pOutputBuffer
,
1934 IMA_UINT
*pOutputBufferLength
,
1936 IMA_BYTE
*pSenseBuffer
,
1937 IMA_UINT
*pSenseBufferLength
1940 IMA_LU_PROPERTIES luProps
;
1942 unsigned char cmdblk
[CDB_GROUP5
];
1945 iscsi_uscsi_t uscsi
;
1947 (void) memset(&cmdblk
[0], 0, CDB_GROUP5
);
1948 cmdblk
[0] = SCMD_REPORT_LUNS
;
1949 cmdblk
[2] = selectReport
;
1951 if (*pOutputBufferLength
> MAX_REPORT_LUNS_BUFFER_LEN
) {
1952 buflen
= MAX_REPORT_LUNS_BUFFER_LEN
;
1954 buflen
= *pOutputBufferLength
;
1956 cmdblk
[6] = (buflen
& 0xff000000) >> 24;
1957 cmdblk
[7] = (buflen
& 0x00ff0000) >> 16;
1958 cmdblk
[8] = (buflen
& 0x0000ff00) >> 8;
1959 cmdblk
[9] = (buflen
& 0x000000ff);
1961 (void) memset(&uscsi
, 0, sizeof (iscsi_uscsi_t
));
1962 uscsi
.iu_vers
= ISCSI_INTERFACE_VERSION
;
1964 /* iu_oid is a session oid in the driver */
1965 if (deviceId
.objectType
== IMA_OBJECT_TYPE_TARGET
) {
1966 if (sendToWellKnownLun
== IMA_TRUE
) {
1967 /* this optional feature is not supported now */
1968 return (IMA_ERROR_NOT_SUPPORTED
);
1970 uscsi
.iu_oid
= deviceId
.objectSequenceNumber
;
1974 * Get LU properties and associated session oid
1975 * for this lun(deviceId) and put in uscsi.iu_oid
1977 status
= getLuProperties(deviceId
, &luProps
);
1978 if (status
!= IMA_STATUS_SUCCESS
) {
1981 uscsi
.iu_oid
= (uint32_t)luProps
.associatedTargetOid
.
1982 objectSequenceNumber
;
1983 uscsi
.iu_lun
= luProps
.targetLun
;
1986 uscsi
.iu_ucmd
.uscsi_flags
= USCSI_READ
;
1987 uscsi
.iu_ucmd
.uscsi_timeout
= USCSI_TIMEOUT_IN_SEC
;
1988 uscsi
.iu_ucmd
.uscsi_bufaddr
= (char *)pOutputBuffer
;
1989 uscsi
.iu_ucmd
.uscsi_buflen
= buflen
;
1990 uscsi
.iu_ucmd
.uscsi_rqbuf
= (char *)pSenseBuffer
;
1991 uscsi
.iu_ucmd
.uscsi_rqlen
= (pSenseBufferLength
!= NULL
) ?
1992 *pSenseBufferLength
: 0;
1993 uscsi
.iu_ucmd
.uscsi_cdb
= (char *)&cmdblk
[0];
1994 uscsi
.iu_ucmd
.uscsi_cdblen
= CDB_GROUP5
;
1996 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
1997 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
1998 ISCSI_DRIVER_DEVCTL
, errno
);
1999 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2002 if (ioctl(fd
, ISCSI_USCSI
, &uscsi
) != 0) {
2004 syslog(LOG_USER
|LOG_DEBUG
,
2005 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno
);
2006 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2009 if (uscsi
.iu_ucmd
.uscsi_status
== STATUS_CHECK
) {
2010 if (pSenseBufferLength
!= NULL
) {
2011 *pSenseBufferLength
-= uscsi
.iu_ucmd
.uscsi_rqresid
;
2013 return (IMA_ERROR_SCSI_STATUS_CHECK_CONDITION
);
2016 *pOutputBufferLength
= buflen
- uscsi
.iu_ucmd
.uscsi_resid
;
2017 return (IMA_STATUS_SUCCESS
);
2021 IMA_API IMA_STATUS
IMA_ExposeLu(
2025 return (IMA_ERROR_NOT_SUPPORTED
);
2029 IMA_API IMA_STATUS
IMA_UnexposeLu(
2033 return (IMA_ERROR_NOT_SUPPORTED
);
2036 IMA_API IMA_STATUS
IMA_GetAddressKeys(
2038 IMA_ADDRESS_KEYS
**ppKeys
2042 IMA_TARGET_PROPERTIES targetProps
;
2043 SUN_IMA_DISC_ADDR_PROP_LIST
*discAddressList
;
2044 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
*pList
;
2045 int i
, j
, addressKeyCount
= 0;
2046 int addressKeyIdx
= 0;
2048 status
= getTargetProperties(targetOid
, &targetProps
);
2049 if (status
!= IMA_STATUS_SUCCESS
) {
2053 status
= getDiscoveryAddressPropertiesList(&discAddressList
);
2054 if (status
!= IMA_STATUS_SUCCESS
) {
2058 /* Get the number of addresses to allocate */
2059 for (i
= 0; i
< discAddressList
->discAddrCount
; i
++) {
2060 (void) sendTargets(discAddressList
->props
[i
].discoveryAddress
,
2062 for (j
= 0; j
< pList
->keyCount
; j
++) {
2063 if (wcsncmp(pList
->keys
[j
].name
, targetProps
.name
,
2064 wslen(pList
->keys
[j
].name
)) == 0) {
2068 (void) IMA_FreeMemory(pList
);
2071 *ppKeys
= (IMA_ADDRESS_KEYS
*)calloc(1, sizeof (IMA_ADDRESS_KEYS
) +
2072 addressKeyCount
* sizeof (IMA_ADDRESS_KEY
));
2073 if (*ppKeys
== NULL
) {
2074 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2076 (*ppKeys
)->addressKeyCount
= addressKeyCount
;
2079 for (i
= 0; i
< discAddressList
->discAddrCount
; i
++) {
2080 (void) sendTargets(discAddressList
->props
[i
].discoveryAddress
,
2082 for (j
= 0; j
< pList
->keyCount
; j
++) {
2083 if (wcsncmp(pList
->keys
[j
].name
, targetProps
.name
,
2084 wslen(pList
->keys
[j
].name
)) != 0) {
2088 bcopy(&(pList
->keys
[j
].address
.ipAddress
),
2089 &((*ppKeys
)->addressKeys
[addressKeyIdx
].
2090 ipAddress
), sizeof (IMA_IP_ADDRESS
));
2092 (*ppKeys
)->addressKeys
[addressKeyIdx
++].portNumber
=
2093 pList
->keys
[j
].address
.portNumber
;
2096 (void) IMA_FreeMemory(pList
);
2098 return (IMA_STATUS_SUCCESS
);
2101 IMA_BOOL
isAuthMethodValid(IMA_OID oid
, IMA_AUTHMETHOD method
) {
2103 IMA_AUTHMETHOD supportedList
[MAX_AUTHMETHODS
];
2104 IMA_UINT i
, supportedCount
;
2106 status
= getSupportedAuthMethods(oid
, IMA_FALSE
, &supportedCount
,
2108 if (status
!= IMA_STATUS_SUCCESS
)
2111 supported
= IMA_FALSE
;
2112 for (i
= 0; i
< supportedCount
; i
++) {
2113 if (method
== supportedList
[i
]) {
2114 supported
= IMA_TRUE
;
2121 IMA_BOOL
isAuthMethodListValid(IMA_OID oid
, const IMA_AUTHMETHOD
*pMethodList
,
2122 IMA_UINT methodCount
) {
2125 if (pMethodList
== NULL
) {
2128 /* Check list for duplicates */
2129 for (i
= 0; i
< methodCount
; i
++) {
2130 for (j
= i
+ 1; j
< methodCount
; j
++) {
2131 if (pMethodList
[i
] == pMethodList
[j
]) {
2136 if (isAuthMethodValid(oid
, pMethodList
[i
]) == IMA_FALSE
) {
2143 IMA_API IMA_STATUS
IMA_GetSupportedAuthMethods(
2145 IMA_BOOL getSettableMethods
,
2146 IMA_UINT
*pMethodCount
,
2147 IMA_AUTHMETHOD
*pMethodList
2150 return (getSupportedAuthMethods(lhbaOid
, getSettableMethods
,
2151 pMethodCount
, pMethodList
));
2156 static IMA_STATUS
getSupportedAuthMethods(
2158 IMA_BOOL getSettableMethods
,
2159 IMA_UINT
*pMethodCount
,
2160 IMA_AUTHMETHOD
*pMethodList
2163 if (pMethodList
== NULL
) {
2165 return (IMA_STATUS_SUCCESS
);
2168 *pMethodCount
= NUM_SUPPORTED_AUTH_METHODS
;
2169 if (*pMethodCount
> 1) {
2170 pMethodList
[0] = IMA_AUTHMETHOD_NONE
;
2171 pMethodList
[1] = IMA_AUTHMETHOD_CHAP
;
2174 return (IMA_STATUS_SUCCESS
);
2177 IMA_API IMA_STATUS
IMA_GetInUseInitiatorAuthMethods(
2179 IMA_UINT
*pMethodCount
,
2180 IMA_AUTHMETHOD
*pMethodList
2183 return (getAuthMethods(lhbaOid
, pMethodCount
, pMethodList
));
2187 IMA_API IMA_STATUS
IMA_GetInitiatorAuthParms(
2189 IMA_AUTHMETHOD method
,
2190 IMA_INITIATOR_AUTHPARMS
*pParms
2194 iscsi_chap_props_t chap_p
;
2196 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
2197 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
2198 ISCSI_DRIVER_DEVCTL
, errno
);
2199 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2202 (void) memset(&chap_p
, 0, sizeof (iscsi_chap_props_t
));
2203 chap_p
.c_vers
= ISCSI_INTERFACE_VERSION
;
2204 chap_p
.c_oid
= (uint32_t)lhbaOid
.objectSequenceNumber
;
2206 if (method
== IMA_AUTHMETHOD_CHAP
) {
2207 if (ioctl(fd
, ISCSI_CHAP_GET
, &chap_p
) != 0) {
2208 syslog(LOG_USER
|LOG_DEBUG
,
2209 "ISCSI_CHAP_GET ioctl failed, errno: %d", errno
);
2211 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2214 return (IMA_ERROR_INVALID_PARAMETER
);
2217 (void) memcpy(pParms
->chapParms
.name
, chap_p
.c_user
,
2219 pParms
->chapParms
.nameLength
= chap_p
.c_user_len
;
2220 (void) memcpy(pParms
->chapParms
.challengeSecret
, chap_p
.c_secret
,
2221 chap_p
.c_secret_len
);
2222 pParms
->chapParms
.challengeSecretLength
= chap_p
.c_secret_len
;
2224 return (IMA_STATUS_SUCCESS
);
2227 IMA_API IMA_STATUS
IMA_SetInitiatorAuthMethods(
2229 IMA_UINT methodCount
,
2230 const IMA_AUTHMETHOD
*pMethodList
2233 if (isAuthMethodListValid(lhbaOid
, pMethodList
,
2234 methodCount
) == IMA_FALSE
)
2235 return (IMA_ERROR_INVALID_PARAMETER
);
2236 return (setAuthMethods(lhbaOid
, &methodCount
, pMethodList
));
2240 * This function only sets CHAP params since we only support CHAP for now.
2242 IMA_API IMA_STATUS
IMA_SetInitiatorAuthParms(
2244 IMA_AUTHMETHOD method
,
2245 const IMA_INITIATOR_AUTHPARMS
*pParms
2249 iscsi_chap_props_t chap_p
;
2251 if (method
!= IMA_AUTHMETHOD_CHAP
)
2252 return (IMA_ERROR_INVALID_PARAMETER
);
2254 if (isAuthMethodValid(lhbaOid
, method
) == IMA_FALSE
) {
2255 return (IMA_ERROR_INVALID_PARAMETER
);
2258 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
2259 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
2260 ISCSI_DRIVER_DEVCTL
, errno
);
2261 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2264 (void) memset(&chap_p
, 0, sizeof (iscsi_chap_props_t
));
2265 chap_p
.c_vers
= ISCSI_INTERFACE_VERSION
;
2266 chap_p
.c_oid
= (uint32_t)lhbaOid
.objectSequenceNumber
;
2268 chap_p
.c_user_len
= pParms
->chapParms
.nameLength
;
2269 (void) memcpy(chap_p
.c_user
, pParms
->chapParms
.name
, chap_p
.c_user_len
);
2271 chap_p
.c_secret_len
= pParms
->chapParms
.challengeSecretLength
;
2272 (void) memcpy(chap_p
.c_secret
, pParms
->chapParms
.challengeSecret
,
2273 chap_p
.c_secret_len
);
2275 if (method
== IMA_AUTHMETHOD_CHAP
) {
2276 if (ioctl(fd
, ISCSI_CHAP_SET
, &chap_p
) != 0) {
2278 syslog(LOG_USER
|LOG_DEBUG
,
2279 "ISCSI_CHAP_SET ioctl failed, errno: %d", errno
);
2280 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2284 return (IMA_STATUS_SUCCESS
);
2287 /* A helper function to obtain iSCSI node parameters. */
2289 getISCSINodeParameter(
2297 iscsi_param_get_t pg
;
2299 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
2300 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
2301 ISCSI_DRIVER_DEVCTL
, errno
);
2302 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2305 (void) memset(&pg
, 0, sizeof (iscsi_param_get_t
));
2306 pg
.g_vers
= ISCSI_INTERFACE_VERSION
;
2307 pg
.g_oid
= (uint32_t)oid
->objectSequenceNumber
;
2308 pg
.g_param
= paramIndex
;
2309 pg
.g_param_type
= ISCSI_SESS_PARAM
;
2311 if (ioctl(fd
, ISCSI_PARAM_GET
, &pg
) != 0) {
2312 syslog(LOG_USER
|LOG_DEBUG
,
2313 "ISCSI_PARAM_GET ioctl failed, errno: %d", errno
);
2315 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2318 switch (paramType
) {
2320 IMA_MIN_MAX_VALUE
*mp
;
2323 mp
= (IMA_MIN_MAX_VALUE
*)pProps
;
2325 mp
->currentValueValid
=
2326 (pg
.g_value
.v_valid
== B_TRUE
) ?
2327 IMA_TRUE
: IMA_FALSE
;
2328 mp
->currentValue
= pg
.g_value
.v_integer
.i_current
;
2329 mp
->defaultValue
= pg
.g_value
.v_integer
.i_default
;
2330 mp
->minimumValue
= pg
.g_value
.v_integer
.i_min
;
2331 mp
->maximumValue
= pg
.g_value
.v_integer
.i_max
;
2332 mp
->incrementValue
= pg
.g_value
.v_integer
.i_incr
;
2336 bp
= (IMA_BOOL_VALUE
*)pProps
;
2337 bp
->currentValueValid
=
2338 (pg
.g_value
.v_valid
== B_TRUE
) ?
2339 IMA_TRUE
: IMA_FALSE
;
2340 bp
->currentValue
= pg
.g_value
.v_bool
.b_current
;
2341 bp
->defaultValue
= pg
.g_value
.v_bool
.b_default
;
2349 return (IMA_STATUS_SUCCESS
);
2352 /* A helper function to set iSCSI node parameters. */
2354 setISCSINodeParameter(
2362 iscsi_param_set_t ps
;
2364 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
2365 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
2366 ISCSI_DRIVER_DEVCTL
, errno
);
2367 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2370 (void) memset(&ps
, 0, sizeof (iscsi_param_set_t
));
2371 ps
.s_vers
= ISCSI_INTERFACE_VERSION
;
2372 ps
.s_oid
= (uint32_t)oid
->objectSequenceNumber
;
2373 ps
.s_param
= paramIndex
;
2375 switch (paramType
) {
2377 IMA_MIN_MAX_VALUE
*mp
;
2380 mp
= (IMA_MIN_MAX_VALUE
*)pProp
;
2381 ps
.s_value
.v_integer
= mp
->currentValue
;
2384 bp
= (IMA_BOOL_VALUE
*)pProp
;
2386 (bp
->currentValue
== IMA_TRUE
) ?
2394 if (ioctl(fd
, ISCSI_PARAM_SET
, &ps
)) {
2395 int tmpErrno
= errno
;
2396 syslog(LOG_USER
|LOG_DEBUG
,
2397 "ISCSI_PARAM_SET ioctl failed, errno: %d", errno
);
2401 return (IMA_ERROR_NOT_SUPPORTED
);
2403 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2408 return (IMA_STATUS_SUCCESS
);
2412 prepare_discovery_entry(
2413 IMA_TARGET_ADDRESS discoveryAddress
,
2417 (void) memset(entry
, 0, sizeof (entry_t
));
2418 entry
->e_vers
= ISCSI_INTERFACE_VERSION
;
2419 entry
->e_oid
= ISCSI_OID_NOTSET
;
2421 if (discoveryAddress
.hostnameIpAddress
.id
.ipAddress
.ipv4Address
==
2423 bcopy(discoveryAddress
.hostnameIpAddress
.id
.ipAddress
.ipAddress
,
2424 entry
->e_u
.u_in6
.s6_addr
,
2425 sizeof (entry
->e_u
.u_in6
.s6_addr
));
2426 entry
->e_insize
= sizeof (struct in6_addr
);
2428 bcopy(discoveryAddress
.hostnameIpAddress
.id
.ipAddress
.ipAddress
,
2429 &entry
->e_u
.u_in4
.s_addr
,
2430 sizeof (entry
->e_u
.u_in4
.s_addr
));
2431 entry
->e_insize
= sizeof (struct in_addr
);
2434 entry
->e_port
= discoveryAddress
.portNumber
;
2436 return (DISC_ADDR_OK
);
2439 static IMA_STATUS
configure_discovery_method(
2441 iSCSIDiscoveryMethod_t method
2446 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
2447 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
2448 ISCSI_DRIVER_DEVCTL
, errno
);
2449 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2452 if (enable
== IMA_FALSE
) {
2453 if (ioctl(fd
, ISCSI_DISCOVERY_CLEAR
, &method
)) {
2456 syslog(LOG_USER
|LOG_DEBUG
,
2457 "ISCSI_DISCOVERY_CLEAR ioctl failed, errno: %d",
2459 if (status
== EBUSY
) {
2460 return (IMA_ERROR_LU_IN_USE
);
2462 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2467 return (IMA_STATUS_SUCCESS
);
2469 /* Set the discovery method */
2470 if (ioctl(fd
, ISCSI_DISCOVERY_SET
, &method
)) {
2472 syslog(LOG_USER
|LOG_DEBUG
,
2473 "ISCSI_DISCOVERY_SET ioctl failed, errno: %d",
2475 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2479 return (IMA_STATUS_SUCCESS
);
2483 static IMA_STATUS
get_target_oid_list(
2484 uint32_t targetListType
,
2485 IMA_OID_LIST
**ppList
)
2489 int target_list_size
;
2490 iscsi_target_list_t
*idlp
, tl_info
;
2492 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
2493 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
2494 ISCSI_DRIVER_DEVCTL
, errno
);
2495 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2498 (void) memset(&tl_info
, 0, sizeof (tl_info
));
2499 tl_info
.tl_vers
= ISCSI_INTERFACE_VERSION
;
2500 tl_info
.tl_in_cnt
= 0;
2501 tl_info
.tl_tgt_list_type
= targetListType
;
2504 * Issue ioctl to obtain the number of targets.
2506 if (ioctl(fd
, ISCSI_TARGET_OID_LIST_GET
, &tl_info
) != 0) {
2508 syslog(LOG_USER
|LOG_DEBUG
,
2509 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
2510 targetListType
, errno
);
2511 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2514 target_list_size
= sizeof (iscsi_target_list_t
);
2515 if (tl_info
.tl_out_cnt
> 1) {
2516 target_list_size
+= (sizeof (uint32_t) *
2517 tl_info
.tl_out_cnt
- 1);
2520 idlp
= (iscsi_target_list_t
*)calloc(1, target_list_size
);
2523 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2526 idlp
->tl_vers
= ISCSI_INTERFACE_VERSION
;
2527 idlp
->tl_in_cnt
= tl_info
.tl_out_cnt
;
2528 idlp
->tl_tgt_list_type
= targetListType
;
2530 /* Issue the same ioctl again to obtain the OIDs. */
2531 if (ioctl(fd
, ISCSI_TARGET_OID_LIST_GET
, idlp
) != 0) {
2534 syslog(LOG_USER
|LOG_DEBUG
,
2535 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
2536 targetListType
, errno
);
2537 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2540 *ppList
= (IMA_OID_LIST
*)calloc(1, sizeof (IMA_OID_LIST
) +
2541 idlp
->tl_out_cnt
* sizeof (IMA_OID
));
2542 if (*ppList
== NULL
) {
2545 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2547 (*ppList
)->oidCount
= idlp
->tl_out_cnt
;
2549 for (i
= 0; i
< idlp
->tl_out_cnt
; i
++) {
2551 if (targetListType
== ISCSI_STATIC_TGT_OID_LIST
)
2552 (*ppList
)->oids
[i
].objectType
=
2553 IMA_OBJECT_TYPE_STATIC_DISCOVERY_TARGET
;
2555 (*ppList
)->oids
[i
].objectType
= IMA_OBJECT_TYPE_TARGET
;
2557 (*ppList
)->oids
[i
].ownerId
= pluginOwnerId
;
2558 (*ppList
)->oids
[i
].objectSequenceNumber
= idlp
->tl_oid_list
[i
];
2563 return (IMA_STATUS_SUCCESS
);
2566 static IMA_STATUS
get_target_lun_oid_list(
2567 IMA_OID
* targetOid
,
2568 iscsi_lun_list_t
**ppLunList
)
2571 iscsi_lun_list_t
*illp
, ll_info
;
2574 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
2575 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
2576 ISCSI_DRIVER_DEVCTL
, errno
);
2577 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2580 (void) memset(&ll_info
, 0, sizeof (ll_info
));
2581 ll_info
.ll_vers
= ISCSI_INTERFACE_VERSION
;
2582 if (targetOid
== NULL
) {
2583 /* get lun oid list for all targets */
2584 ll_info
.ll_all_tgts
= B_TRUE
;
2586 /* get lun oid list for single target */
2587 ll_info
.ll_all_tgts
= B_FALSE
;
2588 ll_info
.ll_tgt_oid
= (uint32_t)targetOid
->objectSequenceNumber
;
2590 ll_info
.ll_in_cnt
= 0;
2593 * Issue ioctl to obtain the number of target LUNs.
2595 if (ioctl(fd
, ISCSI_LUN_OID_LIST_GET
, &ll_info
) != 0) {
2597 syslog(LOG_USER
|LOG_DEBUG
,
2598 "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", errno
);
2599 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2602 lun_list_size
= sizeof (iscsi_lun_list_t
);
2603 if (ll_info
.ll_out_cnt
> 1) {
2604 lun_list_size
+= (sizeof (iscsi_if_lun_t
) *
2605 (ll_info
.ll_out_cnt
- 1));
2608 illp
= (iscsi_lun_list_t
*)calloc(1, lun_list_size
);
2611 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2613 illp
->ll_vers
= ISCSI_INTERFACE_VERSION
;
2614 illp
->ll_all_tgts
= ll_info
.ll_all_tgts
;
2615 illp
->ll_tgt_oid
= ll_info
.ll_tgt_oid
;
2616 illp
->ll_in_cnt
= ll_info
.ll_out_cnt
;
2618 /* Issue the same ioctl again to get the target LUN list */
2619 if (ioctl(fd
, ISCSI_LUN_OID_LIST_GET
, illp
) != 0) {
2622 syslog(LOG_USER
|LOG_DEBUG
,
2623 "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", errno
);
2624 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2630 return (IMA_STATUS_SUCCESS
);
2634 /* A helper function to set authentication method. */
2638 IMA_UINT
*pMethodCount
,
2639 const IMA_AUTHMETHOD
*pMethodList
2644 iscsi_auth_props_t auth
;
2646 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
2647 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
2648 ISCSI_DRIVER_DEVCTL
, errno
);
2649 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2651 (void) memset(&auth
, 0, sizeof (iscsi_auth_props_t
));
2652 auth
.a_vers
= ISCSI_INTERFACE_VERSION
;
2653 auth
.a_oid
= (uint32_t)oid
.objectSequenceNumber
;
2654 /* First do a get because other data fields may exist */
2655 if (ioctl(fd
, ISCSI_AUTH_GET
, &auth
) != 0) {
2657 /* It is fine if there is no other data fields. */
2659 auth
.a_auth_method
= authMethodNone
;
2661 for (i
= 0; i
< *pMethodCount
; i
++) {
2662 switch (pMethodList
[i
]) {
2663 case IMA_AUTHMETHOD_CHAP
:
2664 auth
.a_auth_method
|= authMethodCHAP
;
2671 if (ioctl(fd
, ISCSI_AUTH_SET
, &auth
) != 0) {
2672 syslog(LOG_USER
|LOG_DEBUG
,
2673 "ISCSI_AUTH_SET failed, errno: %d", errno
);
2675 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2679 return (IMA_STATUS_SUCCESS
);
2682 /* A helper function to get authentication method. */
2686 IMA_UINT
*pMethodCount
,
2687 IMA_AUTHMETHOD
*pMethodList
2691 iscsi_auth_props_t auth
;
2693 if (pMethodList
== NULL
) {
2695 return (IMA_STATUS_SUCCESS
);
2698 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
2699 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
2700 ISCSI_DRIVER_DEVCTL
, errno
);
2701 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2704 (void) memset(&auth
, 0, sizeof (iscsi_auth_props_t
));
2705 auth
.a_vers
= ISCSI_INTERFACE_VERSION
;
2706 auth
.a_oid
= (uint32_t)oid
.objectSequenceNumber
;
2708 if (ioctl(fd
, ISCSI_AUTH_GET
, &auth
) != 0) {
2709 syslog(LOG_USER
|LOG_DEBUG
,
2710 "ISCSI_AUTH_GET failed, errno: %d", errno
);
2712 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
2716 if (auth
.a_auth_method
== authMethodNone
) {
2717 pMethodList
[i
++] = IMA_AUTHMETHOD_NONE
;
2718 } else if (auth
.a_auth_method
& authMethodCHAP
) {
2719 pMethodList
[i
++] = IMA_AUTHMETHOD_CHAP
;
2724 return (IMA_STATUS_SUCCESS
);
2727 IMA_API IMA_STATUS
IMA_GetPhbaOidList(
2728 IMA_OID_LIST
**ppList
2731 *ppList
= (IMA_OID_LIST
*)calloc(1, sizeof (IMA_OID_LIST
));
2732 if (*ppList
== NULL
) {
2733 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2735 (*ppList
)->oidCount
= 0;
2736 return (IMA_STATUS_SUCCESS
);
2740 IMA_API IMA_STATUS
IMA_GetPhbaProperties(
2742 IMA_PHBA_PROPERTIES
*pProps
2745 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2749 IMA_API IMA_STATUS
IMA_GetPhbaStatus(
2751 IMA_PHBA_STATUS
*pStatus
2754 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2758 IMA_API IMA_STATUS
IMA_GetPhbaDownloadProperties(
2760 IMA_PHBA_DOWNLOAD_PROPERTIES
*pProps
2763 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2767 IMA_API IMA_STATUS
IMA_IsPhbaDownloadFile(
2769 const IMA_WCHAR
*pFileName
,
2770 IMA_PHBA_DOWNLOAD_IMAGE_PROPERTIES
*pProps
2773 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2777 IMA_API IMA_STATUS
IMA_PhbaDownload(
2779 IMA_PHBA_DOWNLOAD_IMAGE_TYPE imageType
,
2780 const IMA_WCHAR
*pFileName
2783 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2786 IMA_API IMA_STATUS
IMA_GetPnpOidList(
2788 IMA_OID_LIST
**ppList
2792 * Always return the same object ID for the pnp as the spec
2793 * states that this function will always return a list of at least
2796 pnpOid
.objectType
= IMA_OBJECT_TYPE_PNP
;
2797 pnpOid
.ownerId
= pluginOwnerId
;
2798 pnpOid
.objectSequenceNumber
= ISCSI_INITIATOR_OID
;
2800 *ppList
= (IMA_OID_LIST
*)calloc(1, sizeof (IMA_OID_LIST
) +
2801 (1* sizeof (IMA_OID
)));
2803 if (*ppList
== NULL
) {
2804 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
2807 (*ppList
)->oidCount
= 1;
2808 (void) memcpy(&(*ppList
)->oids
[0], &pnpOid
, sizeof (pnpOid
));
2809 return (IMA_STATUS_SUCCESS
);
2813 IMA_API IMA_STATUS
IMA_GetPnpProperties(
2815 IMA_PNP_PROPERTIES
*pProps
2818 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2822 IMA_API IMA_STATUS
IMA_GetPnpStatistics(
2824 IMA_PNP_STATISTICS
*pStats
2827 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2831 IMA_API IMA_STATUS
IMA_GetIpProperties(
2833 IMA_IP_PROPERTIES
*pProps
2836 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2840 IMA_API IMA_STATUS
IMA_SetDefaultGateway(
2842 IMA_IP_ADDRESS defaultGateway
2845 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2849 IMA_API IMA_STATUS
IMA_SetDnsServerAddress(
2851 const IMA_IP_ADDRESS
*pPrimaryDnsServerAddress
,
2852 const IMA_IP_ADDRESS
*pAlternateDnsServerAddress
2855 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2859 IMA_API IMA_STATUS
IMA_SetSubnetMask(
2861 IMA_IP_ADDRESS subnetMask
2864 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2868 IMA_API IMA_STATUS
IMA_SetIpConfigMethod(
2870 IMA_BOOL enableDhcpIpConfiguration
2873 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2876 IMA_API IMA_STATUS
IMA_RegisterForObjectPropertyChanges(
2877 IMA_OBJECT_PROPERTY_FN pClientFn
2880 pObjectPropertyCallback
= pClientFn
;
2881 return (IMA_STATUS_SUCCESS
);
2885 IMA_API IMA_STATUS
IMA_DeregisterForObjectPropertyChanges(
2886 IMA_OBJECT_PROPERTY_FN pClientFn
2889 return (IMA_STATUS_SUCCESS
);
2892 IMA_API IMA_STATUS
IMA_RegisterForObjectVisibilityChanges(
2893 IMA_OBJECT_VISIBILITY_FN pClientFn
2896 pObjectVisibilityCallback
= pClientFn
;
2897 return (IMA_STATUS_SUCCESS
);
2901 IMA_API IMA_STATUS
IMA_DeregisterForObjectVisibilityChanges(
2902 IMA_OBJECT_VISIBILITY_FN pClientFn
2905 return (IMA_STATUS_SUCCESS
);
2909 IMA_API IMA_STATUS
IMA_GetNetworkPortStatus(
2911 IMA_NETWORK_PORT_STATUS
*pStaus
2914 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2918 IMA_API IMA_STATUS
IMA_GetNetworkPortalOidList(
2920 IMA_OID_LIST
**ppList
2923 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2927 IMA_API IMA_STATUS
IMA_GetNetworkPortalProperties(
2928 IMA_OID networkPortalOid
,
2929 IMA_NETWORK_PORTAL_PROPERTIES
*pProps
2932 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2936 IMA_API IMA_STATUS
IMA_SetNetworkPortalIpAddress(
2937 IMA_OID networkPortalOid
,
2938 const IMA_IP_ADDRESS NewIpAddress
2941 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2945 IMA_API IMA_STATUS
IMA_RemoveStaleData(
2949 return (IMA_ERROR_NOT_SUPPORTED
);
2953 IMA_API IMA_STATUS
IMA_GetIpsecProperties(
2955 IMA_IPSEC_PROPERTIES
*pProps
2958 pProps
->ipsecSupported
= IMA_TRUE
;
2959 pProps
->implementedInHardware
= IMA_FALSE
;
2960 pProps
->implementedInSoftware
= IMA_TRUE
;
2962 return (IMA_STATUS_SUCCESS
);
2966 IMA_API IMA_STATUS
IMA_GetLhbaProperties(
2968 IMA_LHBA_PROPERTIES
*pProps
2972 if (pProps
== NULL
) {
2973 return (IMA_ERROR_INVALID_PARAMETER
);
2976 if (lhbaObjectId
.objectSequenceNumber
!= ISCSI_INITIATOR_OID
) {
2977 return (IMA_ERROR_OBJECT_NOT_FOUND
);
2980 (void) memset(pProps
, 0, sizeof (IMA_LHBA_PROPERTIES
));
2981 (void) mbstowcs(pProps
->osDeviceName
, OS_DEVICE_NAME
,
2982 OS_DEVICE_NAME_LEN
);
2983 pProps
->luExposingSupported
= IMA_FALSE
;
2984 pProps
->isDestroyable
= IMA_FALSE
;
2985 pProps
->staleDataRemovable
= IMA_FALSE
;
2986 pProps
->staleDataSize
= 0;
2987 pProps
->initiatorAuthMethodsSettable
= IMA_TRUE
;
2988 pProps
->targetAuthMethodsSettable
= IMA_FALSE
;
2990 return (IMA_STATUS_SUCCESS
);
2993 IMA_API IMA_STATUS
IMA_GetLnpOidList(
2994 IMA_OID_LIST
**ppList
2997 *ppList
= (IMA_OID_LIST
*) calloc(1, (sizeof (IMA_OID_LIST
)));
2998 if (*ppList
== NULL
) {
2999 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
3001 (*ppList
)->oidCount
= 0;
3003 return (IMA_STATUS_SUCCESS
);
3007 IMA_API IMA_STATUS
IMA_GetLnpProperties(
3009 IMA_LNP_PROPERTIES
*pProps
3012 return (IMA_ERROR_OBJECT_NOT_FOUND
);
3015 #define IMA_DISK_DEVICE_NAME_PREFIX "/dev/rdsk/"
3016 #define IMA_TAPE_DEVICE_NAME_PREFIX "/dev/rmt/"
3018 get_lun_devlink(di_devlink_t link
, void *osDeviceName
)
3020 if ((strncmp(IMA_DISK_DEVICE_NAME_PREFIX
, di_devlink_path(link
),
3021 strlen(IMA_DISK_DEVICE_NAME_PREFIX
)) == 0) ||
3022 (strncmp(IMA_TAPE_DEVICE_NAME_PREFIX
, di_devlink_path(link
),
3023 strlen(IMA_TAPE_DEVICE_NAME_PREFIX
)) == 0)) {
3024 (void) mbstowcs((wchar_t *)osDeviceName
, di_devlink_path(link
),
3026 return (DI_WALK_TERMINATE
);
3029 return (DI_WALK_CONTINUE
);
3033 IMA_API IMA_STATUS
IMA_GetPluginProperties(
3035 IMA_PLUGIN_PROPERTIES
*pProps
3038 pProps
->supportedImaVersion
= 1;
3039 libSwprintf(pProps
->vendor
, L
"%ls", LIBRARY_PROPERTY_VENDOR
);
3040 libSwprintf(pProps
->implementationVersion
, L
"%ls",
3041 LIBRARY_PROPERTY_IMPLEMENTATION_VERSION
);
3042 libSwprintf(pProps
->fileName
, L
"%ls", LIBRARY_FILE_NAME
);
3043 GetBuildTime(&(pProps
->buildTime
));
3044 pProps
->lhbasCanBeCreatedAndDestroyed
= IMA_FALSE
;
3045 return (IMA_STATUS_SUCCESS
);
3048 IMA_STATUS
getDiscoveryAddressPropertiesList(
3049 SUN_IMA_DISC_ADDR_PROP_LIST
**ppList
3054 int discovery_addr_list_size
;
3055 iscsi_addr_list_t
*ialp
, al_info
;
3057 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
3058 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
3059 ISCSI_DRIVER_DEVCTL
, errno
);
3060 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3063 (void) memset(&al_info
, 0, sizeof (al_info
));
3064 al_info
.al_vers
= ISCSI_INTERFACE_VERSION
;
3065 al_info
.al_in_cnt
= 0;
3068 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl to obtain the number of
3069 * discovery addresses.
3071 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_LIST_GET
, &al_info
) != 0) {
3073 syslog(LOG_USER
|LOG_DEBUG
,
3074 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d",
3076 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3079 discovery_addr_list_size
= sizeof (iscsi_addr_list_t
);
3080 if (al_info
.al_out_cnt
> 1) {
3081 discovery_addr_list_size
+= (sizeof (iscsi_addr_t
) *
3082 al_info
.al_out_cnt
- 1);
3085 ialp
= (iscsi_addr_list_t
*)calloc(1, discovery_addr_list_size
);
3088 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
3090 ialp
->al_vers
= ISCSI_INTERFACE_VERSION
;
3091 ialp
->al_in_cnt
= al_info
.al_out_cnt
;
3094 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl again to obtain the
3095 * discovery addresses.
3097 if (ioctl(fd
, ISCSI_DISCOVERY_ADDR_LIST_GET
, ialp
) != 0) {
3100 syslog(LOG_USER
|LOG_DEBUG
,
3101 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d",
3103 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3106 *ppList
= (SUN_IMA_DISC_ADDR_PROP_LIST
*)
3107 calloc(1, sizeof (SUN_IMA_DISC_ADDR_PROP_LIST
) +
3108 ialp
->al_out_cnt
* sizeof (IMA_DISCOVERY_ADDRESS_PROPERTIES
));
3110 if (*ppList
== NULL
) {
3113 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
3115 (*ppList
)->discAddrCount
= ialp
->al_out_cnt
;
3117 for (i
= 0; i
< ialp
->al_out_cnt
; i
++) {
3118 if (ialp
->al_addrs
[i
].a_addr
.i_insize
==
3119 sizeof (struct in_addr
)) {
3120 (*ppList
)->props
[i
].discoveryAddress
.hostnameIpAddress
.
3121 id
.ipAddress
.ipv4Address
= IMA_TRUE
;
3122 } else if (ialp
->al_addrs
[i
].a_addr
.i_insize
==
3123 sizeof (struct in6_addr
)) {
3124 (*ppList
)->props
[i
].discoveryAddress
.
3125 hostnameIpAddress
.id
.ipAddress
.ipv4Address
= IMA_FALSE
;
3127 /* Should not happen */
3128 syslog(LOG_USER
|LOG_DEBUG
,
3129 "ISCSI_STATIC_GET returned bad address");
3130 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3133 bcopy(&ialp
->al_addrs
[i
].a_addr
.i_addr
, (*ppList
)->props
[i
].
3134 discoveryAddress
.hostnameIpAddress
.id
.ipAddress
.ipAddress
,
3135 sizeof ((*ppList
)->props
[i
].discoveryAddress
.
3136 hostnameIpAddress
.id
.ipAddress
.ipAddress
));
3138 (*ppList
)->props
[i
].discoveryAddress
.portNumber
=
3139 ialp
->al_addrs
[i
].a_port
;
3144 return (IMA_STATUS_SUCCESS
);
3149 IMA_STATUS
sendTargets(
3150 IMA_TARGET_ADDRESS address
,
3151 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
**ppList
3155 char discAddrStr
[SUN_IMA_IP_ADDRESS_LEN
];
3159 iscsi_sendtgts_list_t
*stl_hdr
= NULL
;
3160 IMA_BOOL retry
= IMA_TRUE
;
3162 #define SENDTGTS_DEFAULT_NUM_TARGETS 10
3164 stl_sz
= sizeof (*stl_hdr
) + ((SENDTGTS_DEFAULT_NUM_TARGETS
- 1) *
3165 sizeof (iscsi_sendtgts_entry_t
));
3166 stl_hdr
= (iscsi_sendtgts_list_t
*)calloc(1, stl_sz
);
3167 if (stl_hdr
== NULL
) {
3168 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
3170 stl_hdr
->stl_entry
.e_vers
= ISCSI_INTERFACE_VERSION
;
3171 stl_hdr
->stl_in_cnt
= SENDTGTS_DEFAULT_NUM_TARGETS
;
3173 colonPos
= strchr(discAddrStr
, ':');
3174 if (colonPos
== NULL
) {
3176 stl_hdr
->stl_entry
.e_insize
= sizeof (struct in_addr
);
3179 stl_hdr
->stl_entry
.e_insize
= sizeof (struct in6_addr
);
3183 bcopy(address
.hostnameIpAddress
.id
.ipAddress
.ipAddress
,
3184 &stl_hdr
->stl_entry
.e_u
,
3185 sizeof (address
.hostnameIpAddress
.id
.ipAddress
.ipAddress
));
3186 stl_hdr
->stl_entry
.e_port
= address
.portNumber
;
3188 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
3189 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
3190 ISCSI_DRIVER_DEVCTL
, errno
);
3191 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3196 * Issue ioctl to obtain the SendTargets list
3198 if (ioctl(fd
, ISCSI_SENDTGTS_GET
, stl_hdr
) != 0) {
3199 syslog(LOG_USER
|LOG_DEBUG
,
3200 "ISCSI_SENDTGTS_GET ioctl failed, errno: %d", errno
);
3203 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3206 /* check if all targets received */
3207 if (stl_hdr
->stl_in_cnt
< stl_hdr
->stl_out_cnt
) {
3208 if (retry
== IMA_TRUE
) {
3209 stl_sz
= sizeof (*stl_hdr
) +
3210 ((stl_hdr
->stl_out_cnt
- 1) *
3211 sizeof (iscsi_sendtgts_entry_t
));
3212 stl_hdr
= (iscsi_sendtgts_list_t
*)
3213 realloc(stl_hdr
, stl_sz
);
3214 if (stl_hdr
== NULL
) {
3216 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
3218 stl_hdr
->stl_in_cnt
= stl_hdr
->stl_out_cnt
;
3220 goto retry_sendtgts
;
3223 * don't retry after 2 attempts. The target list
3224 * shouldn't continue to growing. Justs continue
3225 * on and display what was found.
3227 syslog(LOG_USER
|LOG_DEBUG
,
3228 "ISCSI_SENDTGTS_GET overflow: "
3229 "failed to obtain all targets");
3230 stl_hdr
->stl_out_cnt
= stl_hdr
->stl_in_cnt
;
3236 /* allocate for caller return buffer */
3237 *ppList
= (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
*)calloc(1,
3238 sizeof (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
) +
3239 stl_hdr
->stl_out_cnt
* sizeof (SUN_IMA_DISC_ADDRESS_KEY
));
3240 if (*ppList
== NULL
) {
3242 return (IMA_ERROR_INSUFFICIENT_MEMORY
);
3245 (*ppList
)->keyCount
= stl_hdr
->stl_out_cnt
;
3247 for (ctr
= 0; ctr
< stl_hdr
->stl_out_cnt
; ctr
++) {
3248 (void) mbstowcs((*ppList
)->keys
[ctr
].name
,
3249 (char *)stl_hdr
->stl_list
[ctr
].ste_name
,
3252 (*ppList
)->keys
[ctr
].tpgt
= stl_hdr
->stl_list
[ctr
].ste_tpgt
;
3254 (*ppList
)->keys
[ctr
].address
.portNumber
=
3255 stl_hdr
->stl_list
[ctr
].ste_ipaddr
.a_port
;
3257 if (stl_hdr
->stl_list
[ctr
].ste_ipaddr
.a_addr
.i_insize
==
3258 sizeof (struct in_addr
)) {
3259 (*ppList
)->keys
[ctr
].address
.ipAddress
.ipv4Address
=
3261 } else if (stl_hdr
->stl_list
[ctr
].ste_ipaddr
.a_addr
.i_insize
==
3262 sizeof (struct in6_addr
)) {
3263 (*ppList
)->keys
[ctr
].address
.ipAddress
.ipv4Address
=
3267 syslog(LOG_USER
|LOG_DEBUG
,
3268 "ISCSI_STATIC_GET returned bad address");
3269 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3273 (void) memcpy(&(*ppList
)->keys
[ctr
].address
.ipAddress
.ipAddress
,
3274 &(stl_hdr
->stl_list
[ctr
].ste_ipaddr
.a_addr
.i_addr
),
3275 stl_hdr
->stl_list
[ctr
].ste_ipaddr
.a_addr
.i_insize
);
3279 return (IMA_STATUS_SUCCESS
);
3282 IMA_API IMA_STATUS
SUN_IMA_GetTunableProperties(
3284 ISCSI_TUNABLE_PARAM
*param
)
3287 iscsi_tunable_object_t pg
;
3289 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
3290 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
3291 ISCSI_DRIVER_DEVCTL
, errno
);
3292 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3294 (void) memset(&pg
, 0, sizeof (iscsi_tunable_object_t
));
3295 pg
.t_param
= param
->tunable_objectType
;
3296 pg
.t_oid
= (uint32_t)oid
.objectSequenceNumber
;
3297 if (ioctl(fd
, ISCSI_TUNABLE_PARAM_GET
, &pg
) == -1) {
3298 syslog(LOG_USER
|LOG_DEBUG
,
3299 "ISCSI_TUNABLE_PARAM_GET ioctl failed, errno: %d", errno
);
3301 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3304 char tmp
[MAX_LONG_LONG_STRING_LEN
], *ptr
= NULL
;
3305 if (pg
.t_set
== B_FALSE
) {
3308 return (IMA_STATUS_SUCCESS
);
3310 value
= (long long)pg
.t_value
.v_integer
;
3311 ptr
= lltostr(value
, &tmp
[MAX_LONG_LONG_STRING_LEN
-1]);
3312 if ((ptr
!= NULL
) && (ptr
!= tmp
)) {
3313 tmp
[MAX_LONG_LONG_STRING_LEN
- 1] = '\0';
3316 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3318 switch (param
->tunable_objectType
) {
3319 case ISCSI_RX_TIMEOUT_VALUE
:
3320 (void) strlcpy(param
->tunable_objectValue
,
3321 ptr
, strlen(ptr
) + 1);
3323 case ISCSI_CONN_DEFAULT_LOGIN_MAX
:
3324 (void) strlcpy(param
->tunable_objectValue
,
3325 ptr
, strlen(ptr
) + 1);
3327 case ISCSI_LOGIN_POLLING_DELAY
:
3328 (void) strlcpy(param
->tunable_objectValue
,
3329 ptr
, strlen(ptr
) + 1);
3336 return (IMA_STATUS_SUCCESS
);
3339 IMA_API IMA_STATUS
SUN_IMA_SetTunableProperties(
3341 ISCSI_TUNABLE_PARAM
*param
)
3344 iscsi_tunable_object_t ps
;
3346 if ((fd
= open(ISCSI_DRIVER_DEVCTL
, O_RDONLY
)) == -1) {
3347 syslog(LOG_USER
|LOG_DEBUG
, "Cannot open %s (%d)",
3348 ISCSI_DRIVER_DEVCTL
, errno
);
3349 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3352 (void) memset(&ps
, 0, sizeof (iscsi_tunable_object_t
));
3353 ps
.t_oid
= oid
.objectSequenceNumber
;
3354 ps
.t_param
= param
->tunable_objectType
;
3355 switch (param
->tunable_objectType
) {
3357 case ISCSI_RX_TIMEOUT_VALUE
:
3358 case ISCSI_CONN_DEFAULT_LOGIN_MAX
:
3359 case ISCSI_LOGIN_POLLING_DELAY
:
3360 tmp
= strtol(param
->tunable_objectValue
,
3362 if (((tmp
== 0) && (errno
== EINVAL
)) ||
3363 ((tmp
== LONG_MAX
) && (errno
== ERANGE
)) ||
3364 ((tmp
== LONG_MIN
) && (errno
== ERANGE
))) {
3366 return (IMA_ERROR_INVALID_PARAMETER
);
3368 ps
.t_value
.v_integer
= (uint32_t)tmp
;
3373 if (ioctl(fd
, ISCSI_TUNABLE_PARAM_SET
, &ps
)) {
3374 int tmpErrno
= errno
;
3375 syslog(LOG_USER
|LOG_DEBUG
,
3376 "ISCSI_TUNABLE_PARAM_SET ioctl failed, errno: %d", errno
);
3380 return (IMA_ERROR_NOT_SUPPORTED
);
3382 return (IMA_ERROR_UNEXPECTED_OS_ERROR
);
3386 return (IMA_STATUS_SUCCESS
);