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 src/sun_nws/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 src/sun_nws/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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 #pragma ident "@(#)ima.c 1.7 08/05/23 SMI" 26 27 #include <arpa/inet.h> 28 #include <sys/socket.h> 29 #include <sys/types.h> 30 #include <stdarg.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <strings.h> 34 #include <unistd.h> 35 #include <syslog.h> 36 #include <errno.h> 37 #include <wchar.h> 38 #include <widec.h> 39 #include <libsysevent.h> 40 #include <sys/nvpair.h> 41 #include <fcntl.h> 42 #include <stdio.h> 43 #include <time.h> 44 #include <libdevinfo.h> 45 #include <iscsi_if.h> 46 #include <iscsi_protocol.h> 47 #include <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 67 /* Forward declaration */ 68 #define BOOL_PARAM 1 69 #define MIN_MAX_PARAM 2 70 71 /* OK */ 72 #define DISC_ADDR_OK 0 73 /* Incorrect IP address */ 74 #define DISC_ADDR_INTEGRITY_ERROR 1 75 /* Error converting text IP address to numeric binary form */ 76 #define DISC_ADDR_IP_CONV_ERROR 2 77 78 /* Currently not defined in IMA_TARGET_DISCOVERY_METHOD enum */ 79 #define IMA_TARGET_DISCOVERY_METHOD_UNKNOWN 0 80 81 static IMA_OID lhbaObjectId; 82 static IMA_UINT32 pluginOwnerId; 83 static sysevent_handle_t *shp; 84 85 86 87 /* 88 * Custom struct to allow tgpt to be specified. 89 */ 90 typedef struct _SUN_IMA_DISC_ADDRESS_KEY 91 { 92 IMA_NODE_NAME name; 93 IMA_ADDRESS_KEY address; 94 IMA_UINT16 tpgt; 95 } SUN_IMA_DISC_ADDRESS_KEY; 96 97 /* 98 * Custom struct to allow tgpt to be specified. 99 */ 100 typedef struct _SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES 101 { 102 IMA_UINT keyCount; 103 SUN_IMA_DISC_ADDRESS_KEY keys[1]; 104 } SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES; 105 106 /* 107 * Custom struct to allow tgpt to be specified. 108 */ 109 typedef struct _SUN_IMA_DISC_ADDR_PROP_LIST 110 { 111 IMA_UINT discAddrCount; 112 IMA_DISCOVERY_ADDRESS_PROPERTIES props[1]; 113 } SUN_IMA_DISC_ADDR_PROP_LIST; 114 115 116 static IMA_OBJECT_VISIBILITY_FN pObjectVisibilityCallback = NULL; 117 static IMA_OBJECT_PROPERTY_FN pObjectPropertyCallback = NULL; 118 119 static IMA_STATUS getISCSINodeParameter(int paramType, IMA_OID *oid, 120 void *pProps, uint32_t paramIndex); 121 static IMA_STATUS setISCSINodeParameter(int paramType, IMA_OID *oid, 122 void *pProps, uint32_t paramIndex); 123 static IMA_STATUS setAuthMethods(IMA_OID oid, IMA_UINT *pMethodCount, 124 const IMA_AUTHMETHOD *pMethodList); 125 static IMA_STATUS getAuthMethods(IMA_OID oid, IMA_UINT *pMethodCount, 126 IMA_AUTHMETHOD *pMethodList); 127 128 static int prepare_discovery_entry(IMA_TARGET_ADDRESS discoveryAddress, 129 entry_t *entry); 130 static IMA_STATUS configure_discovery_method(IMA_BOOL enable, 131 iSCSIDiscoveryMethod_t method); 132 static IMA_STATUS get_target_oid_list(uint32_t targetListType, 133 IMA_OID_LIST **ppList); 134 static IMA_STATUS get_target_lun_oid_list(IMA_OID * targetOid, 135 iscsi_lun_list_t **ppLunList); 136 static int get_lun_devlink(di_devlink_t link, void *osDeviceName); 137 static IMA_STATUS getDiscoveryAddressPropertiesList( 138 SUN_IMA_DISC_ADDR_PROP_LIST **ppList 139 ); 140 static IMA_STATUS sendTargets(IMA_TARGET_ADDRESS address, 141 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES **ppList 142 ); 143 144 static IMA_STATUS getSupportedAuthMethods(IMA_OID lhbaOid, 145 IMA_BOOL getSettableMethods, IMA_UINT *pMethodCount, 146 IMA_AUTHMETHOD *pMethodList); 147 static IMA_STATUS getLuProperties(IMA_OID luId, IMA_LU_PROPERTIES *pProps); 148 static IMA_STATUS getTargetProperties(IMA_OID targetId, 149 IMA_TARGET_PROPERTIES *pProps); 150 151 void InitLibrary(); 152 153 static void libSwprintf(wchar_t *wcs, const wchar_t *lpszFormat, ...) 154 { 155 va_list args; 156 va_start(args, lpszFormat); 157 vswprintf(wcs, OS_DEVICE_NAME_LEN - 1, lpszFormat, args); 158 va_end(args); 159 } 160 161 static void 162 sysevent_handler(sysevent_t *ev) 163 { 164 IMA_OID tmpOid; 165 IMA_BOOL becomingVisible = IMA_FALSE; 166 IMA_UINT i; 167 168 const char *visibility_subclasses[] = { 169 ESC_ISCSI_STATIC_START, 170 ESC_ISCSI_STATIC_END, 171 ESC_ISCSI_SEND_TARGETS_START, 172 ESC_ISCSI_SEND_TARGETS_END, 173 ESC_ISCSI_SLP_START, 174 ESC_ISCSI_SLP_END, 175 ESC_ISCSI_ISNS_START, 176 ESC_ISCSI_ISNS_END, 177 NULL 178 }; 179 180 tmpOid.ownerId = pluginOwnerId; 181 tmpOid.objectType = IMA_OBJECT_TYPE_TARGET; 182 tmpOid.objectSequenceNumber = 0; 183 184 /* Make sure our event class matches what we are looking for */ 185 if (strncmp(EC_ISCSI, sysevent_get_class_name(ev), 186 strlen(EC_ISCSI)) != 0) { 187 return; 188 } 189 190 191 /* Check for object property changes */ 192 if ((strncmp(ESC_ISCSI_PROP_CHANGE, 193 sysevent_get_subclass_name(ev), 194 strlen(ESC_ISCSI_PROP_CHANGE)) == 0)) { 195 if (pObjectPropertyCallback != NULL) 196 pObjectPropertyCallback(tmpOid); 197 } else { 198 i = 0; 199 while (visibility_subclasses[i] != NULL) { 200 if ((strncmp(visibility_subclasses[i], 201 sysevent_get_subclass_name(ev), 202 strlen(visibility_subclasses[i])) == 0) && 203 pObjectVisibilityCallback != NULL) { 204 becomingVisible = IMA_TRUE; 205 pObjectVisibilityCallback(becomingVisible, 206 tmpOid); 207 } 208 i++; 209 } 210 } 211 } 212 213 IMA_STATUS init_sysevents() { 214 const char *subclass_list[] = { 215 ESC_ISCSI_STATIC_START, 216 ESC_ISCSI_STATIC_END, 217 ESC_ISCSI_SEND_TARGETS_START, 218 ESC_ISCSI_SEND_TARGETS_END, 219 ESC_ISCSI_SLP_START, 220 ESC_ISCSI_SLP_END, 221 ESC_ISCSI_ISNS_START, 222 ESC_ISCSI_ISNS_END, 223 ESC_ISCSI_PROP_CHANGE, 224 }; 225 226 /* Bind event handler and create subscriber handle */ 227 shp = sysevent_bind_handle(sysevent_handler); 228 if (shp == NULL) { 229 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 230 } 231 232 if (sysevent_subscribe_event(shp, EC_ISCSI, subclass_list, 9) != 0) { 233 sysevent_unbind_handle(shp); 234 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 235 } 236 return (IMA_STATUS_SUCCESS); 237 } 238 239 IMA_STATUS Initialize(IMA_UINT32 pluginOid) { 240 pluginOwnerId = pluginOid; 241 return (init_sysevents()); 242 } 243 244 void Terminate() { 245 if (shp != NULL) { 246 sysevent_unsubscribe_event(shp, EC_ISCSI); 247 } 248 249 } 250 251 void InitLibrary() { 252 } 253 254 static void GetBuildTime(IMA_DATETIME* pdatetime) 255 { 256 memset(pdatetime, 0, sizeof (IMA_DATETIME)); 257 } 258 259 /*ARGSUSED*/ 260 IMA_API IMA_STATUS IMA_GetNodeProperties( 261 IMA_OID nodeOid, 262 IMA_NODE_PROPERTIES *pProps 263 ) 264 { 265 int fd; 266 iscsi_param_get_t pg; 267 268 pProps->runningInInitiatorMode = IMA_TRUE; 269 pProps->runningInTargetMode = IMA_FALSE; 270 pProps->nameAndAliasSettable = IMA_FALSE; 271 272 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 273 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 274 ISCSI_DRIVER_DEVCTL, errno); 275 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 276 } 277 278 memset(&pg, 0, sizeof (iscsi_param_get_t)); 279 pg.g_vers = ISCSI_INTERFACE_VERSION; 280 pg.g_param = ISCSI_LOGIN_PARAM_INITIATOR_NAME; 281 282 if (ioctl(fd, ISCSI_PARAM_GET, &pg) == -1) { 283 pProps->nameValid = IMA_FALSE; 284 } else { 285 if (strlen((char *)pg.g_value.v_name) > 0) { 286 mbstowcs(pProps->name, 287 (char *)pg.g_value.v_name, 288 IMA_NODE_NAME_LEN); 289 pProps->nameValid = IMA_TRUE; 290 } else { 291 pProps->nameValid = IMA_FALSE; 292 } 293 } 294 295 memset(&pg, 0, sizeof (iscsi_param_get_t)); 296 pg.g_vers = ISCSI_INTERFACE_VERSION; 297 pg.g_param = ISCSI_LOGIN_PARAM_INITIATOR_ALIAS; 298 memset(pProps->alias, 0, 299 sizeof (IMA_WCHAR) * IMA_NODE_ALIAS_LEN); 300 if (ioctl(fd, ISCSI_PARAM_GET, &pg) == -1) { 301 pProps->aliasValid = IMA_FALSE; 302 } else { 303 if (strlen((char *)pg.g_value.v_name) > 0) { 304 mbstowcs(pProps->alias, 305 (char *)pg.g_value.v_name, 306 IMA_NODE_ALIAS_LEN); 307 pProps->aliasValid = IMA_TRUE; 308 } 309 } 310 311 close(fd); 312 return (IMA_STATUS_SUCCESS); 313 } 314 315 IMA_API IMA_STATUS IMA_SetNodeName( 316 IMA_OID nodeOid, 317 const IMA_NODE_NAME newName 318 ) 319 { 320 int fd; 321 iscsi_param_set_t ps; 322 323 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 324 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 325 ISCSI_DRIVER_DEVCTL, errno); 326 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 327 } 328 329 memset(&ps, 0, sizeof (iscsi_param_set_t)); 330 ps.s_oid = nodeOid.objectSequenceNumber; 331 ps.s_vers = ISCSI_INTERFACE_VERSION; 332 ps.s_param = ISCSI_LOGIN_PARAM_INITIATOR_NAME; 333 wcstombs((char *)ps.s_value.v_name, newName, ISCSI_MAX_NAME_LEN); 334 if (ioctl(fd, ISCSI_INIT_NODE_NAME_SET, &ps)) { 335 syslog(LOG_USER|LOG_DEBUG, 336 "ISCSI_PARAM_SET ioctl failed, errno: %d", errno); 337 close(fd); 338 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 339 } 340 341 close(fd); 342 return (IMA_STATUS_SUCCESS); 343 } 344 345 IMA_API IMA_STATUS IMA_SetNodeAlias( 346 IMA_OID nodeOid, 347 const IMA_NODE_ALIAS newAlias 348 ) 349 { 350 int fd; 351 iscsi_param_set_t ps; 352 353 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 354 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 355 ISCSI_DRIVER_DEVCTL, errno); 356 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 357 } 358 359 memset(&ps, 0, sizeof (iscsi_param_set_t)); 360 ps.s_oid = nodeOid.objectSequenceNumber; 361 ps.s_vers = ISCSI_INTERFACE_VERSION; 362 ps.s_param = ISCSI_LOGIN_PARAM_INITIATOR_ALIAS; 363 364 /* newAlias = NULL specifies that the alias should be deleted. */ 365 if (newAlias != NULL) 366 wcstombs((char *)ps.s_value.v_name, newAlias, 367 ISCSI_MAX_NAME_LEN); 368 else 369 wcstombs((char *)ps.s_value.v_name, L"", ISCSI_MAX_NAME_LEN); 370 371 if (ioctl(fd, ISCSI_PARAM_SET, &ps)) { 372 syslog(LOG_USER|LOG_DEBUG, 373 "ISCSI_PARAM_SET ioctl failed, errno: %d", errno); 374 close(fd); 375 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 376 } 377 378 close(fd); 379 return (IMA_STATUS_SUCCESS); 380 } 381 382 383 IMA_API IMA_STATUS IMA_GetLhbaOidList( 384 IMA_OID_LIST **ppList 385 ) 386 { 387 /* Always return the same object ID for the lhba */ 388 lhbaObjectId.objectType = IMA_OBJECT_TYPE_LHBA; 389 lhbaObjectId.ownerId = pluginOwnerId; 390 lhbaObjectId.objectSequenceNumber = ISCSI_INITIATOR_OID; 391 392 *ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST)); 393 if (*ppList == NULL) { 394 return (IMA_ERROR_INSUFFICIENT_MEMORY); 395 } 396 397 (*ppList)->oidCount = 1; 398 memcpy(&(*ppList)->oids[0], &lhbaObjectId, sizeof (lhbaObjectId)); 399 return (IMA_STATUS_SUCCESS); 400 } 401 402 403 /* 404 * Get the discovery properties of the LHBA 405 */ 406 /*ARGSUSED*/ 407 IMA_API IMA_STATUS IMA_GetDiscoveryProperties( 408 IMA_OID oid, 409 IMA_DISCOVERY_PROPERTIES *pProps 410 ) 411 { 412 int fd; 413 iSCSIDiscoveryProperties_t discoveryProps; 414 415 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 416 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 417 ISCSI_DRIVER_DEVCTL, errno); 418 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 419 } 420 421 memset(&discoveryProps, 0, sizeof (discoveryProps)); 422 discoveryProps.vers = ISCSI_INTERFACE_VERSION; 423 424 if (ioctl(fd, ISCSI_DISCOVERY_PROPS, &discoveryProps) != 0) { 425 syslog(LOG_USER|LOG_DEBUG, 426 "ISCSI_DISCOVERY_PROPS ioctl failed, errno: %d", errno); 427 close(fd); 428 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 429 } 430 431 pProps->iSnsDiscoverySettable = discoveryProps.iSNSDiscoverySettable; 432 pProps->iSnsDiscoveryEnabled = discoveryProps.iSNSDiscoveryEnabled; 433 /* 434 * Set the iSNS discovery method - The IMA specification indicates 435 * this field is valid only if iSNS discovery is enabled. 436 */ 437 if (pProps->iSnsDiscoveryEnabled == IMA_TRUE) { 438 switch (discoveryProps.iSNSDiscoveryMethod) { 439 case iSNSDiscoveryMethodStatic: 440 pProps->iSnsDiscoveryMethod = 441 IMA_ISNS_DISCOVERY_METHOD_STATIC; 442 break; 443 case iSNSDiscoveryMethodDHCP: 444 pProps->iSnsDiscoveryMethod = 445 IMA_ISNS_DISCOVERY_METHOD_DHCP; 446 break; 447 case iSNSDiscoveryMethodSLP: 448 pProps->iSnsDiscoveryMethod = 449 IMA_ISNS_DISCOVERY_METHOD_SLP; 450 break; 451 default: 452 close(fd); 453 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 454 } 455 } 456 memcpy(pProps->iSnsHost.id.hostname, discoveryProps.iSNSDomainName, 457 sizeof (pProps->iSnsHost.id.hostname)); 458 pProps->slpDiscoverySettable = discoveryProps.SLPDiscoverySettable; 459 pProps->slpDiscoveryEnabled = discoveryProps.SLPDiscoveryEnabled; 460 pProps->staticDiscoverySettable = 461 discoveryProps.StaticDiscoverySettable; 462 pProps->staticDiscoveryEnabled = discoveryProps.StaticDiscoveryEnabled; 463 pProps->sendTargetsDiscoverySettable = 464 discoveryProps.SendTargetsDiscoverySettable; 465 pProps->sendTargetsDiscoveryEnabled = 466 discoveryProps.SendTargetsDiscoveryEnabled; 467 468 close(fd); 469 return (IMA_STATUS_SUCCESS); 470 } 471 472 IMA_API IMA_STATUS IMA_FreeMemory( 473 void *pMemory 474 ) 475 { 476 if (pMemory != NULL) 477 free(pMemory); 478 return (IMA_STATUS_SUCCESS); 479 } 480 481 IMA_API IMA_STATUS IMA_GetNonSharedNodeOidList( 482 IMA_OID_LIST **ppList 483 ) 484 { 485 if (ppList == NULL) 486 return (IMA_ERROR_INVALID_PARAMETER); 487 488 *ppList = (IMA_OID_LIST*) calloc(1, sizeof (IMA_OID_LIST)); 489 if (*ppList == NULL) { 490 return (IMA_ERROR_INSUFFICIENT_MEMORY); 491 } 492 (*ppList)->oidCount = 0; 493 494 return (IMA_STATUS_SUCCESS); 495 } 496 497 IMA_API IMA_STATUS IMA_GetFirstBurstLengthProperties( 498 IMA_OID Oid, 499 IMA_MIN_MAX_VALUE *pProps 500 ) 501 { 502 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps, 503 ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH)); 504 } 505 506 IMA_API IMA_STATUS IMA_GetMaxBurstLengthProperties( 507 IMA_OID Oid, 508 IMA_MIN_MAX_VALUE *pProps 509 ) 510 { 511 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps, 512 ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH)); 513 } 514 515 IMA_API IMA_STATUS IMA_GetMaxRecvDataSegmentLengthProperties( 516 IMA_OID Oid, 517 IMA_MIN_MAX_VALUE *pProps 518 ) 519 { 520 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps, 521 ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH)); 522 } 523 524 /*ARGSUSED*/ 525 IMA_API IMA_STATUS IMA_PluginIOCtl( 526 IMA_OID pluginOid, 527 IMA_UINT command, 528 const void *pInputBuffer, 529 IMA_UINT inputBufferLength, 530 void *pOutputBuffer, 531 IMA_UINT *pOutputBufferLength 532 ) 533 { 534 return (IMA_ERROR_NOT_SUPPORTED); 535 } 536 537 IMA_API IMA_STATUS IMA_SetFirstBurstLength( 538 IMA_OID lhbaId, 539 IMA_UINT firstBurstLength 540 ) 541 { 542 IMA_MIN_MAX_VALUE mv; 543 544 mv.currentValue = firstBurstLength; 545 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 546 ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH)); 547 } 548 549 IMA_API IMA_STATUS IMA_SetMaxBurstLength( 550 IMA_OID lhbaId, 551 IMA_UINT maxBurstLength 552 ) 553 { 554 IMA_MIN_MAX_VALUE mv; 555 556 mv.currentValue = maxBurstLength; 557 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 558 ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH)); 559 } 560 561 IMA_API IMA_STATUS IMA_SetMaxRecvDataSegmentLength( 562 IMA_OID lhbaId, 563 IMA_UINT maxRecvDataSegmentLength 564 ) 565 { 566 IMA_MIN_MAX_VALUE mv; 567 568 mv.currentValue = maxRecvDataSegmentLength; 569 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 570 ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH)); 571 } 572 573 IMA_API IMA_STATUS IMA_GetMaxConnectionsProperties( 574 IMA_OID Oid, 575 IMA_MIN_MAX_VALUE *pProps 576 ) 577 { 578 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps, 579 ISCSI_LOGIN_PARAM_MAX_CONNECTIONS)); 580 } 581 582 IMA_API IMA_STATUS IMA_SetMaxConnections( 583 IMA_OID lhbaId, 584 IMA_UINT maxConnections 585 ) 586 { 587 IMA_MIN_MAX_VALUE mv; 588 589 mv.currentValue = maxConnections; 590 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 591 ISCSI_LOGIN_PARAM_MAX_CONNECTIONS)); 592 } 593 594 IMA_API IMA_STATUS IMA_GetDefaultTime2RetainProperties( 595 IMA_OID lhbaId, 596 IMA_MIN_MAX_VALUE *pProps 597 ) 598 { 599 return (getISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, pProps, 600 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN)); 601 } 602 603 IMA_API IMA_STATUS IMA_SetDefaultTime2Retain( 604 IMA_OID lhbaId, 605 IMA_UINT defaultTime2Retain 606 ) 607 { 608 IMA_MIN_MAX_VALUE mv; 609 610 mv.currentValue = defaultTime2Retain; 611 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 612 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN)); 613 } 614 615 IMA_API IMA_STATUS IMA_GetDefaultTime2WaitProperties( 616 IMA_OID lhbaId, 617 IMA_MIN_MAX_VALUE *pProps 618 ) 619 { 620 return (getISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, pProps, 621 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT)); 622 } 623 624 IMA_API IMA_STATUS IMA_SetDefaultTime2Wait( 625 IMA_OID lhbaId, 626 IMA_UINT defaultTime2Wait 627 ) 628 { 629 IMA_MIN_MAX_VALUE mv; 630 631 mv.currentValue = defaultTime2Wait; 632 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 633 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT)); 634 } 635 636 IMA_API IMA_STATUS IMA_GetMaxOutstandingR2TProperties( 637 IMA_OID Oid, 638 IMA_MIN_MAX_VALUE *pProps 639 ) 640 { 641 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps, 642 ISCSI_LOGIN_PARAM_OUTSTANDING_R2T)); 643 } 644 645 IMA_API IMA_STATUS IMA_SetMaxOutstandingR2T( 646 IMA_OID lhbaId, 647 IMA_UINT maxOutstandingR2T 648 ) 649 { 650 IMA_MIN_MAX_VALUE mv; 651 652 mv.currentValue = maxOutstandingR2T; 653 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 654 ISCSI_LOGIN_PARAM_OUTSTANDING_R2T)); 655 } 656 657 658 IMA_API IMA_STATUS IMA_GetErrorRecoveryLevelProperties( 659 IMA_OID Oid, 660 IMA_MIN_MAX_VALUE *pProps 661 ) 662 { 663 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps, 664 ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL)); 665 } 666 667 IMA_API IMA_STATUS IMA_SetErrorRecoveryLevel( 668 IMA_OID Oid, 669 IMA_UINT errorRecoveryLevel 670 ) 671 { 672 IMA_MIN_MAX_VALUE mv; 673 674 mv.currentValue = errorRecoveryLevel; 675 return (setISCSINodeParameter(MIN_MAX_PARAM, &Oid, &mv, 676 ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL)); 677 } 678 679 IMA_API IMA_STATUS IMA_GetInitialR2TProperties( 680 IMA_OID Oid, 681 IMA_BOOL_VALUE *pProps 682 ) 683 { 684 return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps, 685 ISCSI_LOGIN_PARAM_INITIAL_R2T)); 686 } 687 688 IMA_API IMA_STATUS IMA_SetInitialR2T( 689 IMA_OID Oid, 690 IMA_BOOL initialR2T 691 ) 692 { 693 IMA_BOOL_VALUE bv; 694 695 bv.currentValue = initialR2T; 696 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv, 697 ISCSI_LOGIN_PARAM_INITIAL_R2T)); 698 } 699 700 701 IMA_API IMA_STATUS IMA_GetImmediateDataProperties( 702 IMA_OID Oid, 703 IMA_BOOL_VALUE *pProps 704 ) 705 { 706 return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps, 707 ISCSI_LOGIN_PARAM_IMMEDIATE_DATA)); 708 } 709 710 IMA_API IMA_STATUS IMA_SetImmediateData( 711 IMA_OID Oid, 712 IMA_BOOL immediateData 713 ) 714 { 715 IMA_BOOL_VALUE bv; 716 717 bv.currentValue = immediateData; 718 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv, 719 ISCSI_LOGIN_PARAM_IMMEDIATE_DATA)); 720 } 721 722 IMA_API IMA_STATUS IMA_GetDataPduInOrderProperties( 723 IMA_OID Oid, 724 IMA_BOOL_VALUE *pProps 725 ) 726 { 727 return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps, 728 ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER)); 729 } 730 731 IMA_API IMA_STATUS IMA_SetDataPduInOrder( 732 IMA_OID Oid, 733 IMA_BOOL dataPduInOrder 734 ) 735 { 736 IMA_BOOL_VALUE bv; 737 738 bv.currentValue = dataPduInOrder; 739 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv, 740 ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER)); 741 } 742 743 IMA_API IMA_STATUS IMA_GetDataSequenceInOrderProperties( 744 IMA_OID Oid, 745 IMA_BOOL_VALUE *pProps 746 ) 747 { 748 return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps, 749 ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER)); 750 } 751 752 IMA_API IMA_STATUS IMA_SetDataSequenceInOrder( 753 IMA_OID Oid, 754 IMA_BOOL dataSequenceInOrder 755 ) 756 { 757 IMA_BOOL_VALUE bv; 758 759 bv.currentValue = dataSequenceInOrder; 760 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv, 761 ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER)); 762 } 763 764 765 /*ARGSUSED*/ 766 IMA_API IMA_STATUS IMA_SetStatisticsCollection( 767 IMA_OID Oid, 768 IMA_BOOL enableStatisticsCollection 769 ) 770 { 771 return (IMA_ERROR_NOT_SUPPORTED); 772 } 773 774 775 /*ARGSUSED*/ 776 IMA_API IMA_STATUS IMA_GetDiscoveryAddressOidList( 777 IMA_OID Oid, 778 IMA_OID_LIST **ppList 779 ) 780 { 781 int fd, i, addr_list_size; 782 iscsi_addr_list_t *idlp, al_info; 783 784 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 785 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 786 ISCSI_DRIVER_DEVCTL, errno); 787 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 788 } 789 790 memset(&al_info, 0, sizeof (al_info)); 791 al_info.al_vers = ISCSI_INTERFACE_VERSION; 792 al_info.al_in_cnt = 0; 793 794 /* 795 * Issue ioctl to obtain the number of targets. 796 */ 797 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) { 798 syslog(LOG_USER|LOG_DEBUG, 799 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d", 800 ISCSI_DISCOVERY_ADDR_LIST_GET, errno); 801 close(fd); 802 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 803 } 804 805 addr_list_size = sizeof (iscsi_addr_list_t); 806 if (al_info.al_out_cnt > 1) { 807 addr_list_size += (sizeof (iscsi_addr_list_t) * 808 al_info.al_out_cnt - 1); 809 } 810 811 idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size); 812 if (idlp == NULL) { 813 close(fd); 814 return (IMA_ERROR_INSUFFICIENT_MEMORY); 815 } 816 817 idlp->al_vers = ISCSI_INTERFACE_VERSION; 818 idlp->al_in_cnt = al_info.al_out_cnt; 819 /* Issue the same ioctl again to obtain the OIDs. */ 820 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) { 821 syslog(LOG_USER|LOG_DEBUG, 822 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d", 823 ISCSI_DISCOVERY_ADDR_LIST_GET, errno); 824 free(idlp); 825 close(fd); 826 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 827 } 828 829 *ppList = (IMA_OID_LIST *)calloc(1, sizeof (IMA_OID_LIST) + 830 idlp->al_out_cnt * sizeof (IMA_OID)); 831 if (*ppList == NULL) { 832 free(idlp); 833 close(fd); 834 return (IMA_ERROR_INSUFFICIENT_MEMORY); 835 } 836 (*ppList)->oidCount = idlp->al_out_cnt; 837 838 for (i = 0; i < idlp->al_out_cnt; i++) { 839 (*ppList)->oids[i].objectType = 840 IMA_OBJECT_TYPE_DISCOVERY_ADDRESS; 841 (*ppList)->oids[i].ownerId = pluginOwnerId; 842 (*ppList)->oids[i].objectSequenceNumber = 843 idlp->al_addrs[i].a_oid; 844 } 845 846 free(idlp); 847 close(fd); 848 849 return (IMA_STATUS_SUCCESS); 850 } 851 852 853 /* ARGSUSED */ 854 IMA_API IMA_STATUS IMA_GetStaticDiscoveryTargetOidList( 855 IMA_OID Oid, 856 IMA_OID_LIST **ppList 857 ) 858 { 859 if (Oid.objectType == IMA_OBJECT_TYPE_PNP) { 860 return (IMA_ERROR_OBJECT_NOT_FOUND); 861 } 862 863 return (get_target_oid_list(ISCSI_STATIC_TGT_OID_LIST, ppList)); 864 } 865 866 /* ARGSUSED */ 867 IMA_API IMA_STATUS IMA_GetTargetOidList( 868 IMA_OID Oid, 869 IMA_OID_LIST **ppList 870 ) 871 { 872 return (get_target_oid_list(ISCSI_TGT_PARAM_OID_LIST, ppList)); 873 } 874 875 /*ARGSUSED*/ 876 IMA_API IMA_STATUS IMA_SetIsnsDiscovery( 877 IMA_OID phbaId, 878 IMA_BOOL enableIsnsDiscovery, 879 IMA_ISNS_DISCOVERY_METHOD discoveryMethod, 880 const IMA_HOST_ID *iSnsHost 881 ) 882 { 883 /* XXX need to set discovery Method and domaineName */ 884 return (configure_discovery_method(enableIsnsDiscovery, 885 iSCSIDiscoveryMethodISNS)); 886 } 887 888 889 /* ARGSUSED */ 890 IMA_API IMA_STATUS IMA_SetSlpDiscovery( 891 IMA_OID phbaId, 892 IMA_BOOL enableSlpDiscovery 893 ) 894 { 895 return (configure_discovery_method(enableSlpDiscovery, 896 iSCSIDiscoveryMethodSLP)); 897 } 898 899 900 /* ARGSUSED */ 901 IMA_API IMA_STATUS IMA_SetStaticDiscovery( 902 IMA_OID phbaId, 903 IMA_BOOL enableStaticDiscovery 904 ) 905 { 906 return (configure_discovery_method(enableStaticDiscovery, 907 iSCSIDiscoveryMethodStatic)); 908 } 909 910 /* ARGSUSED */ 911 IMA_API IMA_STATUS IMA_SetSendTargetsDiscovery( 912 IMA_OID phbaId, 913 IMA_BOOL enableSendTargetsDiscovery 914 ) 915 { 916 return (configure_discovery_method(enableSendTargetsDiscovery, 917 iSCSIDiscoveryMethodSendTargets)); 918 } 919 920 /*ARGSUSED*/ 921 IMA_API IMA_STATUS IMA_RemoveDiscoveryAddress( 922 IMA_OID discoveryAddressOid 923 ) 924 { 925 int status, fd, i, addr_list_size; 926 iscsi_addr_list_t *idlp, al_info; 927 iscsi_addr_t *matched_addr = NULL; 928 entry_t entry; 929 930 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 931 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 932 ISCSI_DRIVER_DEVCTL, errno); 933 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 934 } 935 936 memset(&al_info, 0, sizeof (al_info)); 937 al_info.al_vers = ISCSI_INTERFACE_VERSION; 938 al_info.al_in_cnt = 0; 939 940 /* 941 * Issue ioctl to obtain the number of discovery address. 942 */ 943 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) { 944 syslog(LOG_USER|LOG_DEBUG, 945 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d", 946 ISCSI_DISCOVERY_ADDR_LIST_GET, errno); 947 close(fd); 948 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 949 } 950 951 if (al_info.al_out_cnt == 0) { 952 return (IMA_ERROR_OBJECT_NOT_FOUND); 953 } 954 955 addr_list_size = sizeof (iscsi_addr_list_t); 956 if (al_info.al_out_cnt > 1) { 957 addr_list_size += (sizeof (iscsi_addr_list_t) * 958 al_info.al_out_cnt - 1); 959 } 960 961 idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size); 962 if (idlp == NULL) { 963 close(fd); 964 return (IMA_ERROR_INSUFFICIENT_MEMORY); 965 } 966 967 idlp->al_vers = ISCSI_INTERFACE_VERSION; 968 idlp->al_in_cnt = al_info.al_out_cnt; 969 970 /* Issue the same ioctl again to obtain the OIDs. */ 971 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) { 972 syslog(LOG_USER|LOG_DEBUG, 973 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d", 974 ISCSI_DISCOVERY_ADDR_LIST_GET, errno); 975 free(idlp); 976 close(fd); 977 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 978 } 979 980 for (i = 0; i < idlp->al_out_cnt; i++) { 981 if (discoveryAddressOid.objectSequenceNumber != 982 idlp->al_addrs[i].a_oid) 983 continue; 984 matched_addr = &(idlp->al_addrs[i]); 985 } 986 987 if (matched_addr == NULL) { 988 return (IMA_ERROR_OBJECT_NOT_FOUND); 989 } 990 991 992 memset(&entry, 0, sizeof (entry_t)); 993 entry.e_vers = ISCSI_INTERFACE_VERSION; 994 entry.e_oid = discoveryAddressOid.objectSequenceNumber; 995 if (matched_addr->a_addr.i_insize == sizeof (struct in_addr)) { 996 bcopy(&matched_addr->a_addr.i_addr.in4, 997 &entry.e_u.u_in4, sizeof (entry.e_u.u_in4)); 998 entry.e_insize = sizeof (struct in_addr); 999 } else if (matched_addr->a_addr.i_insize == sizeof (struct in6_addr)) { 1000 bcopy(&matched_addr->a_addr.i_addr.in6, 1001 &entry.e_u.u_in6, sizeof (entry.e_u.u_in6)); 1002 entry.e_insize = sizeof<