1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <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>
50
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"
55
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
68
69 /* Forward declaration */
70 #define BOOL_PARAM 1
71 #define MIN_MAX_PARAM 2
72
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
79
80 /* Currently not defined in IMA_TARGET_DISCOVERY_METHOD enum */
81 #define IMA_TARGET_DISCOVERY_METHOD_UNKNOWN 0
82
83 static IMA_OID lhbaObjectId;
84 static IMA_UINT32 pluginOwnerId;
85 static sysevent_handle_t *shp;
86
87
88
89 /*
90 * Custom struct to allow tgpt to be specified.
91 */
92 typedef struct _SUN_IMA_DISC_ADDRESS_KEY
93 {
94 IMA_NODE_NAME name;
95 IMA_ADDRESS_KEY address;
96 IMA_UINT16 tpgt;
97 } SUN_IMA_DISC_ADDRESS_KEY;
98
99 /*
100 * Custom struct to allow tgpt to be specified.
101 */
102 typedef struct _SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
103 {
104 IMA_UINT keyCount;
105 SUN_IMA_DISC_ADDRESS_KEY keys[1];
106 } SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES;
107
108 /*
109 * Custom struct to allow tgpt to be specified.
110 */
111 typedef struct _SUN_IMA_DISC_ADDR_PROP_LIST
112 {
113 IMA_UINT discAddrCount;
114 IMA_DISCOVERY_ADDRESS_PROPERTIES props[1];
115 } SUN_IMA_DISC_ADDR_PROP_LIST;
116
117
118 static IMA_OBJECT_VISIBILITY_FN pObjectVisibilityCallback = NULL;
119 static IMA_OBJECT_PROPERTY_FN pObjectPropertyCallback = NULL;
120
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);
129
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
141 );
142 static IMA_STATUS sendTargets(IMA_TARGET_ADDRESS address,
143 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES **ppList
144 );
145
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);
152
153 void InitLibrary();
154
libSwprintf(wchar_t * wcs,const wchar_t * lpszFormat,...)155 static void libSwprintf(wchar_t *wcs, const wchar_t *lpszFormat, ...)
156 {
157 va_list args;
158 va_start(args, lpszFormat);
159 (void) vswprintf(wcs, OS_DEVICE_NAME_LEN - 1, lpszFormat, args);
160 va_end(args);
161 }
162
163 static void
sysevent_handler(sysevent_t * ev)164 sysevent_handler(sysevent_t *ev)
165 {
166 IMA_OID tmpOid;
167 IMA_BOOL becomingVisible = IMA_FALSE;
168 IMA_UINT i;
169
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
180 };
181
182 tmpOid.ownerId = pluginOwnerId;
183 tmpOid.objectType = IMA_OBJECT_TYPE_TARGET;
184 tmpOid.objectSequenceNumber = 0;
185
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;
190 }
191
192
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);
209 }
210 i++;
211 }
212 }
213 }
214
init_sysevents()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,
226 };
227
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);
232 }
233
234 if (sysevent_subscribe_event(shp, EC_ISCSI, subclass_list, 9) != 0) {
235 sysevent_unbind_handle(shp);
236 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
237 }
238 return (IMA_STATUS_SUCCESS);
239 }
240
Initialize(IMA_UINT32 pluginOid)241 IMA_STATUS Initialize(IMA_UINT32 pluginOid) {
242 pluginOwnerId = pluginOid;
243 return (init_sysevents());
244 }
245
Terminate()246 void Terminate() {
247 if (shp != NULL) {
248 sysevent_unsubscribe_event(shp, EC_ISCSI);
249 }
250
251 }
252
InitLibrary()253 void InitLibrary() {
254 }
255
GetBuildTime(IMA_DATETIME * pdatetime)256 static void GetBuildTime(IMA_DATETIME* pdatetime)
257 {
258 (void) memset(pdatetime, 0, sizeof (IMA_DATETIME));
259 }
260
261 /*ARGSUSED*/
IMA_GetNodeProperties(IMA_OID nodeOid,IMA_NODE_PROPERTIES * pProps)262 IMA_API IMA_STATUS IMA_GetNodeProperties(
263 IMA_OID nodeOid,
264 IMA_NODE_PROPERTIES *pProps
265 )
266 {
267 int fd;
268 iscsi_param_get_t pg;
269
270 pProps->runningInInitiatorMode = IMA_TRUE;
271 pProps->runningInTargetMode = IMA_FALSE;
272 pProps->nameAndAliasSettable = IMA_FALSE;
273
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);
278 }
279
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;
283
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;
294 }
295 }
296
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;
310 }
311 }
312
313 (void) close(fd);
314 return (IMA_STATUS_SUCCESS);
315 }
316
IMA_SetNodeName(IMA_OID nodeOid,const IMA_NODE_NAME newName)317 IMA_API IMA_STATUS IMA_SetNodeName(
318 IMA_OID nodeOid,
319 const IMA_NODE_NAME newName
320 )
321 {
322 int fd;
323 iscsi_param_set_t ps;
324
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);
329 }
330
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);
341 }
342
343 (void) close(fd);
344 return (IMA_STATUS_SUCCESS);
345 }
346
IMA_SetNodeAlias(IMA_OID nodeOid,const IMA_NODE_ALIAS newAlias)347 IMA_API IMA_STATUS IMA_SetNodeAlias(
348 IMA_OID nodeOid,
349 const IMA_NODE_ALIAS newAlias
350 )
351 {
352 int fd;
353 iscsi_param_set_t ps;
354
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);
359 }
360
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;
365
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);
373
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);
379 }
380
381 (void) close(fd);
382 return (IMA_STATUS_SUCCESS);
383 }
384
385
IMA_GetLhbaOidList(IMA_OID_LIST ** ppList)386 IMA_API IMA_STATUS IMA_GetLhbaOidList(
387 IMA_OID_LIST **ppList
388 )
389 {
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;
394
395 *ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST));
396 if (*ppList == NULL) {
397 return (IMA_ERROR_INSUFFICIENT_MEMORY);
398 }
399
400 (*ppList)->oidCount = 1;
401 (void) memcpy(&(*ppList)->oids[0],
402 &lhbaObjectId, sizeof (lhbaObjectId));
403 return (IMA_STATUS_SUCCESS);
404 }
405
406
407 /*
408 * Get the discovery properties of the LHBA
409 */
410 /*ARGSUSED*/
IMA_GetDiscoveryProperties(IMA_OID oid,IMA_DISCOVERY_PROPERTIES * pProps)411 IMA_API IMA_STATUS IMA_GetDiscoveryProperties(
412 IMA_OID oid,
413 IMA_DISCOVERY_PROPERTIES *pProps
414 )
415 {
416 int fd;
417 iSCSIDiscoveryProperties_t discoveryProps;
418
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);
423 }
424
425 (void) memset(&discoveryProps, 0, sizeof (discoveryProps));
426 discoveryProps.vers = ISCSI_INTERFACE_VERSION;
427
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);
433 }
434
435 pProps->iSnsDiscoverySettable = discoveryProps.iSNSDiscoverySettable;
436 pProps->iSnsDiscoveryEnabled = discoveryProps.iSNSDiscoveryEnabled;
437 /*
438 * Set the iSNS discovery method - The IMA specification indicates
439 * this field is valid only if iSNS discovery is enabled.
440 */
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);
458 }
459 }
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;
472
473 (void) close(fd);
474 return (IMA_STATUS_SUCCESS);
475 }
476
IMA_FreeMemory(void * pMemory)477 IMA_API IMA_STATUS IMA_FreeMemory(
478 void *pMemory
479 )
480 {
481 if (pMemory != NULL)
482 free(pMemory);
483 return (IMA_STATUS_SUCCESS);
484 }
485
IMA_GetNonSharedNodeOidList(IMA_OID_LIST ** ppList)486 IMA_API IMA_STATUS IMA_GetNonSharedNodeOidList(
487 IMA_OID_LIST **ppList
488 )
489 {
490 if (ppList == NULL)
491 return (IMA_ERROR_INVALID_PARAMETER);
492
493 *ppList = (IMA_OID_LIST*) calloc(1, sizeof (IMA_OID_LIST));
494 if (*ppList == NULL) {
495 return (IMA_ERROR_INSUFFICIENT_MEMORY);
496 }
497 (*ppList)->oidCount = 0;
498
499 return (IMA_STATUS_SUCCESS);
500 }
501
IMA_GetFirstBurstLengthProperties(IMA_OID Oid,IMA_MIN_MAX_VALUE * pProps)502 IMA_API IMA_STATUS IMA_GetFirstBurstLengthProperties(
503 IMA_OID Oid,
504 IMA_MIN_MAX_VALUE *pProps
505 )
506 {
507 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
508 ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH));
509 }
510
IMA_GetMaxBurstLengthProperties(IMA_OID Oid,IMA_MIN_MAX_VALUE * pProps)511 IMA_API IMA_STATUS IMA_GetMaxBurstLengthProperties(
512 IMA_OID Oid,
513 IMA_MIN_MAX_VALUE *pProps
514 )
515 {
516 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
517 ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH));
518 }
519
IMA_GetMaxRecvDataSegmentLengthProperties(IMA_OID Oid,IMA_MIN_MAX_VALUE * pProps)520 IMA_API IMA_STATUS IMA_GetMaxRecvDataSegmentLengthProperties(
521 IMA_OID Oid,
522 IMA_MIN_MAX_VALUE *pProps
523 )
524 {
525 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
526 ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH));
527 }
528
529 /*ARGSUSED*/
IMA_PluginIOCtl(IMA_OID pluginOid,IMA_UINT command,const void * pInputBuffer,IMA_UINT inputBufferLength,void * pOutputBuffer,IMA_UINT * pOutputBufferLength)530 IMA_API IMA_STATUS IMA_PluginIOCtl(
531 IMA_OID pluginOid,
532 IMA_UINT command,
533 const void *pInputBuffer,
534 IMA_UINT inputBufferLength,
535 void *pOutputBuffer,
536 IMA_UINT *pOutputBufferLength
537 )
538 {
539 return (IMA_ERROR_NOT_SUPPORTED);
540 }
541
IMA_SetFirstBurstLength(IMA_OID lhbaId,IMA_UINT firstBurstLength)542 IMA_API IMA_STATUS IMA_SetFirstBurstLength(
543 IMA_OID lhbaId,
544 IMA_UINT firstBurstLength
545 )
546 {
547 IMA_MIN_MAX_VALUE mv;
548
549 mv.currentValue = firstBurstLength;
550 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
551 ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH));
552 }
553
IMA_SetMaxBurstLength(IMA_OID lhbaId,IMA_UINT maxBurstLength)554 IMA_API IMA_STATUS IMA_SetMaxBurstLength(
555 IMA_OID lhbaId,
556 IMA_UINT maxBurstLength
557 )
558 {
559 IMA_MIN_MAX_VALUE mv;
560
561 mv.currentValue = maxBurstLength;
562 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
563 ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH));
564 }
565
IMA_SetMaxRecvDataSegmentLength(IMA_OID lhbaId,IMA_UINT maxRecvDataSegmentLength)566 IMA_API IMA_STATUS IMA_SetMaxRecvDataSegmentLength(
567 IMA_OID lhbaId,
568 IMA_UINT maxRecvDataSegmentLength
569 )
570 {
571 IMA_MIN_MAX_VALUE mv;
572
573 mv.currentValue = maxRecvDataSegmentLength;
574 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
575 ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH));
576 }
577
IMA_GetMaxConnectionsProperties(IMA_OID Oid,IMA_MIN_MAX_VALUE * pProps)578 IMA_API IMA_STATUS IMA_GetMaxConnectionsProperties(
579 IMA_OID Oid,
580 IMA_MIN_MAX_VALUE *pProps
581 )
582 {
583 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
584 ISCSI_LOGIN_PARAM_MAX_CONNECTIONS));
585 }
586
IMA_SetMaxConnections(IMA_OID lhbaId,IMA_UINT maxConnections)587 IMA_API IMA_STATUS IMA_SetMaxConnections(
588 IMA_OID lhbaId,
589 IMA_UINT maxConnections
590 )
591 {
592 IMA_MIN_MAX_VALUE mv;
593
594 mv.currentValue = maxConnections;
595 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
596 ISCSI_LOGIN_PARAM_MAX_CONNECTIONS));
597 }
598
IMA_GetDefaultTime2RetainProperties(IMA_OID lhbaId,IMA_MIN_MAX_VALUE * pProps)599 IMA_API IMA_STATUS IMA_GetDefaultTime2RetainProperties(
600 IMA_OID lhbaId,
601 IMA_MIN_MAX_VALUE *pProps
602 )
603 {
604 return (getISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, pProps,
605 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN));
606 }
607
IMA_SetDefaultTime2Retain(IMA_OID lhbaId,IMA_UINT defaultTime2Retain)608 IMA_API IMA_STATUS IMA_SetDefaultTime2Retain(
609 IMA_OID lhbaId,
610 IMA_UINT defaultTime2Retain
611 )
612 {
613 IMA_MIN_MAX_VALUE mv;
614
615 mv.currentValue = defaultTime2Retain;
616 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
617 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN));
618 }
619
IMA_GetDefaultTime2WaitProperties(IMA_OID lhbaId,IMA_MIN_MAX_VALUE * pProps)620 IMA_API IMA_STATUS IMA_GetDefaultTime2WaitProperties(
621 IMA_OID lhbaId,
622 IMA_MIN_MAX_VALUE *pProps
623 )
624 {
625 return (getISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, pProps,
626 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT));
627 }
628
IMA_SetDefaultTime2Wait(IMA_OID lhbaId,IMA_UINT defaultTime2Wait)629 IMA_API IMA_STATUS IMA_SetDefaultTime2Wait(
630 IMA_OID lhbaId,
631 IMA_UINT defaultTime2Wait
632 )
633 {
634 IMA_MIN_MAX_VALUE mv;
635
636 mv.currentValue = defaultTime2Wait;
637 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
638 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT));
639 }
640
IMA_GetMaxOutstandingR2TProperties(IMA_OID Oid,IMA_MIN_MAX_VALUE * pProps)641 IMA_API IMA_STATUS IMA_GetMaxOutstandingR2TProperties(
642 IMA_OID Oid,
643 IMA_MIN_MAX_VALUE *pProps
644 )
645 {
646 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
647 ISCSI_LOGIN_PARAM_OUTSTANDING_R2T));
648 }
649
IMA_SetMaxOutstandingR2T(IMA_OID lhbaId,IMA_UINT maxOutstandingR2T)650 IMA_API IMA_STATUS IMA_SetMaxOutstandingR2T(
651 IMA_OID lhbaId,
652 IMA_UINT maxOutstandingR2T
653 )
654 {
655 IMA_MIN_MAX_VALUE mv;
656
657 mv.currentValue = maxOutstandingR2T;
658 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
659 ISCSI_LOGIN_PARAM_OUTSTANDING_R2T));
660 }
661
662
IMA_GetErrorRecoveryLevelProperties(IMA_OID Oid,IMA_MIN_MAX_VALUE * pProps)663 IMA_API IMA_STATUS IMA_GetErrorRecoveryLevelProperties(
664 IMA_OID Oid,
665 IMA_MIN_MAX_VALUE *pProps
666 )
667 {
668 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
669 ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL));
670 }
671
IMA_SetErrorRecoveryLevel(IMA_OID Oid,IMA_UINT errorRecoveryLevel)672 IMA_API IMA_STATUS IMA_SetErrorRecoveryLevel(
673 IMA_OID Oid,
674 IMA_UINT errorRecoveryLevel
675 )
676 {
677 IMA_MIN_MAX_VALUE mv;
678
679 mv.currentValue = errorRecoveryLevel;
680 return (setISCSINodeParameter(MIN_MAX_PARAM, &Oid, &mv,
681 ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL));
682 }
683
IMA_GetInitialR2TProperties(IMA_OID Oid,IMA_BOOL_VALUE * pProps)684 IMA_API IMA_STATUS IMA_GetInitialR2TProperties(
685 IMA_OID Oid,
686 IMA_BOOL_VALUE *pProps
687 )
688 {
689 return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps,
690 ISCSI_LOGIN_PARAM_INITIAL_R2T));
691 }
692
IMA_SetInitialR2T(IMA_OID Oid,IMA_BOOL initialR2T)693 IMA_API IMA_STATUS IMA_SetInitialR2T(
694 IMA_OID Oid,
695 IMA_BOOL initialR2T
696 )
697 {
698 IMA_BOOL_VALUE bv;
699
700 bv.currentValue = initialR2T;
701 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv,
702 ISCSI_LOGIN_PARAM_INITIAL_R2T));
703 }
704
705
IMA_GetImmediateDataProperties(IMA_OID Oid,IMA_BOOL_VALUE * pProps)706 IMA_API IMA_STATUS IMA_GetImmediateDataProperties(
707 IMA_OID Oid,
708 IMA_BOOL_VALUE *pProps
709 )
710 {
711 return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps,
712 ISCSI_LOGIN_PARAM_IMMEDIATE_DATA));
713 }
714
IMA_SetImmediateData(IMA_OID Oid,IMA_BOOL immediateData)715 IMA_API IMA_STATUS IMA_SetImmediateData(
716 IMA_OID Oid,
717 IMA_BOOL immediateData
718 )
719 {
720 IMA_BOOL_VALUE bv;
721
722 bv.currentValue = immediateData;
723 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv,
724 ISCSI_LOGIN_PARAM_IMMEDIATE_DATA));
725 }
726
IMA_GetDataPduInOrderProperties(IMA_OID Oid,IMA_BOOL_VALUE * pProps)727 IMA_API IMA_STATUS IMA_GetDataPduInOrderProperties(
728 IMA_OID Oid,
729 IMA_BOOL_VALUE *pProps
730 )
731 {
732 return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps,
733 ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER));
734 }
735
IMA_SetDataPduInOrder(IMA_OID Oid,IMA_BOOL dataPduInOrder)736 IMA_API IMA_STATUS IMA_SetDataPduInOrder(
737 IMA_OID Oid,
738 IMA_BOOL dataPduInOrder
739 )
740 {
741 IMA_BOOL_VALUE bv;
742
743 bv.currentValue = dataPduInOrder;
744 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv,
745 ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER));
746 }
747
IMA_GetDataSequenceInOrderProperties(IMA_OID Oid,IMA_BOOL_VALUE * pProps)748 IMA_API IMA_STATUS IMA_GetDataSequenceInOrderProperties(
749 IMA_OID Oid,
750 IMA_BOOL_VALUE *pProps
751 )
752 {
753 return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps,
754 ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER));
755 }
756
IMA_SetDataSequenceInOrder(IMA_OID Oid,IMA_BOOL dataSequenceInOrder)757 IMA_API IMA_STATUS IMA_SetDataSequenceInOrder(
758 IMA_OID Oid,
759 IMA_BOOL dataSequenceInOrder
760 )
761 {
762 IMA_BOOL_VALUE bv;
763
764 bv.currentValue = dataSequenceInOrder;
765 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv,
766 ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER));
767 }
768
769
770 /*ARGSUSED*/
IMA_SetStatisticsCollection(IMA_OID Oid,IMA_BOOL enableStatisticsCollection)771 IMA_API IMA_STATUS IMA_SetStatisticsCollection(
772 IMA_OID Oid,
773 IMA_BOOL enableStatisticsCollection
774 )
775 {
776 return (IMA_ERROR_NOT_SUPPORTED);
777 }
778
779
780 /*ARGSUSED*/
IMA_GetDiscoveryAddressOidList(IMA_OID Oid,IMA_OID_LIST ** ppList)781 IMA_API IMA_STATUS IMA_GetDiscoveryAddressOidList(
782 IMA_OID Oid,
783 IMA_OID_LIST **ppList
784 )
785 {
786 int fd, i, addr_list_size;
787 iscsi_addr_list_t *idlp, al_info;
788
789 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
790 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
791 ISCSI_DRIVER_DEVCTL, errno);
792 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
793 }
794
795 (void) memset(&al_info, 0, sizeof (al_info));
796 al_info.al_vers = ISCSI_INTERFACE_VERSION;
797 al_info.al_in_cnt = 0;
798
799 /*
800 * Issue ioctl to obtain the number of targets.
801 */
802 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) {
803 syslog(LOG_USER|LOG_DEBUG,
804 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
805 ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
806 (void) close(fd);
807 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
808 }
809
810 addr_list_size = sizeof (iscsi_addr_list_t);
811 if (al_info.al_out_cnt > 1) {
812 addr_list_size += (sizeof (iscsi_addr_list_t) *
813 al_info.al_out_cnt - 1);
814 }
815
816 idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size);
817 if (idlp == NULL) {
818 (void) close(fd);
819 return (IMA_ERROR_INSUFFICIENT_MEMORY);
820 }
821
822 idlp->al_vers = ISCSI_INTERFACE_VERSION;
823 idlp->al_in_cnt = al_info.al_out_cnt;
824 /* Issue the same ioctl again to obtain the OIDs. */
825 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) {
826 syslog(LOG_USER|LOG_DEBUG,
827 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
828 ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
829 free(idlp);
830 (void) close(fd);
831 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
832 }
833
834 *ppList = (IMA_OID_LIST *)calloc(1, sizeof (IMA_OID_LIST) +
835 idlp->al_out_cnt * sizeof (IMA_OID));
836 if (*ppList == NULL) {
837 free(idlp);
838 (void) close(fd);
839 return (IMA_ERROR_INSUFFICIENT_MEMORY);
840 }
841 (*ppList)->oidCount = idlp->al_out_cnt;
842
843 for (i = 0; i < idlp->al_out_cnt; i++) {
844 (*ppList)->oids[i].objectType =
845 IMA_OBJECT_TYPE_DISCOVERY_ADDRESS;
846 (*ppList)->oids[i].ownerId = pluginOwnerId;
847 (*ppList)->oids[i].objectSequenceNumber =
848 idlp->al_addrs[i].a_oid;
849 }
850
851 free(idlp);
852 (void) close(fd);
853
854 return (IMA_STATUS_SUCCESS);
855 }
856
857
858 /* ARGSUSED */
IMA_GetStaticDiscoveryTargetOidList(IMA_OID Oid,IMA_OID_LIST ** ppList)859 IMA_API IMA_STATUS IMA_GetStaticDiscoveryTargetOidList(
860 IMA_OID Oid,
861 IMA_OID_LIST **ppList
862 )
863 {
864 if (Oid.objectType == IMA_OBJECT_TYPE_PNP) {
865 return (IMA_ERROR_OBJECT_NOT_FOUND);
866 }
867
868 return (get_target_oid_list(ISCSI_STATIC_TGT_OID_LIST, ppList));
869 }
870
871 /* ARGSUSED */
IMA_GetTargetOidList(IMA_OID Oid,IMA_OID_LIST ** ppList)872 IMA_API IMA_STATUS IMA_GetTargetOidList(
873 IMA_OID Oid,
874 IMA_OID_LIST **ppList
875 )
876 {
877 return (get_target_oid_list(ISCSI_TGT_PARAM_OID_LIST, ppList));
878 }
879
880 /*ARGSUSED*/
IMA_SetIsnsDiscovery(IMA_OID phbaId,IMA_BOOL enableIsnsDiscovery,IMA_ISNS_DISCOVERY_METHOD discoveryMethod,const IMA_HOST_ID * iSnsHost)881 IMA_API IMA_STATUS IMA_SetIsnsDiscovery(
882 IMA_OID phbaId,
883 IMA_BOOL enableIsnsDiscovery,
884 IMA_ISNS_DISCOVERY_METHOD discoveryMethod,
885 const IMA_HOST_ID *iSnsHost
886 )
887 {
888 /* XXX need to set discovery Method and domaineName */
889 return (configure_discovery_method(enableIsnsDiscovery,
890 iSCSIDiscoveryMethodISNS));
891 }
892
893
894 /* ARGSUSED */
IMA_SetSlpDiscovery(IMA_OID phbaId,IMA_BOOL enableSlpDiscovery)895 IMA_API IMA_STATUS IMA_SetSlpDiscovery(
896 IMA_OID phbaId,
897 IMA_BOOL enableSlpDiscovery
898 )
899 {
900 return (configure_discovery_method(enableSlpDiscovery,
901 iSCSIDiscoveryMethodSLP));
902 }
903
904
905 /* ARGSUSED */
IMA_SetStaticDiscovery(IMA_OID phbaId,IMA_BOOL enableStaticDiscovery)906 IMA_API IMA_STATUS IMA_SetStaticDiscovery(
907 IMA_OID phbaId,
908 IMA_BOOL enableStaticDiscovery
909 )
910 {
911 return (configure_discovery_method(enableStaticDiscovery,
912 iSCSIDiscoveryMethodStatic));
913 }
914
915 /* ARGSUSED */
IMA_SetSendTargetsDiscovery(IMA_OID phbaId,IMA_BOOL enableSendTargetsDiscovery)916 IMA_API IMA_STATUS IMA_SetSendTargetsDiscovery(
917 IMA_OID phbaId,
918 IMA_BOOL enableSendTargetsDiscovery
919 )
920 {
921 return (configure_discovery_method(enableSendTargetsDiscovery,
922 iSCSIDiscoveryMethodSendTargets));
923 }
924
925 /*ARGSUSED*/
IMA_RemoveDiscoveryAddress(IMA_OID discoveryAddressOid)926 IMA_API IMA_STATUS IMA_RemoveDiscoveryAddress(
927 IMA_OID discoveryAddressOid
928 )
929 {
930 int status, fd, i, addr_list_size;
931 iscsi_addr_list_t *idlp, al_info;
932 iscsi_addr_t *matched_addr = NULL;
933 entry_t entry;
934
935 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
936 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
937 ISCSI_DRIVER_DEVCTL, errno);
938 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
939 }
940
941 (void) memset(&al_info, 0, sizeof (al_info));
942 al_info.al_vers = ISCSI_INTERFACE_VERSION;
943 al_info.al_in_cnt = 0;
944
945 /*
946 * Issue ioctl to obtain the number of discovery address.
947 */
948 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) {
949 syslog(LOG_USER|LOG_DEBUG,
950 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
951 ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
952 (void) close(fd);
953 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
954 }
955
956 if (al_info.al_out_cnt == 0) {
957 return (IMA_ERROR_OBJECT_NOT_FOUND);
958 }
959
960 addr_list_size = sizeof (iscsi_addr_list_t);
961 if (al_info.al_out_cnt > 1) {
962 addr_list_size += (sizeof (iscsi_addr_list_t) *
963 al_info.al_out_cnt - 1);
964 }
965
966 idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size);
967 if (idlp == NULL) {
968 (void) close(fd);
969 return (IMA_ERROR_INSUFFICIENT_MEMORY);
970 }
971
972 idlp->al_vers = ISCSI_INTERFACE_VERSION;
973 idlp->al_in_cnt = al_info.al_out_cnt;
974
975 /* Issue the same ioctl again to obtain the OIDs. */
976 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) {
977 syslog(LOG_USER|LOG_DEBUG,
978 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
979 ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
980 free(idlp);
981 (void) close(fd);
982 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
983 }
984
985 for (i = 0; i < idlp->al_out_cnt; i++) {
986 if (discoveryAddressOid.objectSequenceNumber !=
987 idlp->al_addrs[i].a_oid)
988 continue;
989 matched_addr = &(idlp->al_addrs[i]);
990 }
991
992 if (matched_addr == NULL) {
993 return (IMA_ERROR_OBJECT_NOT_FOUND);
994 }
995
996
997 (void) memset(&entry, 0, sizeof (entry_t));
998 entry.e_vers = ISCSI_INTERFACE_VERSION;
999 entry.e_oid = discoveryAddressOid.objectSequenceNumber;
1000 if (matched_addr->a_addr.i_insize == sizeof (struct in_addr)) {
1001 bcopy(&matched_addr->a_addr.i_addr.in4,
1002 &entry.e_u.u_in4, sizeof (entry.e_u.u_in4));
1003 entry.e_insize = sizeof (struct in_addr);
1004 } else if (matched_addr->a_addr.i_insize == sizeof (struct in6_addr)) {
1005 bcopy(&matched_addr->a_addr.i_addr.in6,
1006 &entry.e_u.u_in6, sizeof (entry.e_u.u_in6));
1007 entry.e_insize = sizeof (struct in6_addr);
1008 } else {
1009 /* Should not happen */
1010 syslog(LOG_USER|LOG_DEBUG,
1011 "ISCSI_STATIC_GET returned bad address");
1012 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1013 }
1014
1015 entry.e_port = matched_addr->a_port;
1016 entry.e_tpgt = 0;
1017 entry.e_oid = discoveryAddressOid.objectSequenceNumber;
1018
1019 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_CLEAR, &entry)) {
1020 status = errno;
1021 (void) close(fd);
1022 syslog(LOG_USER|LOG_DEBUG,
1023 "ISCSI_DISCOVERY_ADDR_CLEAR ioctl failed, errno: %d",
1024 errno);
1025 if (status == EBUSY) {
1026 return (IMA_ERROR_LU_IN_USE);
1027 } else {
1028 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1029 }
1030 }
1031
1032 free(idlp);
1033 (void) close(fd);
1034 return (IMA_STATUS_SUCCESS);
1035 }
1036
1037
1038 /*ARGSUSED*/
IMA_AddDiscoveryAddress(IMA_OID oid,const IMA_TARGET_ADDRESS discoveryAddress,IMA_OID * pDiscoveryAddressOid)1039 IMA_API IMA_STATUS IMA_AddDiscoveryAddress(
1040 IMA_OID oid,
1041 const IMA_TARGET_ADDRESS discoveryAddress,
1042 IMA_OID *pDiscoveryAddressOid
1043 )
1044 {
1045 entry_t entry;
1046 int fd;
1047
1048 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
1049 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
1050 ISCSI_DRIVER_DEVCTL, errno);
1051 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1052 }
1053
1054 if (prepare_discovery_entry(discoveryAddress, &entry) !=
1055 DISC_ADDR_OK) {
1056 (void) close(fd);
1057 return (IMA_ERROR_INVALID_PARAMETER);
1058 }
1059
1060 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_SET, &entry)) {
1061 syslog(LOG_USER|LOG_DEBUG,
1062 "ISCSI_DISCOVERY_ADDR_SET ioctl failed, errno: %d",
1063 errno);
1064 (void) close(fd);
1065 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1066 }
1067
1068 pDiscoveryAddressOid->ownerId = pluginOwnerId;
1069 pDiscoveryAddressOid->objectType = IMA_OBJECT_TYPE_DISCOVERY_ADDRESS;
1070 pDiscoveryAddressOid->objectSequenceNumber = entry.e_oid;
1071
1072 (void) close(fd);
1073 return (IMA_STATUS_SUCCESS);
1074 }
1075
IMA_GetStaticDiscoveryTargetProperties(IMA_OID staticTargetOid,IMA_STATIC_DISCOVERY_TARGET_PROPERTIES * pProps)1076 IMA_API IMA_STATUS IMA_GetStaticDiscoveryTargetProperties(
1077 IMA_OID staticTargetOid,
1078 IMA_STATIC_DISCOVERY_TARGET_PROPERTIES *pProps
1079 )
1080 {
1081 char static_target_addr_str[SUN_IMA_IP_ADDRESS_LEN];
1082 char static_target_addr_port_str[SUN_IMA_IP_ADDRESS_LEN];
1083 int af, fd, status;
1084 iscsi_static_property_t prop;
1085 /* LINTED */
1086 IMA_HOST_ID *host;
1087
1088 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
1089 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
1090 ISCSI_DRIVER_DEVCTL, errno);
1091 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1092 }
1093
1094 (void) memset(&prop, 0, sizeof (iscsi_static_property_t));
1095 prop.p_vers = ISCSI_INTERFACE_VERSION;
1096 prop.p_oid = (uint32_t)staticTargetOid.objectSequenceNumber;
1097 if (ioctl(fd, ISCSI_STATIC_GET, &prop) != 0) {
1098 status = errno;
1099 (void) close(fd);
1100 syslog(LOG_USER|LOG_DEBUG,
1101 "ISCSI_STATIC_GET ioctl failed, errno: %d", status);
1102 if (status == ENOENT) {
1103 return (IMA_ERROR_OBJECT_NOT_FOUND);
1104
1105 } else {
1106 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1107 }
1108 }
1109 (void) close(fd);
1110
1111 (void) mbstowcs(pProps->staticTarget.targetName, (char *)prop.p_name,
1112 sizeof (pProps->staticTarget.targetName)/sizeof (IMA_WCHAR));
1113
1114 if (prop.p_addr_list.al_addrs[0].a_addr.i_insize ==
1115 sizeof (struct in_addr)) {
1116 /* IPv4 */
1117 af = AF_INET;
1118 } else if (prop.p_addr_list.al_addrs[0].a_addr.i_insize ==
1119 sizeof (struct in6_addr)) {
1120 /* IPv6 */
1121 af = AF_INET6;
1122 } else {
1123 /* Should not happen */
1124 syslog(LOG_USER|LOG_DEBUG,
1125 "ISCSI_STATIC_GET returned bad address");
1126 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1127 }
1128
1129 if (inet_ntop(af, &prop.p_addr_list.al_addrs[0].a_addr.i_addr,
1130 static_target_addr_str, sizeof (static_target_addr_str)) == NULL) {
1131 /* Should not happen */
1132 syslog(LOG_USER|LOG_DEBUG,
1133 "ISCSI_STATIC_GET returned address that cannot "
1134 "be inet_ntop");
1135 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1136 } else {
1137 if (af == AF_INET) {
1138 (void) snprintf(static_target_addr_port_str,
1139 SUN_IMA_IP_ADDRESS_LEN,
1140 "%s:%ld",
1141 static_target_addr_str,
1142 prop.p_addr_list.al_addrs[0].a_port);
1143 } else {
1144 (void) snprintf(static_target_addr_port_str,
1145 SUN_IMA_IP_ADDRESS_LEN,
1146 "[%s]:%ld",
1147 static_target_addr_str,
1148 prop.p_addr_list.al_addrs[0].a_port);
1149 }
1150 host = &pProps->staticTarget.targetAddress.hostnameIpAddress;
1151 (void) mbstowcs(pProps->staticTarget.
1152 targetAddress.hostnameIpAddress.
1153 id.hostname, static_target_addr_port_str,
1154 sizeof (host->id.hostname) / sizeof (IMA_WCHAR));
1155 }
1156
1157 return (IMA_STATUS_SUCCESS);
1158 }
1159
1160 /*ARGSUSED*/
IMA_GetDiscoveryAddressProperties(IMA_OID discoveryAddressOid,IMA_DISCOVERY_ADDRESS_PROPERTIES * pProps)1161 IMA_API IMA_STATUS IMA_GetDiscoveryAddressProperties(
1162 IMA_OID discoveryAddressOid,
1163 IMA_DISCOVERY_ADDRESS_PROPERTIES *pProps
1164 )
1165 {
1166 int fd;
1167 int i;
1168 int addr_list_size;
1169 iscsi_addr_list_t *idlp, al_info;
1170 iscsi_addr_t *matched_addr = NULL;
1171 /* LINTED */
1172 IMA_TARGET_ADDRESS *addr;
1173
1174 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
1175 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
1176 ISCSI_DRIVER_DEVCTL, errno);
1177 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1178 }
1179
1180 (void) memset(&al_info, 0, sizeof (al_info));
1181 al_info.al_vers = ISCSI_INTERFACE_VERSION;
1182 al_info.al_in_cnt = 0;
1183
1184 /*
1185 * Issue ioctl to obtain the number of discovery addresses.
1186 */
1187 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) {
1188 (void) close(fd);
1189 syslog(LOG_USER|LOG_DEBUG,
1190 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
1191 ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
1192 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1193 }
1194
1195 if (al_info.al_out_cnt == 0) {
1196 return (IMA_ERROR_OBJECT_NOT_FOUND);
1197 }
1198
1199 addr_list_size = sizeof (iscsi_addr_list_t);
1200 if (al_info.al_out_cnt > 1) {
1201 addr_list_size += (sizeof (iscsi_addr_list_t) *
1202 al_info.al_out_cnt - 1);
1203 }
1204
1205 idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size);
1206 if (idlp == NULL) {
1207 (void) close(fd);
1208 return (IMA_ERROR_INSUFFICIENT_MEMORY);
1209 }
1210
1211 idlp->al_vers = ISCSI_INTERFACE_VERSION;
1212 idlp->al_in_cnt = al_info.al_out_cnt;
1213
1214 /* Issue the same ioctl again to obtain the OIDs. */
1215 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) {
1216 free(idlp);
1217 (void) close(fd);
1218 syslog(LOG_USER|LOG_DEBUG,
1219 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
1220 ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
1221 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1222 }
1223
1224 for (i = 0; i < idlp->al_out_cnt; i++) {
1225 if (discoveryAddressOid.objectSequenceNumber !=
1226 idlp->al_addrs[i].a_oid)
1227 continue;
1228 matched_addr = &(idlp->al_addrs[i]);
1229 }
1230
1231 if (matched_addr == NULL) {
1232 return (IMA_ERROR_OBJECT_NOT_FOUND);
1233 }
1234
1235 if (matched_addr->a_addr.i_insize == sizeof (struct in_addr)) {
1236 pProps->discoveryAddress.hostnameIpAddress.id.
1237 ipAddress.ipv4Address = IMA_TRUE;
1238 } else if (matched_addr->a_addr.i_insize == sizeof (struct in6_addr)) {
1239 pProps->discoveryAddress.hostnameIpAddress.id.
1240 ipAddress.ipv4Address = IMA_FALSE;
1241 } else {
1242 /* Should not happen */
1243 syslog(LOG_USER|LOG_DEBUG,
1244 "ISCSI_STATIC_GET returned bad address");
1245 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1246 }
1247
1248 addr = &pProps->discoveryAddress;
1249 bcopy(&(matched_addr->a_addr.i_addr), pProps->discoveryAddress.
1250 hostnameIpAddress.id.ipAddress.ipAddress,
1251 sizeof (addr->hostnameIpAddress.id.ipAddress.ipAddress));
1252
1253 pProps->discoveryAddress.portNumber = matched_addr->a_port;
1254
1255 pProps->associatedLhbaOid.objectType = IMA_OBJECT_TYPE_LHBA;
1256 pProps->associatedLhbaOid.ownerId = pluginOwnerId;
1257 pProps->associatedLhbaOid.objectSequenceNumber = ISCSI_INITIATOR_OID;
1258
1259 free(idlp);
1260 (void) close(fd);
1261
1262 return (IMA_STATUS_SUCCESS);
1263 }
1264
IMA_RemoveStaticDiscoveryTarget(IMA_OID staticTargetOid)1265 IMA_API IMA_STATUS IMA_RemoveStaticDiscoveryTarget(
1266 IMA_OID staticTargetOid
1267 )
1268 {
1269 entry_t entry;
1270 int status, fd;
1271
1272 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
1273 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
1274 ISCSI_DRIVER_DEVCTL, errno);
1275 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1276 }
1277
1278 (void) memset(&entry, 0, sizeof (entry_t));
1279 entry.e_vers = ISCSI_INTERFACE_VERSION;
1280 entry.e_oid = (uint32_t)staticTargetOid.objectSequenceNumber;
1281
1282 if (ioctl(fd, ISCSI_STATIC_CLEAR, &entry)) {
1283 status = errno;
1284 (void) close(fd);
1285 syslog(LOG_USER|LOG_DEBUG,
1286 "ISCSI_STATIC_CLEAR ioctl failed, errno: %d", errno);
1287 if (status == EBUSY) {
1288 return (IMA_ERROR_LU_IN_USE);
1289 } else {
1290 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1291 }
1292 }
1293
1294 (void) close(fd);
1295 return (IMA_STATUS_SUCCESS);
1296 }
1297
1298 /*ARGSUSED*/
IMA_AddStaticDiscoveryTarget(IMA_OID lhbaOid,const IMA_STATIC_DISCOVERY_TARGET staticConfig,IMA_OID * pTargetOid)1299 IMA_API IMA_STATUS IMA_AddStaticDiscoveryTarget(
1300 IMA_OID lhbaOid,
1301 const IMA_STATIC_DISCOVERY_TARGET staticConfig,
1302 IMA_OID *pTargetOid
1303 )
1304 {
1305 char tmp_target_str[SUN_IMA_IP_ADDRESS_LEN];
1306 char target_addr_str[SUN_IMA_IP_ADDRESS_LEN];
1307 char target_port_str[SUN_IMA_IP_PORT_LEN];
1308 iscsi_target_entry_t target;
1309 int fd;
1310 int target_in_addr_size;
1311 int target_port;
1312 union {
1313 struct in_addr u_in4;
1314 struct in6_addr u_in6;
1315 } target_in;
1316
1317 /*
1318 * staticConfig.address may come in with port number at its trailer.
1319 * Parse it to separate the IP address and port number.
1320 * Also translate the hostname to IP address if needed.
1321 */
1322 (void) wcstombs(tmp_target_str,
1323 staticConfig.targetAddress.hostnameIpAddress.
1324 id.hostname, sizeof (tmp_target_str));
1325
1326 if (tmp_target_str[0] == '[') {
1327 /* IPv6 address */
1328 char *closeBracketPos;
1329 closeBracketPos = strchr(tmp_target_str, ']');
1330 if (!closeBracketPos) {
1331 return (IMA_ERROR_INVALID_PARAMETER);
1332 }
1333
1334 *closeBracketPos = NULL;
1335 (void) strlcpy(target_addr_str, &tmp_target_str[1],
1336 sizeof (target_addr_str));
1337
1338 if (inet_pton(AF_INET6, target_addr_str,
1339 &target_in.u_in6) != 1) {
1340 return (IMA_ERROR_INVALID_PARAMETER);
1341 }
1342 target_in_addr_size = sizeof (struct in6_addr);
1343
1344 /* Extract the port number */
1345 closeBracketPos++;
1346 if (*closeBracketPos == ':') {
1347 closeBracketPos++;
1348
1349 if (*closeBracketPos != NULL) {
1350 (void) strlcpy(target_port_str, closeBracketPos,
1351 sizeof (target_port_str));
1352 target_port = atoi(target_port_str);
1353 } else {
1354 target_port = ISCSI_LISTEN_PORT;
1355 }
1356 } else {
1357 /* No port number specified; use default port */
1358 target_port = ISCSI_LISTEN_PORT;
1359 }
1360 } else {
1361 /* IPv4 address */
1362 char *colonPos;
1363 colonPos = strchr(tmp_target_str, ':');
1364 if (!colonPos) {
1365 /* No port number specified; use default port */
1366 target_port = ISCSI_LISTEN_PORT;
1367 (void) strlcpy(target_addr_str, tmp_target_str,
1368 sizeof (target_addr_str));
1369 } else {
1370 *colonPos = NULL;
1371 (void) strlcpy(target_addr_str, tmp_target_str,
1372 sizeof (target_addr_str));
1373 /* Extract the port number */
1374 colonPos++;
1375 if (*colonPos != NULL) {
1376 (void) strlcpy(target_port_str, colonPos,
1377 sizeof (target_port_str));
1378 target_port = atoi(target_port_str);
1379 } else {
1380 target_port = ISCSI_LISTEN_PORT;
1381 }
1382 }
1383
1384 if (inet_pton(AF_INET, target_addr_str,
1385 &target_in.u_in4) != 1) {
1386 return (IMA_ERROR_INVALID_PARAMETER);
1387 }
1388
1389 target_in_addr_size = sizeof (struct in_addr);
1390 }
1391
1392
1393 (void) memset(&target, 0, sizeof (iscsi_target_entry_t));
1394 target.te_entry.e_vers = ISCSI_INTERFACE_VERSION;
1395 target.te_entry.e_oid = ISCSI_OID_NOTSET;
1396 target.te_entry.e_tpgt = ISCSI_DEFAULT_TPGT;
1397
1398 (void) wcstombs((char *)target.te_name, staticConfig.targetName,
1399 ISCSI_MAX_NAME_LEN);
1400
1401 target.te_entry.e_insize = target_in_addr_size;
1402 if (target.te_entry.e_insize == sizeof (struct in_addr)) {
1403 target.te_entry.e_u.u_in4.s_addr = target_in.u_in4.s_addr;
1404 } else if (target.te_entry.e_insize == sizeof (struct in6_addr)) {
1405 bcopy(target_in.u_in6.s6_addr,
1406 target.te_entry.e_u.u_in6.s6_addr,
1407 sizeof (struct in6_addr));
1408 } else {
1409 /* Should not happen */
1410 syslog(LOG_USER|LOG_DEBUG,
1411 "ISCSI_STATIC_GET returned bad address");
1412 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1413 }
1414
1415 target.te_entry.e_port = target_port;
1416
1417 /* No target portal group specified. Default to -1. */
1418 target.te_entry.e_tpgt = ISCSI_DEFAULT_TPGT;
1419
1420 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
1421 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
1422 ISCSI_DRIVER_DEVCTL, errno);
1423 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1424 }
1425
1426 if (ioctl(fd, ISCSI_STATIC_SET, &target)) {
1427 /*
1428 * Encountered problem setting the IP address and port for
1429 * the target just added.
1430 */
1431 (void) close(fd);
1432 syslog(LOG_USER|LOG_DEBUG,
1433 "ISCSI_STATIC_SET ioctl failed, errno: %d", errno);
1434 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1435 }
1436
1437 pTargetOid->objectType = IMA_OBJECT_TYPE_TARGET;
1438 pTargetOid->ownerId = pluginOwnerId;
1439 pTargetOid->objectSequenceNumber = target.te_entry.e_oid;
1440
1441 (void) close(fd);
1442 return (IMA_STATUS_SUCCESS);
1443 }
1444
IMA_GetTargetProperties(IMA_OID targetId,IMA_TARGET_PROPERTIES * pProps)1445 IMA_API IMA_STATUS IMA_GetTargetProperties(
1446 IMA_OID targetId,
1447 IMA_TARGET_PROPERTIES *pProps
1448 )
1449 {
1450 return (getTargetProperties(targetId, pProps));
1451 }
1452
getTargetProperties(IMA_OID targetId,IMA_TARGET_PROPERTIES * pProps)1453 static IMA_STATUS getTargetProperties(
1454 IMA_OID targetId,
1455 IMA_TARGET_PROPERTIES *pProps
1456 )
1457 {
1458 int fd;
1459 iscsi_property_t prop;
1460
1461 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
1462 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
1463 ISCSI_DRIVER_DEVCTL, errno);
1464 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1465 }
1466
1467 (void) memset(&prop, 0, sizeof (iscsi_property_t));
1468 prop.p_vers = ISCSI_INTERFACE_VERSION;
1469 prop.p_oid = (uint32_t)targetId.objectSequenceNumber;
1470
1471 if (ioctl(fd, ISCSI_TARGET_PROPS_GET, &prop) != 0) {
1472 (void) close(fd);
1473 syslog(LOG_USER|LOG_DEBUG,
1474 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno);
1475 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1476 }
1477
1478 (void) mbstowcs(pProps->name, (char *)prop.p_name, IMA_NODE_NAME_LEN);
1479 (void) memset(pProps->alias, 0,
1480 sizeof (IMA_WCHAR) * IMA_NODE_ALIAS_LEN);
1481 if (prop.p_alias_len > 0) {
1482 (void) mbstowcs(pProps->alias, (char *)prop.p_alias,
1483 IMA_NODE_ALIAS_LEN);
1484 }
1485
1486 /* Initialize the discovery method to unknown method. */
1487 pProps->discoveryMethodFlags = IMA_TARGET_DISCOVERY_METHOD_UNKNOWN;
1488 if (!((prop.p_discovery & iSCSIDiscoveryMethodStatic) ^
1489 iSCSIDiscoveryMethodStatic)) {
1490 pProps->discoveryMethodFlags |=
1491 IMA_TARGET_DISCOVERY_METHOD_STATIC;
1492 }
1493
1494 if (!((prop.p_discovery & iSCSIDiscoveryMethodSLP) ^
1495 iSCSIDiscoveryMethodSLP)) {
1496 pProps->discoveryMethodFlags |= IMA_TARGET_DISCOVERY_METHOD_SLP;
1497 }
1498
1499 if (!((prop.p_discovery & iSCSIDiscoveryMethodISNS) ^
1500 iSCSIDiscoveryMethodISNS)) {
1501 pProps->discoveryMethodFlags |= iSCSIDiscoveryMethodISNS;
1502 }
1503
1504 if (!((prop.p_discovery & iSCSIDiscoveryMethodSendTargets) ^
1505 iSCSIDiscoveryMethodSendTargets)) {
1506 pProps->discoveryMethodFlags |= iSCSIDiscoveryMethodSendTargets;
1507 }
1508
1509 (void) close(fd);
1510 return (IMA_STATUS_SUCCESS);
1511 }
1512
1513 /*ARGSUSED*/
IMA_GetTargetErrorStatistics(IMA_OID targetId,IMA_TARGET_ERROR_STATISTICS * pStats)1514 IMA_API IMA_STATUS IMA_GetTargetErrorStatistics(
1515 IMA_OID targetId,
1516 IMA_TARGET_ERROR_STATISTICS *pStats
1517 )
1518 {
1519 return (IMA_ERROR_NOT_SUPPORTED);
1520 }
1521
IMA_GetLuOidList(IMA_OID oid,IMA_OID_LIST ** ppList)1522 IMA_API IMA_STATUS IMA_GetLuOidList(
1523 IMA_OID oid,
1524 IMA_OID_LIST **ppList
1525 )
1526 {
1527 IMA_STATUS status;
1528 int i;
1529 iscsi_lun_list_t *pLunList;
1530
1531 if (oid.objectType == IMA_OBJECT_TYPE_LHBA) {
1532 status = get_target_lun_oid_list(NULL, &pLunList);
1533 } else {
1534 status = get_target_lun_oid_list(&oid, &pLunList);
1535 }
1536
1537 if (!IMA_SUCCESS(status)) {
1538 return (status);
1539 }
1540
1541 *ppList = (IMA_OID_LIST *) calloc(1, (sizeof (IMA_OID_LIST) +
1542 (pLunList->ll_out_cnt * sizeof (IMA_OID))));
1543 if (*ppList == NULL) {
1544 return (IMA_ERROR_INSUFFICIENT_MEMORY);
1545 }
1546 (*ppList)->oidCount = pLunList->ll_out_cnt;
1547 for (i = 0; i < pLunList->ll_out_cnt; i++) {
1548 (*ppList)->oids[i].objectType = IMA_OBJECT_TYPE_LU;
1549 (*ppList)->oids[i].ownerId = pluginOwnerId;
1550 (*ppList)->oids[i].objectSequenceNumber =
1551 pLunList->ll_luns[i].l_oid;
1552 }
1553
1554 free(pLunList);
1555 return (IMA_STATUS_SUCCESS);
1556 }
1557
IMA_GetLuOid(IMA_OID targetId,IMA_UINT64 lun,IMA_OID * pluId)1558 IMA_API IMA_STATUS IMA_GetLuOid(
1559 IMA_OID targetId,
1560 IMA_UINT64 lun,
1561 IMA_OID *pluId
1562 )
1563 {
1564 IMA_STATUS status;
1565 int i;
1566 iscsi_lun_list_t *pLunList;
1567
1568 status = get_target_lun_oid_list(&targetId, &pLunList);
1569 if (!IMA_SUCCESS(status)) {
1570 return (status);
1571 }
1572
1573 for (i = 0; i < pLunList->ll_out_cnt; i++) {
1574 if (pLunList->ll_luns[i].l_num == lun) {
1575 pluId->objectType = IMA_OBJECT_TYPE_LU;
1576 pluId->ownerId = pluginOwnerId;
1577 pluId->objectSequenceNumber =
1578 pLunList->ll_luns[i].l_oid;
1579 free(pLunList);
1580 return (IMA_STATUS_SUCCESS);
1581 }
1582 }
1583
1584 free(pLunList);
1585 return (IMA_ERROR_OBJECT_NOT_FOUND);
1586 }
1587
IMA_GetLuProperties(IMA_OID luId,IMA_LU_PROPERTIES * pProps)1588 IMA_API IMA_STATUS IMA_GetLuProperties(
1589 IMA_OID luId,
1590 IMA_LU_PROPERTIES *pProps
1591 )
1592 {
1593 return (getLuProperties(luId, pProps));
1594 }
1595
getLuProperties(IMA_OID luId,IMA_LU_PROPERTIES * pProps)1596 static IMA_STATUS getLuProperties(
1597 IMA_OID luId,
1598 IMA_LU_PROPERTIES *pProps
1599 )
1600 {
1601 IMA_STATUS status;
1602 iscsi_lun_list_t *pLunList;
1603 int j;
1604 IMA_BOOL lunMatch = IMA_FALSE;
1605 int fd;
1606 iscsi_lun_props_t lun;
1607 di_devlink_handle_t hdl;
1608
1609 if (luId.objectType != IMA_OBJECT_TYPE_LU) {
1610 return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
1611 }
1612
1613 /*
1614 * get list of lun oids for all targets
1615 */
1616 status = get_target_lun_oid_list(NULL, &pLunList);
1617 if (!IMA_SUCCESS(status)) {
1618 return (status);
1619 }
1620 for (j = 0; j < pLunList->ll_out_cnt; j++) {
1621 /*
1622 * for each lun, check if match is found
1623 */
1624 if (pLunList->ll_luns[j].l_oid == luId.objectSequenceNumber) {
1625 /*
1626 * match found, break out of lun loop
1627 */
1628 lunMatch = IMA_TRUE;
1629 break;
1630 }
1631 }
1632
1633 if (lunMatch == IMA_TRUE) {
1634 (void) memset(&lun, 0, sizeof (iscsi_lun_props_t));
1635 lun.lp_vers = ISCSI_INTERFACE_VERSION;
1636 lun.lp_tgt_oid = pLunList->ll_luns[j].l_tgt_oid;
1637 lun.lp_oid = pLunList->ll_luns[j].l_oid;
1638 }
1639
1640 free(pLunList);
1641
1642 if (lunMatch == IMA_FALSE) {
1643 return (IMA_ERROR_OBJECT_NOT_FOUND);
1644 }
1645
1646 /*
1647 * get lun properties
1648 */
1649 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
1650 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
1651 ISCSI_DRIVER_DEVCTL, errno);
1652 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1653 }
1654
1655 if (ioctl(fd, ISCSI_LUN_PROPS_GET, &lun)) {
1656 syslog(LOG_USER|LOG_DEBUG,
1657 "ISCSI_LUN_PROPS_GET ioctl failed, errno: %d", errno);
1658 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1659 }
1660 (void) close(fd);
1661
1662 /*
1663 * set property values
1664 */
1665 pProps->associatedTargetOid.objectType = IMA_OBJECT_TYPE_TARGET;
1666 pProps->associatedTargetOid.ownerId = pluginOwnerId;
1667 pProps->associatedTargetOid.objectSequenceNumber = lun.lp_tgt_oid;
1668 pProps->targetLun = (IMA_UINT64)lun.lp_num;
1669 pProps->exposedToOs = IMA_TRUE;
1670 (void) memset(&pProps->timeExposedToOs, 0,
1671 sizeof (pProps->timeExposedToOs));
1672
1673 if (lun.lp_status == LunValid) {
1674
1675 /* add minor device delimiter */
1676 (void) strcat(lun.lp_pathname, ":");
1677
1678 if ((strstr(lun.lp_pathname, "sd@") != NULL) ||
1679 (strstr(lun.lp_pathname, "ssd@") != NULL) ||
1680 (strstr(lun.lp_pathname, "disk@") != NULL)) {
1681 /*
1682 * modify returned pathname to obtain the 2nd slice
1683 * of the raw disk
1684 */
1685 (void) strcat(lun.lp_pathname, "c,raw");
1686 }
1687
1688 /*
1689 * Pathname returned by driver is the physical device path.
1690 * This name needs to be converted to the OS device name.
1691 */
1692 if (hdl = di_devlink_init(lun.lp_pathname, DI_MAKE_LINK)) {
1693 pProps->osDeviceName[0] = L'\0';
1694 (void) di_devlink_walk(hdl, NULL, lun.lp_pathname,
1695 DI_PRIMARY_LINK, (void *)pProps->osDeviceName,
1696 get_lun_devlink);
1697 if (pProps->osDeviceName[0] != L'\0') {
1698 /* OS device name synchronously made */
1699 pProps->osDeviceNameValid = IMA_TRUE;
1700 } else {
1701 pProps->osDeviceNameValid = IMA_FALSE;
1702 }
1703
1704 (void) di_devlink_fini(&hdl);
1705 } else {
1706 pProps->osDeviceNameValid = IMA_FALSE;
1707 }
1708
1709 } else {
1710 pProps->osDeviceNameValid = IMA_FALSE;
1711 }
1712
1713 pProps->osParallelIdsValid = IMA_FALSE;
1714
1715 return (IMA_STATUS_SUCCESS);
1716 }
1717
1718 /*ARGSUSED*/
IMA_GetStatisticsProperties(IMA_OID oid,IMA_STATISTICS_PROPERTIES * pProps)1719 IMA_API IMA_STATUS IMA_GetStatisticsProperties(
1720 IMA_OID oid,
1721 IMA_STATISTICS_PROPERTIES *pProps
1722 )
1723 {
1724 return (IMA_ERROR_NOT_SUPPORTED);
1725 }
1726
1727 /*ARGSUSED*/
IMA_GetDeviceStatistics(IMA_OID luId,IMA_DEVICE_STATISTICS * pStats)1728 IMA_API IMA_STATUS IMA_GetDeviceStatistics(
1729 IMA_OID luId,
1730 IMA_DEVICE_STATISTICS *pStats
1731 )
1732 {
1733 return (IMA_ERROR_NOT_SUPPORTED);
1734 }
1735
IMA_LuInquiry(IMA_OID deviceId,IMA_BOOL evpd,IMA_BOOL cmddt,IMA_BYTE pageCode,IMA_BYTE * pOutputBuffer,IMA_UINT * pOutputBufferLength,IMA_BYTE * pSenseBuffer,IMA_UINT * pSenseBufferLength)1736 IMA_API IMA_STATUS IMA_LuInquiry(
1737 IMA_OID deviceId,
1738 IMA_BOOL evpd,
1739 IMA_BOOL cmddt,
1740 IMA_BYTE pageCode,
1741 IMA_BYTE *pOutputBuffer,
1742 IMA_UINT *pOutputBufferLength,
1743 IMA_BYTE *pSenseBuffer,
1744 IMA_UINT *pSenseBufferLength
1745 )
1746 {
1747 IMA_LU_PROPERTIES luProps;
1748 IMA_STATUS status;
1749 unsigned char cmdblk[CDB_GROUP0];
1750 IMA_UINT buflen;
1751 int fd;
1752 iscsi_uscsi_t uscsi;
1753
1754 (void) memset(&cmdblk[0], 0, CDB_GROUP0);
1755 cmdblk[0] = SCMD_INQUIRY;
1756
1757 if (evpd == IMA_TRUE)
1758 cmdblk[1] |= 0x01;
1759 if (cmddt == IMA_TRUE)
1760 cmdblk[1] |= 0x02;
1761
1762 cmdblk[2] = pageCode;
1763
1764 if (*pOutputBufferLength > MAX_INQUIRY_BUFFER_LEN) {
1765 buflen = MAX_INQUIRY_BUFFER_LEN;
1766 } else {
1767 buflen = *pOutputBufferLength;
1768 }
1769 cmdblk[3] = (buflen & 0xff00) >> 8;
1770 cmdblk[4] = (buflen & 0x00ff);
1771
1772 (void) memset(&uscsi, 0, sizeof (iscsi_uscsi_t));
1773 uscsi.iu_vers = ISCSI_INTERFACE_VERSION;
1774
1775 /* iu_oid is a session oid in the driver */
1776 if (deviceId.objectType == IMA_OBJECT_TYPE_TARGET) {
1777 uscsi.iu_oid = deviceId.objectSequenceNumber;
1778 uscsi.iu_lun = 0;
1779 } else {
1780 /*
1781 * Get LU properties and associated session oid
1782 * for this lun(deviceId) and put in uscsi.iu_oid
1783 */
1784 status = getLuProperties(deviceId, &luProps);
1785 if (status != IMA_STATUS_SUCCESS) {
1786 return (status);
1787 }
1788 uscsi.iu_oid = (uint32_t)luProps.associatedTargetOid.
1789 objectSequenceNumber;
1790 uscsi.iu_lun = luProps.targetLun;
1791 }
1792
1793 uscsi.iu_ucmd.uscsi_flags = USCSI_READ;
1794 uscsi.iu_ucmd.uscsi_timeout = USCSI_TIMEOUT_IN_SEC;
1795 uscsi.iu_ucmd.uscsi_bufaddr = (char *)pOutputBuffer;
1796 uscsi.iu_ucmd.uscsi_buflen = buflen;
1797 uscsi.iu_ucmd.uscsi_rqbuf = (char *)pSenseBuffer;
1798 uscsi.iu_ucmd.uscsi_rqlen = (pSenseBufferLength != NULL) ?
1799 *pSenseBufferLength : 0;
1800 uscsi.iu_ucmd.uscsi_cdb = (char *)&cmdblk[0];
1801 uscsi.iu_ucmd.uscsi_cdblen = CDB_GROUP0;
1802
1803 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
1804 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
1805 ISCSI_DRIVER_DEVCTL, errno);
1806 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1807 }
1808
1809 if (ioctl(fd, ISCSI_USCSI, &uscsi) != 0) {
1810 (void) close(fd);
1811 syslog(LOG_USER|LOG_DEBUG,
1812 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno);
1813 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1814 }
1815
1816 if (uscsi.iu_ucmd.uscsi_status == STATUS_CHECK) {
1817 if (pSenseBufferLength != NULL) {
1818 *pSenseBufferLength -= uscsi.iu_ucmd.uscsi_rqresid;
1819 }
1820 return (IMA_ERROR_SCSI_STATUS_CHECK_CONDITION);
1821 }
1822
1823 *pOutputBufferLength = buflen - uscsi.iu_ucmd.uscsi_resid;
1824 return (IMA_STATUS_SUCCESS);
1825 }
1826
IMA_LuReadCapacity(IMA_OID deviceId,IMA_UINT cdbLength,IMA_BYTE * pOutputBuffer,IMA_UINT * pOutputBufferLength,IMA_BYTE * pSenseBuffer,IMA_UINT * pSenseBufferLength)1827 IMA_API IMA_STATUS IMA_LuReadCapacity(
1828 IMA_OID deviceId,
1829 IMA_UINT cdbLength,
1830 IMA_BYTE *pOutputBuffer,
1831 IMA_UINT *pOutputBufferLength,
1832
1833 IMA_BYTE *pSenseBuffer,
1834 IMA_UINT *pSenseBufferLength
1835 )
1836 {
1837 IMA_LU_PROPERTIES luProps;
1838 IMA_STATUS status;
1839 /* CDB_GROUP4 size is safe for both 10 and 16 byte CDBs */
1840 unsigned char cmdblk[CDB_GROUP4];
1841 IMA_UINT buflen;
1842 int fd;
1843 iscsi_uscsi_t uscsi;
1844
1845 (void) memset(&cmdblk[0], 0, CDB_GROUP4);
1846
1847 if (cdbLength == CDB_GROUP1) {
1848 /* Read Capacity (10) command. */
1849 cmdblk[0] = SCMD_READ_CAPACITY;
1850 buflen = *pOutputBufferLength;
1851 } else if (cdbLength == CDB_GROUP4) {
1852 /*
1853 * Read Capacity (16) is a Service Action In command. One
1854 * command byte (0x9E) is overloaded for multiple operations,
1855 * with the second CDB byte specifying the desired operation.
1856 */
1857 cmdblk[0] = SCMD_SVC_ACTION_IN_G4;
1858 cmdblk[1] = SSVC_ACTION_READ_CAPACITY_G4;
1859
1860 if (*pOutputBufferLength > MAX_READ_CAPACITY16_BUFFER_LEN) {
1861 buflen = MAX_READ_CAPACITY16_BUFFER_LEN;
1862 } else {
1863 buflen = *pOutputBufferLength;
1864 }
1865 cmdblk[10] = (buflen & 0xff000000) >> 24;
1866 cmdblk[11] = (buflen & 0x00ff0000) >> 16;
1867 cmdblk[12] = (buflen & 0x0000ff00) >> 8;
1868 cmdblk[13] = (buflen & 0x000000ff);
1869 } else {
1870 /* only 10 and 16 byte CDB are supported */
1871 return (IMA_ERROR_NOT_SUPPORTED);
1872 }
1873
1874 (void) memset(&uscsi, 0, sizeof (iscsi_uscsi_t));
1875 uscsi.iu_vers = ISCSI_INTERFACE_VERSION;
1876
1877 /* iu_oid is a session oid in the driver */
1878 if (deviceId.objectType == IMA_OBJECT_TYPE_TARGET) {
1879 uscsi.iu_oid = deviceId.objectSequenceNumber;
1880 uscsi.iu_lun = 0;
1881 } else {
1882 /*
1883 * Get LU properties and associated session oid
1884 * for this lun(deviceId) and put in uscsi.iu_oid
1885 */
1886 status = getLuProperties(deviceId, &luProps);
1887 if (status != IMA_STATUS_SUCCESS) {
1888 return (status);
1889 }
1890 uscsi.iu_oid = (uint32_t)luProps.associatedTargetOid.
1891 objectSequenceNumber;
1892 uscsi.iu_lun = luProps.targetLun;
1893 }
1894
1895 uscsi.iu_ucmd.uscsi_flags = USCSI_READ;
1896 uscsi.iu_ucmd.uscsi_timeout = USCSI_TIMEOUT_IN_SEC;
1897 uscsi.iu_ucmd.uscsi_bufaddr = (char *)pOutputBuffer;
1898 uscsi.iu_ucmd.uscsi_buflen = buflen;
1899 uscsi.iu_ucmd.uscsi_rqbuf = (char *)pSenseBuffer;
1900 uscsi.iu_ucmd.uscsi_rqlen = (pSenseBufferLength != NULL) ?
1901 *pSenseBufferLength : 0;
1902 uscsi.iu_ucmd.uscsi_cdb = (char *)&cmdblk[0];
1903 uscsi.iu_ucmd.uscsi_cdblen = cdbLength;
1904
1905 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
1906 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
1907 ISCSI_DRIVER_DEVCTL, errno);
1908 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1909 }
1910
1911 if (ioctl(fd, ISCSI_USCSI, &uscsi) != 0) {
1912 (void) close(fd);
1913 syslog(LOG_USER|LOG_DEBUG,
1914 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno);
1915 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1916 }
1917
1918 if (uscsi.iu_ucmd.uscsi_status == STATUS_CHECK) {
1919 if (pSenseBufferLength != NULL) {
1920 *pSenseBufferLength -= uscsi.iu_ucmd.uscsi_rqresid;
1921 }
1922 return (IMA_ERROR_SCSI_STATUS_CHECK_CONDITION);
1923 }
1924
1925 *pOutputBufferLength = buflen - uscsi.iu_ucmd.uscsi_resid;
1926 return (IMA_STATUS_SUCCESS);
1927 }
1928
IMA_LuReportLuns(IMA_OID deviceId,IMA_BOOL sendToWellKnownLun,IMA_BYTE selectReport,IMA_BYTE * pOutputBuffer,IMA_UINT * pOutputBufferLength,IMA_BYTE * pSenseBuffer,IMA_UINT * pSenseBufferLength)1929 IMA_API IMA_STATUS IMA_LuReportLuns(
1930 IMA_OID deviceId,
1931 IMA_BOOL sendToWellKnownLun,
1932 IMA_BYTE selectReport,
1933
1934 IMA_BYTE *pOutputBuffer,
1935 IMA_UINT *pOutputBufferLength,
1936
1937 IMA_BYTE *pSenseBuffer,
1938 IMA_UINT *pSenseBufferLength
1939 )
1940 {
1941 IMA_LU_PROPERTIES luProps;
1942 IMA_STATUS status;
1943 unsigned char cmdblk[CDB_GROUP5];
1944 IMA_UINT buflen;
1945 int fd;
1946 iscsi_uscsi_t uscsi;
1947
1948 (void) memset(&cmdblk[0], 0, CDB_GROUP5);
1949 cmdblk[0] = SCMD_REPORT_LUNS;
1950 cmdblk[2] = selectReport;
1951
1952 if (*pOutputBufferLength > MAX_REPORT_LUNS_BUFFER_LEN) {
1953 buflen = MAX_REPORT_LUNS_BUFFER_LEN;
1954 } else {
1955 buflen = *pOutputBufferLength;
1956 }
1957 cmdblk[6] = (buflen & 0xff000000) >> 24;
1958 cmdblk[7] = (buflen & 0x00ff0000) >> 16;
1959 cmdblk[8] = (buflen & 0x0000ff00) >> 8;
1960 cmdblk[9] = (buflen & 0x000000ff);
1961
1962 (void) memset(&uscsi, 0, sizeof (iscsi_uscsi_t));
1963 uscsi.iu_vers = ISCSI_INTERFACE_VERSION;
1964
1965 /* iu_oid is a session oid in the driver */
1966 if (deviceId.objectType == IMA_OBJECT_TYPE_TARGET) {
1967 if (sendToWellKnownLun == IMA_TRUE) {
1968 /* this optional feature is not supported now */
1969 return (IMA_ERROR_NOT_SUPPORTED);
1970 }
1971 uscsi.iu_oid = deviceId.objectSequenceNumber;
1972 uscsi.iu_lun = 0;
1973 } else {
1974 /*
1975 * Get LU properties and associated session oid
1976 * for this lun(deviceId) and put in uscsi.iu_oid
1977 */
1978 status = getLuProperties(deviceId, &luProps);
1979 if (status != IMA_STATUS_SUCCESS) {
1980 return (status);
1981 }
1982 uscsi.iu_oid = (uint32_t)luProps.associatedTargetOid.
1983 objectSequenceNumber;
1984 uscsi.iu_lun = luProps.targetLun;
1985 }
1986
1987 uscsi.iu_ucmd.uscsi_flags = USCSI_READ;
1988 uscsi.iu_ucmd.uscsi_timeout = USCSI_TIMEOUT_IN_SEC;
1989 uscsi.iu_ucmd.uscsi_bufaddr = (char *)pOutputBuffer;
1990 uscsi.iu_ucmd.uscsi_buflen = buflen;
1991 uscsi.iu_ucmd.uscsi_rqbuf = (char *)pSenseBuffer;
1992 uscsi.iu_ucmd.uscsi_rqlen = (pSenseBufferLength != NULL) ?
1993 *pSenseBufferLength : 0;
1994 uscsi.iu_ucmd.uscsi_cdb = (char *)&cmdblk[0];
1995 uscsi.iu_ucmd.uscsi_cdblen = CDB_GROUP5;
1996
1997 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
1998 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
1999 ISCSI_DRIVER_DEVCTL, errno);
2000 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2001 }
2002
2003 if (ioctl(fd, ISCSI_USCSI, &uscsi) != 0) {
2004 (void) close(fd);
2005 syslog(LOG_USER|LOG_DEBUG,
2006 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno);
2007 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2008 }
2009
2010 if (uscsi.iu_ucmd.uscsi_status == STATUS_CHECK) {
2011 if (pSenseBufferLength != NULL) {
2012 *pSenseBufferLength -= uscsi.iu_ucmd.uscsi_rqresid;
2013 }
2014 return (IMA_ERROR_SCSI_STATUS_CHECK_CONDITION);
2015 }
2016
2017 *pOutputBufferLength = buflen - uscsi.iu_ucmd.uscsi_resid;
2018 return (IMA_STATUS_SUCCESS);
2019 }
2020
2021 /*ARGSUSED*/
IMA_ExposeLu(IMA_OID luId)2022 IMA_API IMA_STATUS IMA_ExposeLu(
2023 IMA_OID luId
2024 )
2025 {
2026 return (IMA_ERROR_NOT_SUPPORTED);
2027 }
2028
2029 /*ARGSUSED*/
IMA_UnexposeLu(IMA_OID luId)2030 IMA_API IMA_STATUS IMA_UnexposeLu(
2031 IMA_OID luId
2032 )
2033 {
2034 return (IMA_ERROR_NOT_SUPPORTED);
2035 }
2036
IMA_GetAddressKeys(IMA_OID targetOid,IMA_ADDRESS_KEYS ** ppKeys)2037 IMA_API IMA_STATUS IMA_GetAddressKeys(
2038 IMA_OID targetOid,
2039 IMA_ADDRESS_KEYS **ppKeys
2040 )
2041 {
2042 IMA_STATUS status;
2043 IMA_TARGET_PROPERTIES targetProps;
2044 SUN_IMA_DISC_ADDR_PROP_LIST *discAddressList;
2045 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *pList;
2046 int i, j, addressKeyCount = 0;
2047 int addressKeyIdx = 0;
2048
2049 status = getTargetProperties(targetOid, &targetProps);
2050 if (status != IMA_STATUS_SUCCESS) {
2051 return (status);
2052 }
2053
2054 status = getDiscoveryAddressPropertiesList(&discAddressList);
2055 if (status != IMA_STATUS_SUCCESS) {
2056 return (status);
2057 }
2058
2059 /* Get the number of addresses to allocate */
2060 for (i = 0; i < discAddressList->discAddrCount; i++) {
2061 (void) sendTargets(discAddressList->props[i].discoveryAddress,
2062 &pList);
2063 for (j = 0; j < pList->keyCount; j++) {
2064 if (wcsncmp(pList->keys[j].name, targetProps.name,
2065 wslen(pList->keys[j].name)) == 0) {
2066 addressKeyCount++;
2067 }
2068 }
2069 (void) IMA_FreeMemory(pList);
2070 }
2071
2072 *ppKeys = (IMA_ADDRESS_KEYS *)calloc(1, sizeof (IMA_ADDRESS_KEYS) +
2073 addressKeyCount * sizeof (IMA_ADDRESS_KEY));
2074 if (*ppKeys == NULL) {
2075 return (IMA_ERROR_INSUFFICIENT_MEMORY);
2076 }
2077 (*ppKeys)->addressKeyCount = addressKeyCount;
2078 addressKeyIdx = 0;
2079
2080 for (i = 0; i < discAddressList->discAddrCount; i++) {
2081 (void) sendTargets(discAddressList->props[i].discoveryAddress,
2082 &pList);
2083 for (j = 0; j < pList->keyCount; j++) {
2084 if (wcsncmp(pList->keys[j].name, targetProps.name,
2085 wslen(pList->keys[j].name)) != 0) {
2086 continue;
2087 }
2088
2089 bcopy(&(pList->keys[j].address.ipAddress),
2090 &((*ppKeys)->addressKeys[addressKeyIdx].
2091 ipAddress), sizeof (IMA_IP_ADDRESS));
2092
2093 (*ppKeys)->addressKeys[addressKeyIdx++].portNumber =
2094 pList->keys[j].address.portNumber;
2095
2096 }
2097 (void) IMA_FreeMemory(pList);
2098 }
2099 return (IMA_STATUS_SUCCESS);
2100 }
2101
isAuthMethodValid(IMA_OID oid,IMA_AUTHMETHOD method)2102 IMA_BOOL isAuthMethodValid(IMA_OID oid, IMA_AUTHMETHOD method) {
2103 IMA_STATUS status;
2104 IMA_AUTHMETHOD supportedList[MAX_AUTHMETHODS];
2105 IMA_UINT i, supportedCount;
2106 IMA_BOOL supported;
2107 status = getSupportedAuthMethods(oid, IMA_FALSE, &supportedCount,
2108 supportedList);
2109 if (status != IMA_STATUS_SUCCESS)
2110 return (IMA_FALSE);
2111
2112 supported = IMA_FALSE;
2113 for (i = 0; i < supportedCount; i++) {
2114 if (method == supportedList[i]) {
2115 supported = IMA_TRUE;
2116 }
2117 }
2118
2119 return (supported);
2120 }
2121
isAuthMethodListValid(IMA_OID oid,const IMA_AUTHMETHOD * pMethodList,IMA_UINT methodCount)2122 IMA_BOOL isAuthMethodListValid(IMA_OID oid, const IMA_AUTHMETHOD *pMethodList,
2123 IMA_UINT methodCount) {
2124 IMA_UINT i, j;
2125
2126 if (pMethodList == NULL) {
2127 return (IMA_FALSE);
2128 }
2129 /* Check list for duplicates */
2130 for (i = 0; i < methodCount; i++) {
2131 for (j = i + 1; j < methodCount; j++) {
2132 if (pMethodList[i] == pMethodList[j]) {
2133 return (IMA_FALSE);
2134 }
2135 }
2136
2137 if (isAuthMethodValid(oid, pMethodList[i]) == IMA_FALSE) {
2138 return (IMA_FALSE);
2139 }
2140 }
2141 return (IMA_TRUE);
2142 }
2143
IMA_GetSupportedAuthMethods(IMA_OID lhbaOid,IMA_BOOL getSettableMethods,IMA_UINT * pMethodCount,IMA_AUTHMETHOD * pMethodList)2144 IMA_API IMA_STATUS IMA_GetSupportedAuthMethods(
2145 IMA_OID lhbaOid,
2146 IMA_BOOL getSettableMethods,
2147 IMA_UINT *pMethodCount,
2148 IMA_AUTHMETHOD *pMethodList
2149 )
2150 {
2151 return (getSupportedAuthMethods(lhbaOid, getSettableMethods,
2152 pMethodCount, pMethodList));
2153 }
2154
2155
2156 /*ARGSUSED*/
getSupportedAuthMethods(IMA_OID lhbaOid,IMA_BOOL getSettableMethods,IMA_UINT * pMethodCount,IMA_AUTHMETHOD * pMethodList)2157 static IMA_STATUS getSupportedAuthMethods(
2158 IMA_OID lhbaOid,
2159 IMA_BOOL getSettableMethods,
2160 IMA_UINT *pMethodCount,
2161 IMA_AUTHMETHOD *pMethodList
2162 )
2163 {
2164 if (pMethodList == NULL) {
2165 *pMethodCount = 0;
2166 return (IMA_STATUS_SUCCESS);
2167 }
2168
2169 *pMethodCount = NUM_SUPPORTED_AUTH_METHODS;
2170 if (*pMethodCount > 1) {
2171 pMethodList[0] = IMA_AUTHMETHOD_NONE;
2172 pMethodList[1] = IMA_AUTHMETHOD_CHAP;
2173 }
2174
2175 return (IMA_STATUS_SUCCESS);
2176 }
2177
IMA_GetInUseInitiatorAuthMethods(IMA_OID lhbaOid,IMA_UINT * pMethodCount,IMA_AUTHMETHOD * pMethodList)2178 IMA_API IMA_STATUS IMA_GetInUseInitiatorAuthMethods(
2179 IMA_OID lhbaOid,
2180 IMA_UINT *pMethodCount,
2181 IMA_AUTHMETHOD *pMethodList
2182 )
2183 {
2184 return (getAuthMethods(lhbaOid, pMethodCount, pMethodList));
2185 }
2186
2187 /*ARGSUSED*/
IMA_GetInitiatorAuthParms(IMA_OID lhbaOid,IMA_AUTHMETHOD method,IMA_INITIATOR_AUTHPARMS * pParms)2188 IMA_API IMA_STATUS IMA_GetInitiatorAuthParms(
2189 IMA_OID lhbaOid,
2190 IMA_AUTHMETHOD method,
2191 IMA_INITIATOR_AUTHPARMS *pParms
2192 )
2193 {
2194 int fd;
2195 iscsi_chap_props_t chap_p;
2196
2197 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
2198 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
2199 ISCSI_DRIVER_DEVCTL, errno);
2200 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2201 }
2202
2203 (void) memset(&chap_p, 0, sizeof (iscsi_chap_props_t));
2204 chap_p.c_vers = ISCSI_INTERFACE_VERSION;
2205 chap_p.c_oid = (uint32_t)lhbaOid.objectSequenceNumber;
2206
2207 if (method == IMA_AUTHMETHOD_CHAP) {
2208 if (ioctl(fd, ISCSI_CHAP_GET, &chap_p) != 0) {
2209 syslog(LOG_USER|LOG_DEBUG,
2210 "ISCSI_CHAP_GET ioctl failed, errno: %d", errno);
2211 (void) close(fd);
2212 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2213 }
2214 } else {
2215 return (IMA_ERROR_INVALID_PARAMETER);
2216 }
2217
2218 (void) memcpy(pParms->chapParms.name, chap_p.c_user,
2219 chap_p.c_user_len);
2220 pParms->chapParms.nameLength = chap_p.c_user_len;
2221 (void) memcpy(pParms->chapParms.challengeSecret, chap_p.c_secret,
2222 chap_p.c_secret_len);
2223 pParms->chapParms.challengeSecretLength = chap_p.c_secret_len;
2224
2225 return (IMA_STATUS_SUCCESS);
2226 }
2227
IMA_SetInitiatorAuthMethods(IMA_OID lhbaOid,IMA_UINT methodCount,const IMA_AUTHMETHOD * pMethodList)2228 IMA_API IMA_STATUS IMA_SetInitiatorAuthMethods(
2229 IMA_OID lhbaOid,
2230 IMA_UINT methodCount,
2231 const IMA_AUTHMETHOD *pMethodList
2232 )
2233 {
2234 if (isAuthMethodListValid(lhbaOid, pMethodList,
2235 methodCount) == IMA_FALSE)
2236 return (IMA_ERROR_INVALID_PARAMETER);
2237 return (setAuthMethods(lhbaOid, &methodCount, pMethodList));
2238 }
2239
2240 /*
2241 * This function only sets CHAP params since we only support CHAP for now.
2242 */
IMA_SetInitiatorAuthParms(IMA_OID lhbaOid,IMA_AUTHMETHOD method,const IMA_INITIATOR_AUTHPARMS * pParms)2243 IMA_API IMA_STATUS IMA_SetInitiatorAuthParms(
2244 IMA_OID lhbaOid,
2245 IMA_AUTHMETHOD method,
2246 const IMA_INITIATOR_AUTHPARMS *pParms
2247 )
2248 {
2249 int fd;
2250 iscsi_chap_props_t chap_p;
2251
2252 if (method != IMA_AUTHMETHOD_CHAP)
2253 return (IMA_ERROR_INVALID_PARAMETER);
2254
2255 if (isAuthMethodValid(lhbaOid, method) == IMA_FALSE) {
2256 return (IMA_ERROR_INVALID_PARAMETER);
2257 }
2258
2259 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
2260 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
2261 ISCSI_DRIVER_DEVCTL, errno);
2262 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2263 }
2264
2265 (void) memset(&chap_p, 0, sizeof (iscsi_chap_props_t));
2266 chap_p.c_vers = ISCSI_INTERFACE_VERSION;
2267 chap_p.c_oid = (uint32_t)lhbaOid.objectSequenceNumber;
2268
2269 chap_p.c_user_len = pParms->chapParms.nameLength;
2270 (void) memcpy(chap_p.c_user, pParms->chapParms.name, chap_p.c_user_len);
2271
2272 chap_p.c_secret_len = pParms->chapParms.challengeSecretLength;
2273 (void) memcpy(chap_p.c_secret, pParms->chapParms.challengeSecret,
2274 chap_p.c_secret_len);
2275
2276 if (method == IMA_AUTHMETHOD_CHAP) {
2277 if (ioctl(fd, ISCSI_CHAP_SET, &chap_p) != 0) {
2278 (void) close(fd);
2279 syslog(LOG_USER|LOG_DEBUG,
2280 "ISCSI_CHAP_SET ioctl failed, errno: %d", errno);
2281 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2282 }
2283 }
2284
2285 return (IMA_STATUS_SUCCESS);
2286 }
2287
2288 /* A helper function to obtain iSCSI node parameters. */
2289 static IMA_STATUS
getISCSINodeParameter(int paramType,IMA_OID * oid,void * pProps,uint32_t paramIndex)2290 getISCSINodeParameter(
2291 int paramType,
2292 IMA_OID *oid,
2293 void *pProps,
2294 uint32_t paramIndex
2295 )
2296 {
2297 int fd;
2298 iscsi_param_get_t pg;
2299
2300 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
2301 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
2302 ISCSI_DRIVER_DEVCTL, errno);
2303 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2304 }
2305
2306 (void) memset(&pg, 0, sizeof (iscsi_param_get_t));
2307 pg.g_vers = ISCSI_INTERFACE_VERSION;
2308 pg.g_oid = (uint32_t)oid->objectSequenceNumber;
2309 pg.g_param = paramIndex;
2310 pg.g_param_type = ISCSI_SESS_PARAM;
2311
2312 if (ioctl(fd, ISCSI_PARAM_GET, &pg) != 0) {
2313 syslog(LOG_USER|LOG_DEBUG,
2314 "ISCSI_PARAM_GET ioctl failed, errno: %d", errno);
2315 (void) close(fd);
2316 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2317 }
2318
2319 switch (paramType) {
2320 IMA_BOOL_VALUE *bp;
2321 IMA_MIN_MAX_VALUE *mp;
2322
2323 case MIN_MAX_PARAM:
2324 mp = (IMA_MIN_MAX_VALUE *)pProps;
2325
2326 mp->currentValueValid =
2327 (pg.g_value.v_valid == B_TRUE) ?
2328 IMA_TRUE : IMA_FALSE;
2329 mp->currentValue = pg.g_value.v_integer.i_current;
2330 mp->defaultValue = pg.g_value.v_integer.i_default;
2331 mp->minimumValue = pg.g_value.v_integer.i_min;
2332 mp->maximumValue = pg.g_value.v_integer.i_max;
2333 mp->incrementValue = pg.g_value.v_integer.i_incr;
2334 break;
2335
2336 case BOOL_PARAM:
2337 bp = (IMA_BOOL_VALUE *)pProps;
2338 bp->currentValueValid =
2339 (pg.g_value.v_valid == B_TRUE) ?
2340 IMA_TRUE : IMA_FALSE;
2341 bp->currentValue = pg.g_value.v_bool.b_current;
2342 bp->defaultValue = pg.g_value.v_bool.b_default;
2343 break;
2344
2345 default:
2346 break;
2347 }
2348
2349 (void) close(fd);
2350 return (IMA_STATUS_SUCCESS);
2351 }
2352
2353 /* A helper function to set iSCSI node parameters. */
2354 static IMA_STATUS
setISCSINodeParameter(int paramType,IMA_OID * oid,void * pProp,uint32_t paramIndex)2355 setISCSINodeParameter(
2356 int paramType,
2357 IMA_OID *oid,
2358 void *pProp,
2359 uint32_t paramIndex
2360 )
2361 {
2362 int fd;
2363 iscsi_param_set_t ps;
2364
2365 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
2366 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
2367 ISCSI_DRIVER_DEVCTL, errno);
2368 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2369 }
2370
2371 (void) memset(&ps, 0, sizeof (iscsi_param_set_t));
2372 ps.s_vers = ISCSI_INTERFACE_VERSION;
2373 ps.s_oid = (uint32_t)oid->objectSequenceNumber;
2374 ps.s_param = paramIndex;
2375
2376 switch (paramType) {
2377 IMA_BOOL_VALUE *bp;
2378 IMA_MIN_MAX_VALUE *mp;
2379
2380 case MIN_MAX_PARAM:
2381 mp = (IMA_MIN_MAX_VALUE *)pProp;
2382 ps.s_value.v_integer = mp->currentValue;
2383 break;
2384 case BOOL_PARAM:
2385 bp = (IMA_BOOL_VALUE *)pProp;
2386 ps.s_value.v_bool =
2387 (bp->currentValue == IMA_TRUE) ?
2388 B_TRUE : B_FALSE;
2389 break;
2390
2391 default:
2392 break;
2393 }
2394
2395 if (ioctl(fd, ISCSI_PARAM_SET, &ps)) {
2396 int tmpErrno = errno;
2397 syslog(LOG_USER|LOG_DEBUG,
2398 "ISCSI_PARAM_SET ioctl failed, errno: %d", errno);
2399 (void) close(fd);
2400 switch (tmpErrno) {
2401 case ENOTSUP :
2402 return (IMA_ERROR_NOT_SUPPORTED);
2403 default :
2404 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2405 }
2406 }
2407
2408 (void) close(fd);
2409 return (IMA_STATUS_SUCCESS);
2410 }
2411
2412 static int
prepare_discovery_entry(IMA_TARGET_ADDRESS discoveryAddress,entry_t * entry)2413 prepare_discovery_entry(
2414 IMA_TARGET_ADDRESS discoveryAddress,
2415 entry_t *entry
2416 )
2417 {
2418 (void) memset(entry, 0, sizeof (entry_t));
2419 entry->e_vers = ISCSI_INTERFACE_VERSION;
2420 entry->e_oid = ISCSI_OID_NOTSET;
2421
2422 if (discoveryAddress.hostnameIpAddress.id.ipAddress.ipv4Address ==
2423 IMA_FALSE) {
2424 bcopy(discoveryAddress.hostnameIpAddress.id.ipAddress.ipAddress,
2425 entry->e_u.u_in6.s6_addr,
2426 sizeof (entry->e_u.u_in6.s6_addr));
2427 entry->e_insize = sizeof (struct in6_addr);
2428 } else {
2429 bcopy(discoveryAddress.hostnameIpAddress.id.ipAddress.ipAddress,
2430 &entry->e_u.u_in4.s_addr,
2431 sizeof (entry->e_u.u_in4.s_addr));
2432 entry->e_insize = sizeof (struct in_addr);
2433 }
2434
2435 entry->e_port = discoveryAddress.portNumber;
2436 entry->e_tpgt = 0;
2437 return (DISC_ADDR_OK);
2438 }
2439
configure_discovery_method(IMA_BOOL enable,iSCSIDiscoveryMethod_t method)2440 static IMA_STATUS configure_discovery_method(
2441 IMA_BOOL enable,
2442 iSCSIDiscoveryMethod_t method
2443 )
2444 {
2445 int fd, status;
2446
2447 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
2448 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
2449 ISCSI_DRIVER_DEVCTL, errno);
2450 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2451 }
2452
2453 if (enable == IMA_FALSE) {
2454 if (ioctl(fd, ISCSI_DISCOVERY_CLEAR, &method)) {
2455 status = errno;
2456 (void) close(fd);
2457 syslog(LOG_USER|LOG_DEBUG,
2458 "ISCSI_DISCOVERY_CLEAR ioctl failed, errno: %d",
2459 status);
2460 if (status == EBUSY) {
2461 return (IMA_ERROR_LU_IN_USE);
2462 } else {
2463 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2464 }
2465 }
2466
2467 (void) close(fd);
2468 return (IMA_STATUS_SUCCESS);
2469 } else {
2470 /* Set the discovery method */
2471 if (ioctl(fd, ISCSI_DISCOVERY_SET, &method)) {
2472 (void) close(fd);
2473 syslog(LOG_USER|LOG_DEBUG,
2474 "ISCSI_DISCOVERY_SET ioctl failed, errno: %d",
2475 errno);
2476 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2477 }
2478
2479 (void) close(fd);
2480 return (IMA_STATUS_SUCCESS);
2481 }
2482 }
2483
get_target_oid_list(uint32_t targetListType,IMA_OID_LIST ** ppList)2484 static IMA_STATUS get_target_oid_list(
2485 uint32_t targetListType,
2486 IMA_OID_LIST **ppList)
2487 {
2488 int fd;
2489 int i;
2490 int target_list_size;
2491 iscsi_target_list_t *idlp, tl_info;
2492
2493 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
2494 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
2495 ISCSI_DRIVER_DEVCTL, errno);
2496 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2497 }
2498
2499 (void) memset(&tl_info, 0, sizeof (tl_info));
2500 tl_info.tl_vers = ISCSI_INTERFACE_VERSION;
2501 tl_info.tl_in_cnt = 0;
2502 tl_info.tl_tgt_list_type = targetListType;
2503
2504 /*
2505 * Issue ioctl to obtain the number of targets.
2506 */
2507 if (ioctl(fd, ISCSI_TARGET_OID_LIST_GET, &tl_info) != 0) {
2508 (void) close(fd);
2509 syslog(LOG_USER|LOG_DEBUG,
2510 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
2511 targetListType, errno);
2512 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2513 }
2514
2515 target_list_size = sizeof (iscsi_target_list_t);
2516 if (tl_info.tl_out_cnt > 1) {
2517 target_list_size += (sizeof (uint32_t) *
2518 tl_info.tl_out_cnt - 1);
2519 }
2520
2521 idlp = (iscsi_target_list_t *)calloc(1, target_list_size);
2522 if (idlp == NULL) {
2523 (void) close(fd);
2524 return (IMA_ERROR_INSUFFICIENT_MEMORY);
2525 }
2526
2527 idlp->tl_vers = ISCSI_INTERFACE_VERSION;
2528 idlp->tl_in_cnt = tl_info.tl_out_cnt;
2529 idlp->tl_tgt_list_type = targetListType;
2530
2531 /* Issue the same ioctl again to obtain the OIDs. */
2532 if (ioctl(fd, ISCSI_TARGET_OID_LIST_GET, idlp) != 0) {
2533 free(idlp);
2534 (void) close(fd);
2535 syslog(LOG_USER|LOG_DEBUG,
2536 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
2537 targetListType, errno);
2538 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2539 }
2540
2541 *ppList = (IMA_OID_LIST *)calloc(1, sizeof (IMA_OID_LIST) +
2542 idlp->tl_out_cnt * sizeof (IMA_OID));
2543 if (*ppList == NULL) {
2544 free(idlp);
2545 (void) close(fd);
2546 return (IMA_ERROR_INSUFFICIENT_MEMORY);
2547 }
2548 (*ppList)->oidCount = idlp->tl_out_cnt;
2549
2550 for (i = 0; i < idlp->tl_out_cnt; i++) {
2551
2552 if (targetListType == ISCSI_STATIC_TGT_OID_LIST)
2553 (*ppList)->oids[i].objectType =
2554 IMA_OBJECT_TYPE_STATIC_DISCOVERY_TARGET;
2555 else
2556 (*ppList)->oids[i].objectType = IMA_OBJECT_TYPE_TARGET;
2557
2558 (*ppList)->oids[i].ownerId = pluginOwnerId;
2559 (*ppList)->oids[i].objectSequenceNumber = idlp->tl_oid_list[i];
2560 }
2561
2562 free(idlp);
2563 (void) close(fd);
2564 return (IMA_STATUS_SUCCESS);
2565 }
2566
get_target_lun_oid_list(IMA_OID * targetOid,iscsi_lun_list_t ** ppLunList)2567 static IMA_STATUS get_target_lun_oid_list(
2568 IMA_OID * targetOid,
2569 iscsi_lun_list_t **ppLunList)
2570 {
2571 int fd;
2572 iscsi_lun_list_t *illp, ll_info;
2573 int lun_list_size;
2574
2575 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
2576 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
2577 ISCSI_DRIVER_DEVCTL, errno);
2578 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2579 }
2580
2581 (void) memset(&ll_info, 0, sizeof (ll_info));
2582 ll_info.ll_vers = ISCSI_INTERFACE_VERSION;
2583 if (targetOid == NULL) {
2584 /* get lun oid list for all targets */
2585 ll_info.ll_all_tgts = B_TRUE;
2586 } else {
2587 /* get lun oid list for single target */
2588 ll_info.ll_all_tgts = B_FALSE;
2589 ll_info.ll_tgt_oid = (uint32_t)targetOid->objectSequenceNumber;
2590 }
2591 ll_info.ll_in_cnt = 0;
2592
2593 /*
2594 * Issue ioctl to obtain the number of target LUNs.
2595 */
2596 if (ioctl(fd, ISCSI_LUN_OID_LIST_GET, &ll_info) != 0) {
2597 (void) close(fd);
2598 syslog(LOG_USER|LOG_DEBUG,
2599 "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", errno);
2600 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2601 }
2602
2603 lun_list_size = sizeof (iscsi_lun_list_t);
2604 if (ll_info.ll_out_cnt > 1) {
2605 lun_list_size += (sizeof (iscsi_if_lun_t) *
2606 (ll_info.ll_out_cnt - 1));
2607 }
2608
2609 illp = (iscsi_lun_list_t *)calloc(1, lun_list_size);
2610 if (illp == NULL) {
2611 (void) close(fd);
2612 return (IMA_ERROR_INSUFFICIENT_MEMORY);
2613 }
2614 illp->ll_vers = ISCSI_INTERFACE_VERSION;
2615 illp->ll_all_tgts = ll_info.ll_all_tgts;
2616 illp->ll_tgt_oid = ll_info.ll_tgt_oid;
2617 illp->ll_in_cnt = ll_info.ll_out_cnt;
2618
2619 /* Issue the same ioctl again to get the target LUN list */
2620 if (ioctl(fd, ISCSI_LUN_OID_LIST_GET, illp) != 0) {
2621 free(illp);
2622 (void) close(fd);
2623 syslog(LOG_USER|LOG_DEBUG,
2624 "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", errno);
2625 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2626 }
2627
2628 *ppLunList = illp;
2629
2630 (void) close(fd);
2631 return (IMA_STATUS_SUCCESS);
2632 }
2633
2634
2635 /* A helper function to set authentication method. */
2636 static IMA_STATUS
setAuthMethods(IMA_OID oid,IMA_UINT * pMethodCount,const IMA_AUTHMETHOD * pMethodList)2637 setAuthMethods(
2638 IMA_OID oid,
2639 IMA_UINT *pMethodCount,
2640 const IMA_AUTHMETHOD *pMethodList
2641 )
2642 {
2643 int fd;
2644 int i;
2645 iscsi_auth_props_t auth;
2646
2647 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
2648 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
2649 ISCSI_DRIVER_DEVCTL, errno);
2650 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2651 }
2652 (void) memset(&auth, 0, sizeof (iscsi_auth_props_t));
2653 auth.a_vers = ISCSI_INTERFACE_VERSION;
2654 auth.a_oid = (uint32_t)oid.objectSequenceNumber;
2655 /* First do a get because other data fields may exist */
2656 if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) {
2657 /* EMPTY */
2658 /* It is fine if there is no other data fields. */
2659 }
2660 auth.a_auth_method = authMethodNone;
2661
2662 for (i = 0; i < *pMethodCount; i++) {
2663 switch (pMethodList[i]) {
2664 case IMA_AUTHMETHOD_CHAP:
2665 auth.a_auth_method |= authMethodCHAP;
2666 break;
2667 default:
2668 break;
2669 }
2670 }
2671
2672 if (ioctl(fd, ISCSI_AUTH_SET, &auth) != 0) {
2673 syslog(LOG_USER|LOG_DEBUG,
2674 "ISCSI_AUTH_SET failed, errno: %d", errno);
2675 (void) close(fd);
2676 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2677 }
2678
2679 (void) close(fd);
2680 return (IMA_STATUS_SUCCESS);
2681 }
2682
2683 /* A helper function to get authentication method. */
2684 static IMA_STATUS
getAuthMethods(IMA_OID oid,IMA_UINT * pMethodCount,IMA_AUTHMETHOD * pMethodList)2685 getAuthMethods(
2686 IMA_OID oid,
2687 IMA_UINT *pMethodCount,
2688 IMA_AUTHMETHOD *pMethodList
2689 )
2690 {
2691 int fd, i;
2692 iscsi_auth_props_t auth;
2693
2694 if (pMethodList == NULL) {
2695 *pMethodCount = 0;
2696 return (IMA_STATUS_SUCCESS);
2697 }
2698
2699 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
2700 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
2701 ISCSI_DRIVER_DEVCTL, errno);
2702 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2703 }
2704
2705 (void) memset(&auth, 0, sizeof (iscsi_auth_props_t));
2706 auth.a_vers = ISCSI_INTERFACE_VERSION;
2707 auth.a_oid = (uint32_t)oid.objectSequenceNumber;
2708
2709 if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) {
2710 syslog(LOG_USER|LOG_DEBUG,
2711 "ISCSI_AUTH_GET failed, errno: %d", errno);
2712 (void) close(fd);
2713 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2714 }
2715
2716 i = 0;
2717 if (auth.a_auth_method == authMethodNone) {
2718 pMethodList[i++] = IMA_AUTHMETHOD_NONE;
2719 } else if (auth.a_auth_method & authMethodCHAP) {
2720 pMethodList[i++] = IMA_AUTHMETHOD_CHAP;
2721 }
2722 *pMethodCount = i;
2723
2724 (void) close(fd);
2725 return (IMA_STATUS_SUCCESS);
2726 }
2727
IMA_GetPhbaOidList(IMA_OID_LIST ** ppList)2728 IMA_API IMA_STATUS IMA_GetPhbaOidList(
2729 IMA_OID_LIST **ppList
2730 )
2731 {
2732 *ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST));
2733 if (*ppList == NULL) {
2734 return (IMA_ERROR_INSUFFICIENT_MEMORY);
2735 }
2736 (*ppList)->oidCount = 0;
2737 return (IMA_STATUS_SUCCESS);
2738 }
2739
2740 /* ARGSUSED */
IMA_GetPhbaProperties(IMA_OID phbaOid,IMA_PHBA_PROPERTIES * pProps)2741 IMA_API IMA_STATUS IMA_GetPhbaProperties(
2742 IMA_OID phbaOid,
2743 IMA_PHBA_PROPERTIES *pProps
2744 )
2745 {
2746 return (IMA_ERROR_OBJECT_NOT_FOUND);
2747 }
2748
2749 /* ARGSUSED */
IMA_GetPhbaStatus(IMA_OID phbaOid,IMA_PHBA_STATUS * pStatus)2750 IMA_API IMA_STATUS IMA_GetPhbaStatus(
2751 IMA_OID phbaOid,
2752 IMA_PHBA_STATUS *pStatus
2753 )
2754 {
2755 return (IMA_ERROR_OBJECT_NOT_FOUND);
2756 }
2757
2758 /* ARGSUSED */
IMA_GetPhbaDownloadProperties(IMA_OID phbaOid,IMA_PHBA_DOWNLOAD_PROPERTIES * pProps)2759 IMA_API IMA_STATUS IMA_GetPhbaDownloadProperties(
2760 IMA_OID phbaOid,
2761 IMA_PHBA_DOWNLOAD_PROPERTIES *pProps
2762 )
2763 {
2764 return (IMA_ERROR_OBJECT_NOT_FOUND);
2765 }
2766
2767 /* ARGSUSED */
IMA_IsPhbaDownloadFile(IMA_OID phbaOid,const IMA_WCHAR * pFileName,IMA_PHBA_DOWNLOAD_IMAGE_PROPERTIES * pProps)2768 IMA_API IMA_STATUS IMA_IsPhbaDownloadFile(
2769 IMA_OID phbaOid,
2770 const IMA_WCHAR *pFileName,
2771 IMA_PHBA_DOWNLOAD_IMAGE_PROPERTIES *pProps
2772 )
2773 {
2774 return (IMA_ERROR_OBJECT_NOT_FOUND);
2775 }
2776
2777 /* ARGSUSED */
IMA_PhbaDownload(IMA_OID phbaOid,IMA_PHBA_DOWNLOAD_IMAGE_TYPE imageType,const IMA_WCHAR * pFileName)2778 IMA_API IMA_STATUS IMA_PhbaDownload(
2779 IMA_OID phbaOid,
2780 IMA_PHBA_DOWNLOAD_IMAGE_TYPE imageType,
2781 const IMA_WCHAR *pFileName
2782 )
2783 {
2784 return (IMA_ERROR_OBJECT_NOT_FOUND);
2785 }
2786
IMA_GetPnpOidList(IMA_OID pnpOid,IMA_OID_LIST ** ppList)2787 IMA_API IMA_STATUS IMA_GetPnpOidList(
2788 IMA_OID pnpOid,
2789 IMA_OID_LIST **ppList
2790 )
2791 {
2792 /*
2793 * Always return the same object ID for the pnp as the spec
2794 * states that this function will always return a list of at least
2795 * one element
2796 */
2797 pnpOid.objectType = IMA_OBJECT_TYPE_PNP;
2798 pnpOid.ownerId = pluginOwnerId;
2799 pnpOid.objectSequenceNumber = ISCSI_INITIATOR_OID;
2800
2801 *ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST) +
2802 (1* sizeof (IMA_OID)));
2803
2804 if (*ppList == NULL) {
2805 return (IMA_ERROR_INSUFFICIENT_MEMORY);
2806 }
2807
2808 (*ppList)->oidCount = 1;
2809 (void) memcpy(&(*ppList)->oids[0], &pnpOid, sizeof (pnpOid));
2810 return (IMA_STATUS_SUCCESS);
2811 }
2812
2813 /* ARGSUSED */
IMA_GetPnpProperties(IMA_OID pnpOid,IMA_PNP_PROPERTIES * pProps)2814 IMA_API IMA_STATUS IMA_GetPnpProperties(
2815 IMA_OID pnpOid,
2816 IMA_PNP_PROPERTIES *pProps
2817 )
2818 {
2819 return (IMA_ERROR_OBJECT_NOT_FOUND);
2820 }
2821
2822 /* ARGSUSED */
IMA_GetPnpStatistics(IMA_OID pnpOid,IMA_PNP_STATISTICS * pStats)2823 IMA_API IMA_STATUS IMA_GetPnpStatistics(
2824 IMA_OID pnpOid,
2825 IMA_PNP_STATISTICS *pStats
2826 )
2827 {
2828 return (IMA_ERROR_OBJECT_NOT_FOUND);
2829 }
2830
2831 /* ARGSUSED */
IMA_GetIpProperties(IMA_OID oid,IMA_IP_PROPERTIES * pProps)2832 IMA_API IMA_STATUS IMA_GetIpProperties(
2833 IMA_OID oid,
2834 IMA_IP_PROPERTIES *pProps
2835 )
2836 {
2837 return (IMA_ERROR_OBJECT_NOT_FOUND);
2838 }
2839
2840 /* ARGSUSED */
IMA_SetDefaultGateway(IMA_OID oid,IMA_IP_ADDRESS defaultGateway)2841 IMA_API IMA_STATUS IMA_SetDefaultGateway(
2842 IMA_OID oid,
2843 IMA_IP_ADDRESS defaultGateway
2844 )
2845 {
2846 return (IMA_ERROR_OBJECT_NOT_FOUND);
2847 }
2848
2849 /* ARGSUSED */
IMA_SetDnsServerAddress(IMA_OID oid,const IMA_IP_ADDRESS * pPrimaryDnsServerAddress,const IMA_IP_ADDRESS * pAlternateDnsServerAddress)2850 IMA_API IMA_STATUS IMA_SetDnsServerAddress(
2851 IMA_OID oid,
2852 const IMA_IP_ADDRESS *pPrimaryDnsServerAddress,
2853 const IMA_IP_ADDRESS *pAlternateDnsServerAddress
2854 )
2855 {
2856 return (IMA_ERROR_OBJECT_NOT_FOUND);
2857 }
2858
2859 /* ARGSUSED */
IMA_SetSubnetMask(IMA_OID oid,IMA_IP_ADDRESS subnetMask)2860 IMA_API IMA_STATUS IMA_SetSubnetMask(
2861 IMA_OID oid,
2862 IMA_IP_ADDRESS subnetMask
2863 )
2864 {
2865 return (IMA_ERROR_OBJECT_NOT_FOUND);
2866 }
2867
2868 /* ARGSUSED */
IMA_SetIpConfigMethod(IMA_OID oid,IMA_BOOL enableDhcpIpConfiguration)2869 IMA_API IMA_STATUS IMA_SetIpConfigMethod(
2870 IMA_OID oid,
2871 IMA_BOOL enableDhcpIpConfiguration
2872 )
2873 {
2874 return (IMA_ERROR_OBJECT_NOT_FOUND);
2875 }
2876
IMA_RegisterForObjectPropertyChanges(IMA_OBJECT_PROPERTY_FN pClientFn)2877 IMA_API IMA_STATUS IMA_RegisterForObjectPropertyChanges(
2878 IMA_OBJECT_PROPERTY_FN pClientFn
2879 )
2880 {
2881 pObjectPropertyCallback = pClientFn;
2882 return (IMA_STATUS_SUCCESS);
2883 }
2884
2885 /* ARGSUSED */
IMA_DeregisterForObjectPropertyChanges(IMA_OBJECT_PROPERTY_FN pClientFn)2886 IMA_API IMA_STATUS IMA_DeregisterForObjectPropertyChanges(
2887 IMA_OBJECT_PROPERTY_FN pClientFn
2888 )
2889 {
2890 return (IMA_STATUS_SUCCESS);
2891 }
2892
IMA_RegisterForObjectVisibilityChanges(IMA_OBJECT_VISIBILITY_FN pClientFn)2893 IMA_API IMA_STATUS IMA_RegisterForObjectVisibilityChanges(
2894 IMA_OBJECT_VISIBILITY_FN pClientFn
2895 )
2896 {
2897 pObjectVisibilityCallback = pClientFn;
2898 return (IMA_STATUS_SUCCESS);
2899 }
2900
2901 /* ARGSUSED */
IMA_DeregisterForObjectVisibilityChanges(IMA_OBJECT_VISIBILITY_FN pClientFn)2902 IMA_API IMA_STATUS IMA_DeregisterForObjectVisibilityChanges(
2903 IMA_OBJECT_VISIBILITY_FN pClientFn
2904 )
2905 {
2906 return (IMA_STATUS_SUCCESS);
2907 }
2908
2909 /* ARGSUSED */
IMA_GetNetworkPortStatus(IMA_OID portOid,IMA_NETWORK_PORT_STATUS * pStaus)2910 IMA_API IMA_STATUS IMA_GetNetworkPortStatus(
2911 IMA_OID portOid,
2912 IMA_NETWORK_PORT_STATUS *pStaus
2913 )
2914 {
2915 return (IMA_ERROR_OBJECT_NOT_FOUND);
2916 }
2917
2918 /* ARGSUSED */
IMA_GetNetworkPortalOidList(IMA_OID pnpOid,IMA_OID_LIST ** ppList)2919 IMA_API IMA_STATUS IMA_GetNetworkPortalOidList(
2920 IMA_OID pnpOid,
2921 IMA_OID_LIST **ppList
2922 )
2923 {
2924 return (IMA_ERROR_OBJECT_NOT_FOUND);
2925 }
2926
2927 /* ARGSUSED */
IMA_GetNetworkPortalProperties(IMA_OID networkPortalOid,IMA_NETWORK_PORTAL_PROPERTIES * pProps)2928 IMA_API IMA_STATUS IMA_GetNetworkPortalProperties(
2929 IMA_OID networkPortalOid,
2930 IMA_NETWORK_PORTAL_PROPERTIES *pProps
2931 )
2932 {
2933 return (IMA_ERROR_OBJECT_NOT_FOUND);
2934 }
2935
2936 /* ARGSUSED */
IMA_SetNetworkPortalIpAddress(IMA_OID networkPortalOid,const IMA_IP_ADDRESS NewIpAddress)2937 IMA_API IMA_STATUS IMA_SetNetworkPortalIpAddress(
2938 IMA_OID networkPortalOid,
2939 const IMA_IP_ADDRESS NewIpAddress
2940 )
2941 {
2942 return (IMA_ERROR_OBJECT_NOT_FOUND);
2943 }
2944
2945 /* ARGSUSED */
IMA_RemoveStaleData(IMA_OID lhbaOid)2946 IMA_API IMA_STATUS IMA_RemoveStaleData(
2947 IMA_OID lhbaOid
2948 )
2949 {
2950 return (IMA_ERROR_NOT_SUPPORTED);
2951 }
2952
2953 /* ARGSUSED */
IMA_GetIpsecProperties(IMA_OID oid,IMA_IPSEC_PROPERTIES * pProps)2954 IMA_API IMA_STATUS IMA_GetIpsecProperties(
2955 IMA_OID oid,
2956 IMA_IPSEC_PROPERTIES *pProps
2957 )
2958 {
2959 pProps->ipsecSupported = IMA_TRUE;
2960 pProps->implementedInHardware = IMA_FALSE;
2961 pProps->implementedInSoftware = IMA_TRUE;
2962
2963 return (IMA_STATUS_SUCCESS);
2964 }
2965
2966 /* ARGSUSED */
IMA_GetLhbaProperties(IMA_OID lhbaOid,IMA_LHBA_PROPERTIES * pProps)2967 IMA_API IMA_STATUS IMA_GetLhbaProperties(
2968 IMA_OID lhbaOid,
2969 IMA_LHBA_PROPERTIES *pProps
2970 )
2971 {
2972
2973 if (pProps == NULL) {
2974 return (IMA_ERROR_INVALID_PARAMETER);
2975 }
2976
2977 if (lhbaObjectId.objectSequenceNumber != ISCSI_INITIATOR_OID) {
2978 return (IMA_ERROR_OBJECT_NOT_FOUND);
2979 }
2980
2981 (void) memset(pProps, 0, sizeof (IMA_LHBA_PROPERTIES));
2982 (void) mbstowcs(pProps->osDeviceName, OS_DEVICE_NAME,
2983 OS_DEVICE_NAME_LEN);
2984 pProps->luExposingSupported = IMA_FALSE;
2985 pProps->isDestroyable = IMA_FALSE;
2986 pProps->staleDataRemovable = IMA_FALSE;
2987 pProps->staleDataSize = 0;
2988 pProps->initiatorAuthMethodsSettable = IMA_TRUE;
2989 pProps->targetAuthMethodsSettable = IMA_FALSE;
2990
2991 return (IMA_STATUS_SUCCESS);
2992 }
2993
IMA_GetLnpOidList(IMA_OID_LIST ** ppList)2994 IMA_API IMA_STATUS IMA_GetLnpOidList(
2995 IMA_OID_LIST **ppList
2996 )
2997 {
2998 *ppList = (IMA_OID_LIST *) calloc(1, (sizeof (IMA_OID_LIST)));
2999 if (*ppList == NULL) {
3000 return (IMA_ERROR_INSUFFICIENT_MEMORY);
3001 }
3002 (*ppList)->oidCount = 0;
3003
3004 return (IMA_STATUS_SUCCESS);
3005 }
3006
3007 /* ARGSUSED */
IMA_GetLnpProperties(IMA_OID lnpOid,IMA_LNP_PROPERTIES * pProps)3008 IMA_API IMA_STATUS IMA_GetLnpProperties(
3009 IMA_OID lnpOid,
3010 IMA_LNP_PROPERTIES *pProps
3011 )
3012 {
3013 return (IMA_ERROR_OBJECT_NOT_FOUND);
3014 }
3015
3016 #define IMA_DISK_DEVICE_NAME_PREFIX "/dev/rdsk/"
3017 #define IMA_TAPE_DEVICE_NAME_PREFIX "/dev/rmt/"
3018 static int
get_lun_devlink(di_devlink_t link,void * osDeviceName)3019 get_lun_devlink(di_devlink_t link, void *osDeviceName)
3020 {
3021 if ((strncmp(IMA_DISK_DEVICE_NAME_PREFIX, di_devlink_path(link),
3022 strlen(IMA_DISK_DEVICE_NAME_PREFIX)) == 0) ||
3023 (strncmp(IMA_TAPE_DEVICE_NAME_PREFIX, di_devlink_path(link),
3024 strlen(IMA_TAPE_DEVICE_NAME_PREFIX)) == 0)) {
3025 (void) mbstowcs((wchar_t *)osDeviceName, di_devlink_path(link),
3026 MAXPATHLEN);
3027 return (DI_WALK_TERMINATE);
3028 }
3029
3030 return (DI_WALK_CONTINUE);
3031 }
3032
3033 /* ARGSUSED */
IMA_GetPluginProperties(IMA_OID pluginOid,IMA_PLUGIN_PROPERTIES * pProps)3034 IMA_API IMA_STATUS IMA_GetPluginProperties(
3035 IMA_OID pluginOid,
3036 IMA_PLUGIN_PROPERTIES *pProps
3037 )
3038 {
3039 pProps->supportedImaVersion = 1;
3040 libSwprintf(pProps->vendor, L"%ls", LIBRARY_PROPERTY_VENDOR);
3041 libSwprintf(pProps->implementationVersion, L"%ls",
3042 LIBRARY_PROPERTY_IMPLEMENTATION_VERSION);
3043 libSwprintf(pProps->fileName, L"%ls", LIBRARY_FILE_NAME);
3044 GetBuildTime(&(pProps->buildTime));
3045 pProps->lhbasCanBeCreatedAndDestroyed = IMA_FALSE;
3046 return (IMA_STATUS_SUCCESS);
3047 }
3048
getDiscoveryAddressPropertiesList(SUN_IMA_DISC_ADDR_PROP_LIST ** ppList)3049 IMA_STATUS getDiscoveryAddressPropertiesList(
3050 SUN_IMA_DISC_ADDR_PROP_LIST **ppList
3051 )
3052 {
3053 int fd;
3054 int i;
3055 int discovery_addr_list_size;
3056 iscsi_addr_list_t *ialp, al_info;
3057
3058 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
3059 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
3060 ISCSI_DRIVER_DEVCTL, errno);
3061 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3062 }
3063
3064 (void) memset(&al_info, 0, sizeof (al_info));
3065 al_info.al_vers = ISCSI_INTERFACE_VERSION;
3066 al_info.al_in_cnt = 0;
3067
3068 /*
3069 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl to obtain the number of
3070 * discovery addresses.
3071 */
3072 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) {
3073 (void) close(fd);
3074 syslog(LOG_USER|LOG_DEBUG,
3075 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d",
3076 errno);
3077 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3078 }
3079
3080 discovery_addr_list_size = sizeof (iscsi_addr_list_t);
3081 if (al_info.al_out_cnt > 1) {
3082 discovery_addr_list_size += (sizeof (iscsi_addr_t) *
3083 al_info.al_out_cnt - 1);
3084 }
3085
3086 ialp = (iscsi_addr_list_t *)calloc(1, discovery_addr_list_size);
3087 if (ialp == NULL) {
3088 (void) close(fd);
3089 return (IMA_ERROR_INSUFFICIENT_MEMORY);
3090 }
3091 ialp->al_vers = ISCSI_INTERFACE_VERSION;
3092 ialp->al_in_cnt = al_info.al_out_cnt;
3093
3094 /*
3095 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl again to obtain the
3096 * discovery addresses.
3097 */
3098 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, ialp) != 0) {
3099 free(ialp);
3100 (void) close(fd);
3101 syslog(LOG_USER|LOG_DEBUG,
3102 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d",
3103 errno);
3104 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3105 }
3106
3107 *ppList = (SUN_IMA_DISC_ADDR_PROP_LIST *)
3108 calloc(1, sizeof (SUN_IMA_DISC_ADDR_PROP_LIST) +
3109 ialp->al_out_cnt * sizeof (IMA_DISCOVERY_ADDRESS_PROPERTIES));
3110
3111 if (*ppList == NULL) {
3112 free(ialp);
3113 (void) close(fd);
3114 return (IMA_ERROR_INSUFFICIENT_MEMORY);
3115 }
3116 (*ppList)->discAddrCount = ialp->al_out_cnt;
3117
3118 for (i = 0; i < ialp->al_out_cnt; i++) {
3119 if (ialp->al_addrs[i].a_addr.i_insize ==
3120 sizeof (struct in_addr)) {
3121 (*ppList)->props[i].discoveryAddress.hostnameIpAddress.
3122 id.ipAddress.ipv4Address = IMA_TRUE;
3123 } else if (ialp->al_addrs[i].a_addr.i_insize ==
3124 sizeof (struct in6_addr)) {
3125 (*ppList)->props[i].discoveryAddress.
3126 hostnameIpAddress.id.ipAddress.ipv4Address = IMA_FALSE;
3127 } else {
3128 /* Should not happen */
3129 syslog(LOG_USER|LOG_DEBUG,
3130 "ISCSI_STATIC_GET returned bad address");
3131 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3132 }
3133
3134 bcopy(&ialp->al_addrs[i].a_addr.i_addr, (*ppList)->props[i].
3135 discoveryAddress.hostnameIpAddress.id.ipAddress.ipAddress,
3136 sizeof ((*ppList)->props[i].discoveryAddress.
3137 hostnameIpAddress.id.ipAddress.ipAddress));
3138
3139 (*ppList)->props[i].discoveryAddress.portNumber =
3140 ialp->al_addrs[i].a_port;
3141 }
3142
3143 free(ialp);
3144 (void) close(fd);
3145 return (IMA_STATUS_SUCCESS);
3146 }
3147
3148
3149 /* ARGSUSED */
sendTargets(IMA_TARGET_ADDRESS address,SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES ** ppList)3150 IMA_STATUS sendTargets(
3151 IMA_TARGET_ADDRESS address,
3152 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES **ppList
3153 )
3154 {
3155 char *colonPos;
3156 char discAddrStr[SUN_IMA_IP_ADDRESS_LEN];
3157 int fd;
3158 int ctr;
3159 int stl_sz;
3160 iscsi_sendtgts_list_t *stl_hdr = NULL;
3161 IMA_BOOL retry = IMA_TRUE;
3162
3163 #define SENDTGTS_DEFAULT_NUM_TARGETS 10
3164
3165 stl_sz = sizeof (*stl_hdr) + ((SENDTGTS_DEFAULT_NUM_TARGETS - 1) *
3166 sizeof (iscsi_sendtgts_entry_t));
3167 stl_hdr = (iscsi_sendtgts_list_t *)calloc(1, stl_sz);
3168 if (stl_hdr == NULL) {
3169 return (IMA_ERROR_INSUFFICIENT_MEMORY);
3170 }
3171 stl_hdr->stl_entry.e_vers = ISCSI_INTERFACE_VERSION;
3172 stl_hdr->stl_in_cnt = SENDTGTS_DEFAULT_NUM_TARGETS;
3173
3174 colonPos = strchr(discAddrStr, ':');
3175 if (colonPos == NULL) {
3176 /* IPv4 */
3177 stl_hdr->stl_entry.e_insize = sizeof (struct in_addr);
3178 } else {
3179 /* IPv6 */
3180 stl_hdr->stl_entry.e_insize = sizeof (struct in6_addr);
3181 }
3182
3183
3184 bcopy(address.hostnameIpAddress.id.ipAddress.ipAddress,
3185 &stl_hdr->stl_entry.e_u,
3186 sizeof (address.hostnameIpAddress.id.ipAddress.ipAddress));
3187 stl_hdr->stl_entry.e_port = address.portNumber;
3188
3189 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
3190 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
3191 ISCSI_DRIVER_DEVCTL, errno);
3192 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3193 }
3194
3195 retry_sendtgts:
3196 /*
3197 * Issue ioctl to obtain the SendTargets list
3198 */
3199 if (ioctl(fd, ISCSI_SENDTGTS_GET, stl_hdr) != 0) {
3200 syslog(LOG_USER|LOG_DEBUG,
3201 "ISCSI_SENDTGTS_GET ioctl failed, errno: %d", errno);
3202 (void) close(fd);
3203 free(stl_hdr);
3204 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3205 }
3206
3207 /* check if all targets received */
3208 if (stl_hdr->stl_in_cnt < stl_hdr->stl_out_cnt) {
3209 if (retry == IMA_TRUE) {
3210 stl_sz = sizeof (*stl_hdr) +
3211 ((stl_hdr->stl_out_cnt - 1) *
3212 sizeof (iscsi_sendtgts_entry_t));
3213 stl_hdr = (iscsi_sendtgts_list_t *)
3214 realloc(stl_hdr, stl_sz);
3215 if (stl_hdr == NULL) {
3216 (void) close(fd);
3217 return (IMA_ERROR_INSUFFICIENT_MEMORY);
3218 }
3219 stl_hdr->stl_in_cnt = stl_hdr->stl_out_cnt;
3220 retry = IMA_FALSE;
3221 goto retry_sendtgts;
3222 } else {
3223 /*
3224 * don't retry after 2 attempts. The target list
3225 * shouldn't continue to growing. Justs continue
3226 * on and display what was found.
3227 */
3228 syslog(LOG_USER|LOG_DEBUG,
3229 "ISCSI_SENDTGTS_GET overflow: "
3230 "failed to obtain all targets");
3231 stl_hdr->stl_out_cnt = stl_hdr->stl_in_cnt;
3232 }
3233 }
3234
3235 (void) close(fd);
3236
3237 /* allocate for caller return buffer */
3238 *ppList = (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *)calloc(1,
3239 sizeof (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES) +
3240 stl_hdr->stl_out_cnt * sizeof (SUN_IMA_DISC_ADDRESS_KEY));
3241 if (*ppList == NULL) {
3242 free(stl_hdr);
3243 return (IMA_ERROR_INSUFFICIENT_MEMORY);
3244 }
3245
3246 (*ppList)->keyCount = stl_hdr->stl_out_cnt;
3247
3248 for (ctr = 0; ctr < stl_hdr->stl_out_cnt; ctr++) {
3249 (void) mbstowcs((*ppList)->keys[ctr].name,
3250 (char *)stl_hdr->stl_list[ctr].ste_name,
3251 IMA_NODE_NAME_LEN);
3252
3253 (*ppList)->keys[ctr].tpgt = stl_hdr->stl_list[ctr].ste_tpgt;
3254
3255 (*ppList)->keys[ctr].address.portNumber =
3256 stl_hdr->stl_list[ctr].ste_ipaddr.a_port;
3257
3258 if (stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize ==
3259 sizeof (struct in_addr)) {
3260 (*ppList)->keys[ctr].address.ipAddress.ipv4Address =
3261 IMA_TRUE;
3262 } else if (stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize ==
3263 sizeof (struct in6_addr)) {
3264 (*ppList)->keys[ctr].address.ipAddress.ipv4Address =
3265 IMA_FALSE;
3266 } else {
3267 free(stl_hdr);
3268 syslog(LOG_USER|LOG_DEBUG,
3269 "ISCSI_STATIC_GET returned bad address");
3270 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3271 }
3272
3273
3274 (void) memcpy(&(*ppList)->keys[ctr].address.ipAddress.ipAddress,
3275 &(stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_addr),
3276 stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize);
3277 }
3278 free(stl_hdr);
3279
3280 return (IMA_STATUS_SUCCESS);
3281 }
3282
SUN_IMA_GetTunableProperties(IMA_OID oid,ISCSI_TUNABLE_PARAM * param)3283 IMA_API IMA_STATUS SUN_IMA_GetTunableProperties(
3284 IMA_OID oid,
3285 ISCSI_TUNABLE_PARAM *param)
3286 {
3287 int fd;
3288 iscsi_tunable_object_t pg;
3289
3290 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
3291 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
3292 ISCSI_DRIVER_DEVCTL, errno);
3293 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3294 }
3295 (void) memset(&pg, 0, sizeof (iscsi_tunable_object_t));
3296 pg.t_param = param->tunable_objectType;
3297 pg.t_oid = (uint32_t)oid.objectSequenceNumber;
3298 if (ioctl(fd, ISCSI_TUNABLE_PARAM_GET, &pg) == -1) {
3299 syslog(LOG_USER|LOG_DEBUG,
3300 "ISCSI_TUNABLE_PARAM_GET ioctl failed, errno: %d", errno);
3301 (void) close(fd);
3302 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3303 } else {
3304 long long value;
3305 char tmp[MAX_LONG_LONG_STRING_LEN], *ptr = NULL;
3306 if (pg.t_set == B_FALSE) {
3307 /* default value */
3308 (void) close(fd);
3309 return (IMA_STATUS_SUCCESS);
3310 }
3311 value = (long long)pg.t_value.v_integer;
3312 ptr = lltostr(value, &tmp[MAX_LONG_LONG_STRING_LEN -1]);
3313 if ((ptr != NULL) && (ptr != tmp)) {
3314 tmp[MAX_LONG_LONG_STRING_LEN - 1] = '\0';
3315 } else {
3316 (void) close(fd);
3317 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3318 }
3319 switch (param->tunable_objectType) {
3320 case ISCSI_RX_TIMEOUT_VALUE:
3321 (void) strlcpy(param->tunable_objectValue,
3322 ptr, strlen(ptr) + 1);
3323 break;
3324 case ISCSI_CONN_DEFAULT_LOGIN_MAX:
3325 (void) strlcpy(param->tunable_objectValue,
3326 ptr, strlen(ptr) + 1);
3327 break;
3328 case ISCSI_LOGIN_POLLING_DELAY:
3329 (void) strlcpy(param->tunable_objectValue,
3330 ptr, strlen(ptr) + 1);
3331 break;
3332 default:
3333 break;
3334 }
3335 }
3336 (void) close(fd);
3337 return (IMA_STATUS_SUCCESS);
3338 }
3339
SUN_IMA_SetTunableProperties(IMA_OID oid,ISCSI_TUNABLE_PARAM * param)3340 IMA_API IMA_STATUS SUN_IMA_SetTunableProperties(
3341 IMA_OID oid,
3342 ISCSI_TUNABLE_PARAM *param)
3343 {
3344 int fd;
3345 iscsi_tunable_object_t ps;
3346
3347 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
3348 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
3349 ISCSI_DRIVER_DEVCTL, errno);
3350 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3351 }
3352
3353 (void) memset(&ps, 0, sizeof (iscsi_tunable_object_t));
3354 ps.t_oid = oid.objectSequenceNumber;
3355 ps.t_param = param->tunable_objectType;
3356 switch (param->tunable_objectType) {
3357 long tmp;
3358 case ISCSI_RX_TIMEOUT_VALUE:
3359 case ISCSI_CONN_DEFAULT_LOGIN_MAX:
3360 case ISCSI_LOGIN_POLLING_DELAY:
3361 tmp = strtol(param->tunable_objectValue,
3362 NULL, 10);
3363 if (((tmp == 0) && (errno == EINVAL)) ||
3364 ((tmp == LONG_MAX) && (errno == ERANGE)) ||
3365 ((tmp == LONG_MIN) && (errno == ERANGE))) {
3366 (void) close(fd);
3367 return (IMA_ERROR_INVALID_PARAMETER);
3368 }
3369 ps.t_value.v_integer = (uint32_t)tmp;
3370 break;
3371 default:
3372 break;
3373 }
3374 if (ioctl(fd, ISCSI_TUNABLE_PARAM_SET, &ps)) {
3375 int tmpErrno = errno;
3376 syslog(LOG_USER|LOG_DEBUG,
3377 "ISCSI_TUNABLE_PARAM_SET ioctl failed, errno: %d", errno);
3378 (void) close(fd);
3379 switch (tmpErrno) {
3380 case ENOTSUP :
3381 return (IMA_ERROR_NOT_SUPPORTED);
3382 default:
3383 return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3384 }
3385 }
3386 (void) close(fd);
3387 return (IMA_STATUS_SUCCESS);
3388 }
3389