sd: remove 'ssd' driver support
[unleashed/tickless.git] / usr / src / lib / libsun_ima / common / ima.c
blob30f1bfafc37e15f35ef89d2670986ecd1f383d19
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
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>
29 #include <stdarg.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <unistd.h>
34 #include <syslog.h>
35 #include <errno.h>
36 #include <wchar.h>
37 #include <widec.h>
38 #include <libsysevent.h>
39 #include <sys/nvpair.h>
40 #include <fcntl.h>
41 #include <stdio.h>
42 #include <time.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>
48 #include <ima.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 */
70 #define BOOL_PARAM 1
71 #define MIN_MAX_PARAM 2
73 /* OK */
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
94 IMA_NODE_NAME name;
95 IMA_ADDRESS_KEY address;
96 IMA_UINT16 tpgt;
97 } SUN_IMA_DISC_ADDRESS_KEY;
100 * Custom struct to allow tgpt to be specified.
102 typedef struct _SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
104 IMA_UINT keyCount;
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,
131 entry_t *entry);
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);
153 void InitLibrary();
155 static void libSwprintf(wchar_t *wcs, const wchar_t *lpszFormat, ...)
157 va_list args;
158 va_start(args, lpszFormat);
159 (void) vswprintf(wcs, OS_DEVICE_NAME_LEN - 1, lpszFormat, args);
160 va_end(args);
163 static void
164 sysevent_handler(sysevent_t *ev)
166 IMA_OID tmpOid;
167 IMA_BOOL becomingVisible = IMA_FALSE;
168 IMA_UINT i;
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,
175 ESC_ISCSI_SLP_START,
176 ESC_ISCSI_SLP_END,
177 ESC_ISCSI_ISNS_START,
178 ESC_ISCSI_ISNS_END,
179 NULL
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) {
189 return;
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);
199 } else {
200 i = 0;
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,
208 tmpOid);
210 i++;
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,
221 ESC_ISCSI_SLP_START,
222 ESC_ISCSI_SLP_END,
223 ESC_ISCSI_ISNS_START,
224 ESC_ISCSI_ISNS_END,
225 ESC_ISCSI_PROP_CHANGE,
228 /* Bind event handler and create subscriber handle */
229 shp = sysevent_bind_handle(sysevent_handler);
230 if (shp == NULL) {
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());
246 void Terminate() {
247 if (shp != NULL) {
248 sysevent_unsubscribe_event(shp, EC_ISCSI);
253 void InitLibrary() {
256 static void GetBuildTime(IMA_DATETIME* pdatetime)
258 (void) memset(pdatetime, 0, sizeof (IMA_DATETIME));
261 /*ARGSUSED*/
262 IMA_API IMA_STATUS IMA_GetNodeProperties(
263 IMA_OID nodeOid,
264 IMA_NODE_PROPERTIES *pProps
267 int fd;
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;
286 } else {
287 if (strlen((char *)pg.g_value.v_name) > 0) {
288 (void) mbstowcs(pProps->name,
289 (char *)pg.g_value.v_name,
290 IMA_NODE_NAME_LEN);
291 pProps->nameValid = IMA_TRUE;
292 } else {
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;
304 } else {
305 if (strlen((char *)pg.g_value.v_name) > 0) {
306 (void) mbstowcs(pProps->alias,
307 (char *)pg.g_value.v_name,
308 IMA_NODE_ALIAS_LEN);
309 pProps->aliasValid = IMA_TRUE;
313 (void) close(fd);
314 return (IMA_STATUS_SUCCESS);
317 IMA_API IMA_STATUS IMA_SetNodeName(
318 IMA_OID nodeOid,
319 const IMA_NODE_NAME newName
322 int fd;
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);
339 (void) close(fd);
340 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
343 (void) close(fd);
344 return (IMA_STATUS_SUCCESS);
347 IMA_API IMA_STATUS IMA_SetNodeAlias(
348 IMA_OID nodeOid,
349 const IMA_NODE_ALIAS newAlias
352 int fd;
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,
369 ISCSI_MAX_NAME_LEN);
370 else
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);
377 (void) close(fd);
378 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
381 (void) close(fd);
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
410 /*ARGSUSED*/
411 IMA_API IMA_STATUS IMA_GetDiscoveryProperties(
412 IMA_OID oid,
413 IMA_DISCOVERY_PROPERTIES *pProps
416 int fd;
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);
431 (void) close(fd);
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;
446 break;
447 case iSNSDiscoveryMethodDHCP:
448 pProps->iSnsDiscoveryMethod =
449 IMA_ISNS_DISCOVERY_METHOD_DHCP;
450 break;
451 case iSNSDiscoveryMethodSLP:
452 pProps->iSnsDiscoveryMethod =
453 IMA_ISNS_DISCOVERY_METHOD_SLP;
454 break;
455 default:
456 (void) close(fd);
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;
473 (void) close(fd);
474 return (IMA_STATUS_SUCCESS);
477 IMA_API IMA_STATUS IMA_FreeMemory(
478 void *pMemory
481 free(pMemory);
482 return (IMA_STATUS_SUCCESS);
485 IMA_API IMA_STATUS IMA_GetNonSharedNodeOidList(
486 IMA_OID_LIST **ppList
489 if (ppList == NULL)
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(
502 IMA_OID Oid,
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(
511 IMA_OID Oid,
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(
520 IMA_OID Oid,
521 IMA_MIN_MAX_VALUE *pProps
524 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
525 ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH));
528 /*ARGSUSED*/
529 IMA_API IMA_STATUS IMA_PluginIOCtl(
530 IMA_OID pluginOid,
531 IMA_UINT command,
532 const void *pInputBuffer,
533 IMA_UINT inputBufferLength,
534 void *pOutputBuffer,
535 IMA_UINT *pOutputBufferLength
538 return (IMA_ERROR_NOT_SUPPORTED);
541 IMA_API IMA_STATUS IMA_SetFirstBurstLength(
542 IMA_OID lhbaId,
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(
554 IMA_OID lhbaId,
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(
566 IMA_OID lhbaId,
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(
578 IMA_OID Oid,
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(
587 IMA_OID lhbaId,
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(
599 IMA_OID lhbaId,
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(
608 IMA_OID lhbaId,
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(
620 IMA_OID lhbaId,
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(
629 IMA_OID lhbaId,
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(
641 IMA_OID Oid,
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(
650 IMA_OID lhbaId,
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(
663 IMA_OID Oid,
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(
672 IMA_OID Oid,
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(
684 IMA_OID Oid,
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(
693 IMA_OID Oid,
694 IMA_BOOL initialR2T
697 IMA_BOOL_VALUE bv;
699 bv.currentValue = initialR2T;
700 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv,
701 ISCSI_LOGIN_PARAM_INITIAL_R2T));
705 IMA_API IMA_STATUS IMA_GetImmediateDataProperties(
706 IMA_OID Oid,
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(
715 IMA_OID Oid,
716 IMA_BOOL immediateData
719 IMA_BOOL_VALUE bv;
721 bv.currentValue = immediateData;
722 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv,
723 ISCSI_LOGIN_PARAM_IMMEDIATE_DATA));
726 IMA_API IMA_STATUS IMA_GetDataPduInOrderProperties(
727 IMA_OID Oid,
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(
736 IMA_OID Oid,
737 IMA_BOOL dataPduInOrder
740 IMA_BOOL_VALUE bv;
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(
748 IMA_OID Oid,
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(
757 IMA_OID Oid,
758 IMA_BOOL dataSequenceInOrder
761 IMA_BOOL_VALUE bv;
763 bv.currentValue = dataSequenceInOrder;
764 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv,
765 ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER));
769 /*ARGSUSED*/
770 IMA_API IMA_STATUS IMA_SetStatisticsCollection(
771 IMA_OID Oid,
772 IMA_BOOL enableStatisticsCollection
775 return (IMA_ERROR_NOT_SUPPORTED);
779 /*ARGSUSED*/
780 IMA_API IMA_STATUS IMA_GetDiscoveryAddressOidList(
781 IMA_OID Oid,
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);
805 (void) close(fd);
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);
816 if (idlp == NULL) {
817 (void) close(fd);
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);
828 free(idlp);
829 (void) close(fd);
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) {
836 free(idlp);
837 (void) close(fd);
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;
850 free(idlp);
851 (void) close(fd);
853 return (IMA_STATUS_SUCCESS);
857 /* ARGSUSED */
858 IMA_API IMA_STATUS IMA_GetStaticDiscoveryTargetOidList(
859 IMA_OID Oid,
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));
870 /* ARGSUSED */
871 IMA_API IMA_STATUS IMA_GetTargetOidList(
872 IMA_OID Oid,
873 IMA_OID_LIST **ppList
876 return (get_target_oid_list(ISCSI_TGT_PARAM_OID_LIST, ppList));
879 /*ARGSUSED*/
880 IMA_API IMA_STATUS IMA_SetIsnsDiscovery(
881 IMA_OID phbaId,
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));
893 /* ARGSUSED */
894 IMA_API IMA_STATUS IMA_SetSlpDiscovery(
895 IMA_OID phbaId,
896 IMA_BOOL enableSlpDiscovery
899 return (configure_discovery_method(enableSlpDiscovery,
900 iSCSIDiscoveryMethodSLP));
904 /* ARGSUSED */
905 IMA_API IMA_STATUS IMA_SetStaticDiscovery(
906 IMA_OID phbaId,
907 IMA_BOOL enableStaticDiscovery
910 return (configure_discovery_method(enableStaticDiscovery,
911 iSCSIDiscoveryMethodStatic));
914 /* ARGSUSED */
915 IMA_API IMA_STATUS IMA_SetSendTargetsDiscovery(
916 IMA_OID phbaId,
917 IMA_BOOL enableSendTargetsDiscovery
920 return (configure_discovery_method(enableSendTargetsDiscovery,
921 iSCSIDiscoveryMethodSendTargets));
924 /*ARGSUSED*/
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;
932 entry_t entry;
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);
951 (void) close(fd);
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);
966 if (idlp == NULL) {
967 (void) close(fd);
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);
979 free(idlp);
980 (void) close(fd);
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)
987 continue;
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);
1007 } else {
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;
1015 entry.e_tpgt = 0;
1016 entry.e_oid = discoveryAddressOid.objectSequenceNumber;
1018 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_CLEAR, &entry)) {
1019 status = errno;
1020 (void) close(fd);
1021 syslog(LOG_USER|LOG_DEBUG,
1022 "ISCSI_DISCOVERY_ADDR_CLEAR ioctl failed, errno: %d",
1023 errno);
1024 if (status == EBUSY) {
1025 return (IMA_ERROR_LU_IN_USE);
1026 } else {
1027 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1031 free(idlp);
1032 (void) close(fd);
1033 return (IMA_STATUS_SUCCESS);
1037 /*ARGSUSED*/
1038 IMA_API IMA_STATUS IMA_AddDiscoveryAddress(
1039 IMA_OID oid,
1040 const IMA_TARGET_ADDRESS discoveryAddress,
1041 IMA_OID *pDiscoveryAddressOid
1044 entry_t entry;
1045 int fd;
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) !=
1054 DISC_ADDR_OK) {
1055 (void) close(fd);
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",
1062 errno);
1063 (void) close(fd);
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;
1071 (void) close(fd);
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];
1082 int af, fd, status;
1083 iscsi_static_property_t prop;
1084 /* LINTED */
1085 IMA_HOST_ID *host;
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) {
1097 status = errno;
1098 (void) close(fd);
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);
1104 } else {
1105 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1108 (void) close(fd);
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)) {
1115 /* IPv4 */
1116 af = AF_INET;
1117 } else if (prop.p_addr_list.al_addrs[0].a_addr.i_insize ==
1118 sizeof (struct in6_addr)) {
1119 /* IPv6 */
1120 af = AF_INET6;
1121 } else {
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 "
1133 "be inet_ntop");
1134 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1135 } else {
1136 if (af == AF_INET) {
1137 (void) snprintf(static_target_addr_port_str,
1138 SUN_IMA_IP_ADDRESS_LEN,
1139 "%s:%ld",
1140 static_target_addr_str,
1141 prop.p_addr_list.al_addrs[0].a_port);
1142 } else {
1143 (void) snprintf(static_target_addr_port_str,
1144 SUN_IMA_IP_ADDRESS_LEN,
1145 "[%s]:%ld",
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);
1159 /*ARGSUSED*/
1160 IMA_API IMA_STATUS IMA_GetDiscoveryAddressProperties(
1161 IMA_OID discoveryAddressOid,
1162 IMA_DISCOVERY_ADDRESS_PROPERTIES *pProps
1165 int fd;
1166 int i;
1167 int addr_list_size;
1168 iscsi_addr_list_t *idlp, al_info;
1169 iscsi_addr_t *matched_addr = NULL;
1170 /* LINTED */
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) {
1187 (void) close(fd);
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);
1205 if (idlp == NULL) {
1206 (void) close(fd);
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) {
1215 free(idlp);
1216 (void) close(fd);
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)
1226 continue;
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;
1240 } else {
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;
1258 free(idlp);
1259 (void) close(fd);
1261 return (IMA_STATUS_SUCCESS);
1264 IMA_API IMA_STATUS IMA_RemoveStaticDiscoveryTarget(
1265 IMA_OID staticTargetOid
1268 entry_t entry;
1269 int status, fd;
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)) {
1282 status = errno;
1283 (void) close(fd);
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);
1288 } else {
1289 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1293 (void) close(fd);
1294 return (IMA_STATUS_SUCCESS);
1297 /*ARGSUSED*/
1298 IMA_API IMA_STATUS IMA_AddStaticDiscoveryTarget(
1299 IMA_OID lhbaOid,
1300 const IMA_STATIC_DISCOVERY_TARGET staticConfig,
1301 IMA_OID *pTargetOid
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;
1308 int fd;
1309 int target_in_addr_size;
1310 int target_port;
1311 union {
1312 struct in_addr u_in4;
1313 struct in6_addr u_in6;
1314 } target_in;
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] == '[') {
1326 /* IPv6 address */
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 */
1344 closeBracketPos++;
1345 if (*closeBracketPos == ':') {
1346 closeBracketPos++;
1348 if (*closeBracketPos != '\0') {
1349 (void) strlcpy(target_port_str, closeBracketPos,
1350 sizeof (target_port_str));
1351 target_port = atoi(target_port_str);
1352 } else {
1353 target_port = ISCSI_LISTEN_PORT;
1355 } else {
1356 /* No port number specified; use default port */
1357 target_port = ISCSI_LISTEN_PORT;
1359 } else {
1360 /* IPv4 address */
1361 char *colonPos;
1362 colonPos = strchr(tmp_target_str, ':');
1363 if (!colonPos) {
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));
1368 } else {
1369 *colonPos = '\0';
1370 (void) strlcpy(target_addr_str, tmp_target_str,
1371 sizeof (target_addr_str));
1372 /* Extract the port number */
1373 colonPos++;
1374 if (*colonPos != '\0') {
1375 (void) strlcpy(target_port_str, colonPos,
1376 sizeof (target_port_str));
1377 target_port = atoi(target_port_str);
1378 } else {
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));
1407 } else {
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.
1430 (void) close(fd);
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;
1440 (void) close(fd);
1441 return (IMA_STATUS_SUCCESS);
1444 IMA_API IMA_STATUS IMA_GetTargetProperties(
1445 IMA_OID targetId,
1446 IMA_TARGET_PROPERTIES *pProps
1449 return (getTargetProperties(targetId, pProps));
1452 static IMA_STATUS getTargetProperties(
1453 IMA_OID targetId,
1454 IMA_TARGET_PROPERTIES *pProps
1457 int fd;
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) {
1471 (void) close(fd);
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;
1508 (void) close(fd);
1509 return (IMA_STATUS_SUCCESS);
1512 /*ARGSUSED*/
1513 IMA_API IMA_STATUS IMA_GetTargetErrorStatistics(
1514 IMA_OID targetId,
1515 IMA_TARGET_ERROR_STATISTICS *pStats
1518 return (IMA_ERROR_NOT_SUPPORTED);
1521 IMA_API IMA_STATUS IMA_GetLuOidList(
1522 IMA_OID oid,
1523 IMA_OID_LIST **ppList
1526 IMA_STATUS status;
1527 int i;
1528 iscsi_lun_list_t *pLunList;
1530 if (oid.objectType == IMA_OBJECT_TYPE_LHBA) {
1531 status = get_target_lun_oid_list(NULL, &pLunList);
1532 } else {
1533 status = get_target_lun_oid_list(&oid, &pLunList);
1536 if (!IMA_SUCCESS(status)) {
1537 return (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;
1553 free(pLunList);
1554 return (IMA_STATUS_SUCCESS);
1557 IMA_API IMA_STATUS IMA_GetLuOid(
1558 IMA_OID targetId,
1559 IMA_UINT64 lun,
1560 IMA_OID *pluId
1563 IMA_STATUS status;
1564 int i;
1565 iscsi_lun_list_t *pLunList;
1567 status = get_target_lun_oid_list(&targetId, &pLunList);
1568 if (!IMA_SUCCESS(status)) {
1569 return (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;
1578 free(pLunList);
1579 return (IMA_STATUS_SUCCESS);
1583 free(pLunList);
1584 return (IMA_ERROR_OBJECT_NOT_FOUND);
1587 IMA_API IMA_STATUS IMA_GetLuProperties(
1588 IMA_OID luId,
1589 IMA_LU_PROPERTIES *pProps
1592 return (getLuProperties(luId, pProps));
1595 static IMA_STATUS getLuProperties(
1596 IMA_OID luId,
1597 IMA_LU_PROPERTIES *pProps
1600 IMA_STATUS status;
1601 iscsi_lun_list_t *pLunList;
1602 int j;
1603 IMA_BOOL lunMatch = IMA_FALSE;
1604 int fd;
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)) {
1617 return (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;
1628 break;
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;
1639 free(pLunList);
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);
1659 (void) close(fd);
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
1682 * of the raw disk
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,
1695 get_lun_devlink);
1696 if (pProps->osDeviceName[0] != L'\0') {
1697 /* OS device name synchronously made */
1698 pProps->osDeviceNameValid = IMA_TRUE;
1699 } else {
1700 pProps->osDeviceNameValid = IMA_FALSE;
1703 (void) di_devlink_fini(&hdl);
1704 } else {
1705 pProps->osDeviceNameValid = IMA_FALSE;
1708 } else {
1709 pProps->osDeviceNameValid = IMA_FALSE;
1712 pProps->osParallelIdsValid = IMA_FALSE;
1714 return (IMA_STATUS_SUCCESS);
1717 /*ARGSUSED*/
1718 IMA_API IMA_STATUS IMA_GetStatisticsProperties(
1719 IMA_OID oid,
1720 IMA_STATISTICS_PROPERTIES *pProps
1723 return (IMA_ERROR_NOT_SUPPORTED);
1726 /*ARGSUSED*/
1727 IMA_API IMA_STATUS IMA_GetDeviceStatistics(
1728 IMA_OID luId,
1729 IMA_DEVICE_STATISTICS *pStats
1732 return (IMA_ERROR_NOT_SUPPORTED);
1735 IMA_API IMA_STATUS IMA_LuInquiry(
1736 IMA_OID deviceId,
1737 IMA_BOOL evpd,
1738 IMA_BOOL cmddt,
1739 IMA_BYTE pageCode,
1740 IMA_BYTE *pOutputBuffer,
1741 IMA_UINT *pOutputBufferLength,
1742 IMA_BYTE *pSenseBuffer,
1743 IMA_UINT *pSenseBufferLength
1746 IMA_LU_PROPERTIES luProps;
1747 IMA_STATUS status;
1748 unsigned char cmdblk[CDB_GROUP0];
1749 IMA_UINT buflen;
1750 int fd;
1751 iscsi_uscsi_t uscsi;
1753 (void) memset(&cmdblk[0], 0, CDB_GROUP0);
1754 cmdblk[0] = SCMD_INQUIRY;
1756 if (evpd == IMA_TRUE)
1757 cmdblk[1] |= 0x01;
1758 if (cmddt == IMA_TRUE)
1759 cmdblk[1] |= 0x02;
1761 cmdblk[2] = pageCode;
1763 if (*pOutputBufferLength > MAX_INQUIRY_BUFFER_LEN) {
1764 buflen = MAX_INQUIRY_BUFFER_LEN;
1765 } else {
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;
1777 uscsi.iu_lun = 0;
1778 } else {
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) {
1785 return (status);
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) {
1809 (void) close(fd);
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(
1827 IMA_OID deviceId,
1828 IMA_UINT cdbLength,
1829 IMA_BYTE *pOutputBuffer,
1830 IMA_UINT *pOutputBufferLength,
1832 IMA_BYTE *pSenseBuffer,
1833 IMA_UINT *pSenseBufferLength
1836 IMA_LU_PROPERTIES luProps;
1837 IMA_STATUS status;
1838 /* CDB_GROUP4 size is safe for both 10 and 16 byte CDBs */
1839 unsigned char cmdblk[CDB_GROUP4];
1840 IMA_UINT buflen;
1841 int fd;
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;
1861 } else {
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);
1868 } else {
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;
1879 uscsi.iu_lun = 0;
1880 } else {
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) {
1887 return (status);
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) {
1911 (void) close(fd);
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(
1929 IMA_OID deviceId,
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;
1941 IMA_STATUS status;
1942 unsigned char cmdblk[CDB_GROUP5];
1943 IMA_UINT buflen;
1944 int fd;
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;
1953 } else {
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;
1971 uscsi.iu_lun = 0;
1972 } else {
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) {
1979 return (status);
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) {
2003 (void) close(fd);
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);
2020 /*ARGSUSED*/
2021 IMA_API IMA_STATUS IMA_ExposeLu(
2022 IMA_OID luId
2025 return (IMA_ERROR_NOT_SUPPORTED);
2028 /*ARGSUSED*/
2029 IMA_API IMA_STATUS IMA_UnexposeLu(
2030 IMA_OID luId
2033 return (IMA_ERROR_NOT_SUPPORTED);
2036 IMA_API IMA_STATUS IMA_GetAddressKeys(
2037 IMA_OID targetOid,
2038 IMA_ADDRESS_KEYS **ppKeys
2041 IMA_STATUS status;
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) {
2050 return (status);
2053 status = getDiscoveryAddressPropertiesList(&discAddressList);
2054 if (status != IMA_STATUS_SUCCESS) {
2055 return (status);
2058 /* Get the number of addresses to allocate */
2059 for (i = 0; i < discAddressList->discAddrCount; i++) {
2060 (void) sendTargets(discAddressList->props[i].discoveryAddress,
2061 &pList);
2062 for (j = 0; j < pList->keyCount; j++) {
2063 if (wcsncmp(pList->keys[j].name, targetProps.name,
2064 wslen(pList->keys[j].name)) == 0) {
2065 addressKeyCount++;
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;
2077 addressKeyIdx = 0;
2079 for (i = 0; i < discAddressList->discAddrCount; i++) {
2080 (void) sendTargets(discAddressList->props[i].discoveryAddress,
2081 &pList);
2082 for (j = 0; j < pList->keyCount; j++) {
2083 if (wcsncmp(pList->keys[j].name, targetProps.name,
2084 wslen(pList->keys[j].name)) != 0) {
2085 continue;
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) {
2102 IMA_STATUS status;
2103 IMA_AUTHMETHOD supportedList[MAX_AUTHMETHODS];
2104 IMA_UINT i, supportedCount;
2105 IMA_BOOL supported;
2106 status = getSupportedAuthMethods(oid, IMA_FALSE, &supportedCount,
2107 supportedList);
2108 if (status != IMA_STATUS_SUCCESS)
2109 return (IMA_FALSE);
2111 supported = IMA_FALSE;
2112 for (i = 0; i < supportedCount; i++) {
2113 if (method == supportedList[i]) {
2114 supported = IMA_TRUE;
2118 return (supported);
2121 IMA_BOOL isAuthMethodListValid(IMA_OID oid, const IMA_AUTHMETHOD *pMethodList,
2122 IMA_UINT methodCount) {
2123 IMA_UINT i, j;
2125 if (pMethodList == NULL) {
2126 return (IMA_FALSE);
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]) {
2132 return (IMA_FALSE);
2136 if (isAuthMethodValid(oid, pMethodList[i]) == IMA_FALSE) {
2137 return (IMA_FALSE);
2140 return (IMA_TRUE);
2143 IMA_API IMA_STATUS IMA_GetSupportedAuthMethods(
2144 IMA_OID lhbaOid,
2145 IMA_BOOL getSettableMethods,
2146 IMA_UINT *pMethodCount,
2147 IMA_AUTHMETHOD *pMethodList
2150 return (getSupportedAuthMethods(lhbaOid, getSettableMethods,
2151 pMethodCount, pMethodList));
2155 /*ARGSUSED*/
2156 static IMA_STATUS getSupportedAuthMethods(
2157 IMA_OID lhbaOid,
2158 IMA_BOOL getSettableMethods,
2159 IMA_UINT *pMethodCount,
2160 IMA_AUTHMETHOD *pMethodList
2163 if (pMethodList == NULL) {
2164 *pMethodCount = 0;
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(
2178 IMA_OID lhbaOid,
2179 IMA_UINT *pMethodCount,
2180 IMA_AUTHMETHOD *pMethodList
2183 return (getAuthMethods(lhbaOid, pMethodCount, pMethodList));
2186 /*ARGSUSED*/
2187 IMA_API IMA_STATUS IMA_GetInitiatorAuthParms(
2188 IMA_OID lhbaOid,
2189 IMA_AUTHMETHOD method,
2190 IMA_INITIATOR_AUTHPARMS *pParms
2193 int fd;
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);
2210 (void) close(fd);
2211 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2213 } else {
2214 return (IMA_ERROR_INVALID_PARAMETER);
2217 (void) memcpy(pParms->chapParms.name, chap_p.c_user,
2218 chap_p.c_user_len);
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(
2228 IMA_OID lhbaOid,
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(
2243 IMA_OID lhbaOid,
2244 IMA_AUTHMETHOD method,
2245 const IMA_INITIATOR_AUTHPARMS *pParms
2248 int fd;
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) {
2277 (void) close(fd);
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. */
2288 static IMA_STATUS
2289 getISCSINodeParameter(
2290 int paramType,
2291 IMA_OID *oid,
2292 void *pProps,
2293 uint32_t paramIndex
2296 int fd;
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);
2314 (void) close(fd);
2315 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2318 switch (paramType) {
2319 IMA_BOOL_VALUE *bp;
2320 IMA_MIN_MAX_VALUE *mp;
2322 case MIN_MAX_PARAM:
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;
2333 break;
2335 case BOOL_PARAM:
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;
2342 break;
2344 default:
2345 break;
2348 (void) close(fd);
2349 return (IMA_STATUS_SUCCESS);
2352 /* A helper function to set iSCSI node parameters. */
2353 static IMA_STATUS
2354 setISCSINodeParameter(
2355 int paramType,
2356 IMA_OID *oid,
2357 void *pProp,
2358 uint32_t paramIndex
2361 int fd;
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) {
2376 IMA_BOOL_VALUE *bp;
2377 IMA_MIN_MAX_VALUE *mp;
2379 case MIN_MAX_PARAM:
2380 mp = (IMA_MIN_MAX_VALUE *)pProp;
2381 ps.s_value.v_integer = mp->currentValue;
2382 break;
2383 case BOOL_PARAM:
2384 bp = (IMA_BOOL_VALUE *)pProp;
2385 ps.s_value.v_bool =
2386 (bp->currentValue == IMA_TRUE) ?
2387 B_TRUE : B_FALSE;
2388 break;
2390 default:
2391 break;
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);
2398 (void) close(fd);
2399 switch (tmpErrno) {
2400 case ENOTSUP :
2401 return (IMA_ERROR_NOT_SUPPORTED);
2402 default :
2403 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2407 (void) close(fd);
2408 return (IMA_STATUS_SUCCESS);
2411 static int
2412 prepare_discovery_entry(
2413 IMA_TARGET_ADDRESS discoveryAddress,
2414 entry_t *entry
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 ==
2422 IMA_FALSE) {
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);
2427 } else {
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;
2435 entry->e_tpgt = 0;
2436 return (DISC_ADDR_OK);
2439 static IMA_STATUS configure_discovery_method(
2440 IMA_BOOL enable,
2441 iSCSIDiscoveryMethod_t method
2444 int fd, status;
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)) {
2454 status = errno;
2455 (void) close(fd);
2456 syslog(LOG_USER|LOG_DEBUG,
2457 "ISCSI_DISCOVERY_CLEAR ioctl failed, errno: %d",
2458 status);
2459 if (status == EBUSY) {
2460 return (IMA_ERROR_LU_IN_USE);
2461 } else {
2462 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2466 (void) close(fd);
2467 return (IMA_STATUS_SUCCESS);
2468 } else {
2469 /* Set the discovery method */
2470 if (ioctl(fd, ISCSI_DISCOVERY_SET, &method)) {
2471 (void) close(fd);
2472 syslog(LOG_USER|LOG_DEBUG,
2473 "ISCSI_DISCOVERY_SET ioctl failed, errno: %d",
2474 errno);
2475 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2478 (void) close(fd);
2479 return (IMA_STATUS_SUCCESS);
2483 static IMA_STATUS get_target_oid_list(
2484 uint32_t targetListType,
2485 IMA_OID_LIST **ppList)
2487 int fd;
2488 int i;
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) {
2507 (void) close(fd);
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);
2521 if (idlp == NULL) {
2522 (void) close(fd);
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) {
2532 free(idlp);
2533 (void) close(fd);
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) {
2543 free(idlp);
2544 (void) close(fd);
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;
2554 else
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];
2561 free(idlp);
2562 (void) close(fd);
2563 return (IMA_STATUS_SUCCESS);
2566 static IMA_STATUS get_target_lun_oid_list(
2567 IMA_OID * targetOid,
2568 iscsi_lun_list_t **ppLunList)
2570 int fd;
2571 iscsi_lun_list_t *illp, ll_info;
2572 int lun_list_size;
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;
2585 } else {
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) {
2596 (void) close(fd);
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);
2609 if (illp == NULL) {
2610 (void) close(fd);
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) {
2620 free(illp);
2621 (void) close(fd);
2622 syslog(LOG_USER|LOG_DEBUG,
2623 "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", errno);
2624 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2627 *ppLunList = illp;
2629 (void) close(fd);
2630 return (IMA_STATUS_SUCCESS);
2634 /* A helper function to set authentication method. */
2635 static IMA_STATUS
2636 setAuthMethods(
2637 IMA_OID oid,
2638 IMA_UINT *pMethodCount,
2639 const IMA_AUTHMETHOD *pMethodList
2642 int fd;
2643 int i;
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) {
2656 /* EMPTY */
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;
2665 break;
2666 default:
2667 break;
2671 if (ioctl(fd, ISCSI_AUTH_SET, &auth) != 0) {
2672 syslog(LOG_USER|LOG_DEBUG,
2673 "ISCSI_AUTH_SET failed, errno: %d", errno);
2674 (void) close(fd);
2675 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2678 (void) close(fd);
2679 return (IMA_STATUS_SUCCESS);
2682 /* A helper function to get authentication method. */
2683 static IMA_STATUS
2684 getAuthMethods(
2685 IMA_OID oid,
2686 IMA_UINT *pMethodCount,
2687 IMA_AUTHMETHOD *pMethodList
2690 int fd, i;
2691 iscsi_auth_props_t auth;
2693 if (pMethodList == NULL) {
2694 *pMethodCount = 0;
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);
2711 (void) close(fd);
2712 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2715 i = 0;
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;
2721 *pMethodCount = i;
2723 (void) close(fd);
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);
2739 /* ARGSUSED */
2740 IMA_API IMA_STATUS IMA_GetPhbaProperties(
2741 IMA_OID phbaOid,
2742 IMA_PHBA_PROPERTIES *pProps
2745 return (IMA_ERROR_OBJECT_NOT_FOUND);
2748 /* ARGSUSED */
2749 IMA_API IMA_STATUS IMA_GetPhbaStatus(
2750 IMA_OID phbaOid,
2751 IMA_PHBA_STATUS *pStatus
2754 return (IMA_ERROR_OBJECT_NOT_FOUND);
2757 /* ARGSUSED */
2758 IMA_API IMA_STATUS IMA_GetPhbaDownloadProperties(
2759 IMA_OID phbaOid,
2760 IMA_PHBA_DOWNLOAD_PROPERTIES *pProps
2763 return (IMA_ERROR_OBJECT_NOT_FOUND);
2766 /* ARGSUSED */
2767 IMA_API IMA_STATUS IMA_IsPhbaDownloadFile(
2768 IMA_OID phbaOid,
2769 const IMA_WCHAR *pFileName,
2770 IMA_PHBA_DOWNLOAD_IMAGE_PROPERTIES *pProps
2773 return (IMA_ERROR_OBJECT_NOT_FOUND);
2776 /* ARGSUSED */
2777 IMA_API IMA_STATUS IMA_PhbaDownload(
2778 IMA_OID phbaOid,
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(
2787 IMA_OID pnpOid,
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
2794 * one element
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);
2812 /* ARGSUSED */
2813 IMA_API IMA_STATUS IMA_GetPnpProperties(
2814 IMA_OID pnpOid,
2815 IMA_PNP_PROPERTIES *pProps
2818 return (IMA_ERROR_OBJECT_NOT_FOUND);
2821 /* ARGSUSED */
2822 IMA_API IMA_STATUS IMA_GetPnpStatistics(
2823 IMA_OID pnpOid,
2824 IMA_PNP_STATISTICS *pStats
2827 return (IMA_ERROR_OBJECT_NOT_FOUND);
2830 /* ARGSUSED */
2831 IMA_API IMA_STATUS IMA_GetIpProperties(
2832 IMA_OID oid,
2833 IMA_IP_PROPERTIES *pProps
2836 return (IMA_ERROR_OBJECT_NOT_FOUND);
2839 /* ARGSUSED */
2840 IMA_API IMA_STATUS IMA_SetDefaultGateway(
2841 IMA_OID oid,
2842 IMA_IP_ADDRESS defaultGateway
2845 return (IMA_ERROR_OBJECT_NOT_FOUND);
2848 /* ARGSUSED */
2849 IMA_API IMA_STATUS IMA_SetDnsServerAddress(
2850 IMA_OID oid,
2851 const IMA_IP_ADDRESS *pPrimaryDnsServerAddress,
2852 const IMA_IP_ADDRESS *pAlternateDnsServerAddress
2855 return (IMA_ERROR_OBJECT_NOT_FOUND);
2858 /* ARGSUSED */
2859 IMA_API IMA_STATUS IMA_SetSubnetMask(
2860 IMA_OID oid,
2861 IMA_IP_ADDRESS subnetMask
2864 return (IMA_ERROR_OBJECT_NOT_FOUND);
2867 /* ARGSUSED */
2868 IMA_API IMA_STATUS IMA_SetIpConfigMethod(
2869 IMA_OID oid,
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);
2884 /* ARGSUSED */
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);
2900 /* ARGSUSED */
2901 IMA_API IMA_STATUS IMA_DeregisterForObjectVisibilityChanges(
2902 IMA_OBJECT_VISIBILITY_FN pClientFn
2905 return (IMA_STATUS_SUCCESS);
2908 /* ARGSUSED */
2909 IMA_API IMA_STATUS IMA_GetNetworkPortStatus(
2910 IMA_OID portOid,
2911 IMA_NETWORK_PORT_STATUS *pStaus
2914 return (IMA_ERROR_OBJECT_NOT_FOUND);
2917 /* ARGSUSED */
2918 IMA_API IMA_STATUS IMA_GetNetworkPortalOidList(
2919 IMA_OID pnpOid,
2920 IMA_OID_LIST **ppList
2923 return (IMA_ERROR_OBJECT_NOT_FOUND);
2926 /* ARGSUSED */
2927 IMA_API IMA_STATUS IMA_GetNetworkPortalProperties(
2928 IMA_OID networkPortalOid,
2929 IMA_NETWORK_PORTAL_PROPERTIES *pProps
2932 return (IMA_ERROR_OBJECT_NOT_FOUND);
2935 /* ARGSUSED */
2936 IMA_API IMA_STATUS IMA_SetNetworkPortalIpAddress(
2937 IMA_OID networkPortalOid,
2938 const IMA_IP_ADDRESS NewIpAddress
2941 return (IMA_ERROR_OBJECT_NOT_FOUND);
2944 /* ARGSUSED */
2945 IMA_API IMA_STATUS IMA_RemoveStaleData(
2946 IMA_OID lhbaOid
2949 return (IMA_ERROR_NOT_SUPPORTED);
2952 /* ARGSUSED */
2953 IMA_API IMA_STATUS IMA_GetIpsecProperties(
2954 IMA_OID oid,
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);
2965 /* ARGSUSED */
2966 IMA_API IMA_STATUS IMA_GetLhbaProperties(
2967 IMA_OID lhbaOid,
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);
3006 /* ARGSUSED */
3007 IMA_API IMA_STATUS IMA_GetLnpProperties(
3008 IMA_OID lnpOid,
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/"
3017 static int
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),
3025 MAXPATHLEN);
3026 return (DI_WALK_TERMINATE);
3029 return (DI_WALK_CONTINUE);
3032 /* ARGSUSED */
3033 IMA_API IMA_STATUS IMA_GetPluginProperties(
3034 IMA_OID pluginOid,
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
3052 int fd;
3053 int i;
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) {
3072 (void) close(fd);
3073 syslog(LOG_USER|LOG_DEBUG,
3074 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d",
3075 errno);
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);
3086 if (ialp == NULL) {
3087 (void) close(fd);
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) {
3098 free(ialp);
3099 (void) close(fd);
3100 syslog(LOG_USER|LOG_DEBUG,
3101 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d",
3102 errno);
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) {
3111 free(ialp);
3112 (void) close(fd);
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;
3126 } else {
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;
3142 free(ialp);
3143 (void) close(fd);
3144 return (IMA_STATUS_SUCCESS);
3148 /* ARGSUSED */
3149 IMA_STATUS sendTargets(
3150 IMA_TARGET_ADDRESS address,
3151 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES **ppList
3154 char *colonPos;
3155 char discAddrStr[SUN_IMA_IP_ADDRESS_LEN];
3156 int fd;
3157 int ctr;
3158 int stl_sz;
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) {
3175 /* IPv4 */
3176 stl_hdr->stl_entry.e_insize = sizeof (struct in_addr);
3177 } else {
3178 /* IPv6 */
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);
3194 retry_sendtgts:
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);
3201 (void) close(fd);
3202 free(stl_hdr);
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) {
3215 (void) close(fd);
3216 return (IMA_ERROR_INSUFFICIENT_MEMORY);
3218 stl_hdr->stl_in_cnt = stl_hdr->stl_out_cnt;
3219 retry = IMA_FALSE;
3220 goto retry_sendtgts;
3221 } else {
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;
3234 (void) close(fd);
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) {
3241 free(stl_hdr);
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,
3250 IMA_NODE_NAME_LEN);
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 =
3260 IMA_TRUE;
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 =
3264 IMA_FALSE;
3265 } else {
3266 free(stl_hdr);
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);
3277 free(stl_hdr);
3279 return (IMA_STATUS_SUCCESS);
3282 IMA_API IMA_STATUS SUN_IMA_GetTunableProperties(
3283 IMA_OID oid,
3284 ISCSI_TUNABLE_PARAM *param)
3286 int fd;
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);
3300 (void) close(fd);
3301 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3302 } else {
3303 long long value;
3304 char tmp[MAX_LONG_LONG_STRING_LEN], *ptr = NULL;
3305 if (pg.t_set == B_FALSE) {
3306 /* default value */
3307 (void) close(fd);
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';
3314 } else {
3315 (void) close(fd);
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);
3322 break;
3323 case ISCSI_CONN_DEFAULT_LOGIN_MAX:
3324 (void) strlcpy(param->tunable_objectValue,
3325 ptr, strlen(ptr) + 1);
3326 break;
3327 case ISCSI_LOGIN_POLLING_DELAY:
3328 (void) strlcpy(param->tunable_objectValue,
3329 ptr, strlen(ptr) + 1);
3330 break;
3331 default:
3332 break;
3335 (void) close(fd);
3336 return (IMA_STATUS_SUCCESS);
3339 IMA_API IMA_STATUS SUN_IMA_SetTunableProperties(
3340 IMA_OID oid,
3341 ISCSI_TUNABLE_PARAM *param)
3343 int fd;
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) {
3356 long tmp;
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,
3361 NULL, 10);
3362 if (((tmp == 0) && (errno == EINVAL)) ||
3363 ((tmp == LONG_MAX) && (errno == ERANGE)) ||
3364 ((tmp == LONG_MIN) && (errno == ERANGE))) {
3365 (void) close(fd);
3366 return (IMA_ERROR_INVALID_PARAMETER);
3368 ps.t_value.v_integer = (uint32_t)tmp;
3369 break;
3370 default:
3371 break;
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);
3377 (void) close(fd);
3378 switch (tmpErrno) {
3379 case ENOTSUP :
3380 return (IMA_ERROR_NOT_SUPPORTED);
3381 default:
3382 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3385 (void) close(fd);
3386 return (IMA_STATUS_SUCCESS);