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