stmf.c revision 7beff157537d14493d525a42d33f0621b0b26217
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <strings.h>
#include <fcntl.h>
#include <unistd.h>
#include <libintl.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#include <libnvpair.h>
#include <pthread.h>
#include <syslog.h>
#include <libstmf.h>
#include <inttypes.h>
#include <store.h>
#include <locale.h>
#include <math.h>
#include <libstmf_impl.h>
#include <sys/stmf_ioctl.h>
#include <sys/stmf_sbd_ioctl.h>
#include <sys/pppt_ioctl.h>
#include <macros.h>
#define EUI "eui."
#define WWN "wwn."
#define IQN "iqn."
#define LU_ASCII_GUID_SIZE 32
#define LU_GUID_SIZE 16
#define OUI_ASCII_SIZE 6
#define HOST_ID_ASCII_SIZE 8
#define OUI_SIZE 3
#define HOST_ID_SIZE 4
#define IDENT_LENGTH_BYTE 3
/* various initial allocation values */
#define ALLOC_LU 8192
#define ALLOC_TARGET_PORT 2048
#define ALLOC_PROVIDER 64
#define ALLOC_GROUP 2048
#define ALLOC_SESSION 2048
#define ALLOC_VE 256
#define ALLOC_GRP_MEMBER 256
#define MAX_ISCSI_NAME 223
#define MAX_LU_ALIAS_SIZE 256
#define OPEN_STMF 0
#define OPEN_EXCL_STMF O_EXCL
#define OPEN_SBD 0
#define OPEN_EXCL_SBD O_EXCL
#define OPEN_PPPT 0
#define OPEN_EXCL_PPPT O_EXCL
#define LOGICAL_UNIT_TYPE 0
#define TARGET_TYPE 1
#define STMF_SERVICE_TYPE 2
#define HOST_GROUP 1
#define TARGET_GROUP 2
/* set default persistence here */
#define STMF_DEFAULT_PERSIST STMF_PERSIST_SMF
#define MAX_PROVIDER_RETRY 30
static int initializeConfig();
static int guidCompare(const void *, const void *);
static int getStmfState(stmf_state_desc_t *);
static int createDiskResource(luResourceImpl *);
static int removeGuidFromDiskStore(stmfGuid *);
static int addGuidToDiskStore(stmfGuid *, char *);
static int checkHexUpper(char *);
static int strToShift(const char *);
static int niceStrToNum(const char *, uint64_t *);
static int validateModifyDiskProp(uint32_t);
static uint8_t iGetPersistMethod();
static int groupListIoctl(stmfGroupList **, int);
static int iLoadGroupFromPs(stmfGroupList **, int);
static int setDiskGlobalProp(uint32_t, const char *);
static int viewEntryCompare(const void *, const void *);
static void deleteNonActiveLus();
static int iPersistType = 0;
/* when B_TRUE, no need to access SMF anymore. Just use iPersistType */
/*
* Open for stmf module
*
* flag - open flag (OPEN_STMF, OPEN_EXCL_STMF)
* fd - pointer to integer. On success, contains the stmf file descriptor
*/
static int
{
int ret = STMF_STATUS_ERROR;
} else {
} else {
}
}
return (ret);
}
/*
* Open for sbd module
*
* flag - open flag (OPEN_SBD, OPEN_EXCL_SBD)
* fd - pointer to integer. On success, contains the stmf file descriptor
*/
static int
{
int ret = STMF_STATUS_ERROR;
} else {
} else {
}
}
return (ret);
}
/*
* Open for pppt module
*
* flag - open flag (OPEN_PPPT, OPEN_EXCL_PPPT)
* fd - pointer to integer. On success, contains the stmf file descriptor
*/
static int
{
int ret = STMF_STATUS_ERROR;
} else {
} else {
}
}
return (ret);
}
/*
* initializeConfig
*
* This routine should be called before any ioctl requiring initialization
* which is basically everything except stmfGetState(), setStmfState() and
* stmfLoadConfig().
*/
static int
{
int ret;
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/* if we've already initialized or in the process, return success */
return (STMF_STATUS_SUCCESS);
}
ret = stmfLoadConfig();
if (ret != STMF_STATUS_SUCCESS) {
"initializeConfig:stmfLoadConfig:error(%d)", ret);
return (ret);
}
if (ret != STMF_STATUS_SUCCESS) {
"initializeConfig:stmfGetState:error(%d)", ret);
return (ret);
}
}
return (ret);
}
/*
* groupIoctl
*
*
* cmd - valid STMF ioctl group cmd
* groupName - groupName to create or delete
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int ioctlRet;
/*
* Issue ioctl to create the host group
*/
if (ioctlRet != 0) {
switch (errno) {
case EPERM:
case EACCES:
break;
default:
switch (stmfIoctl.stmf_error) {
case STMF_IOCERR_TG_EXISTS:
case STMF_IOCERR_HG_EXISTS:
break;
case STMF_IOCERR_TG_IN_USE:
case STMF_IOCERR_HG_IN_USE:
break;
case STMF_IOCERR_INVALID_HG:
case STMF_IOCERR_INVALID_TG:
break;
default:
"groupIoctl:error(%d)",
break;
}
break;
}
}
done:
return (ret);
}
/*
* groupMemberIoctl
*
*
* cmd - valid STMF ioctl group member cmd
* groupName - groupName to add to or remove from
* devid - group member to add or remove
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int ioctlRet;
devid->identLength);
/*
* Issue ioctl to add to the host group
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
switch (stmfIoctl.stmf_error) {
break;
default:
break;
}
break;
case EPERM:
case EACCES:
break;
default:
switch (stmfIoctl.stmf_error) {
break;
ret =
break;
case STMF_IOCERR_INVALID_TG:
case STMF_IOCERR_INVALID_HG:
ret =
break;
default:
"groupMemberIoctl:error"
"(%d)",
break;
}
break;
}
}
done:
return (ret);
}
/*
* qsort function
* sort on veIndex
*/
static int
{
return (1);
return (-1);
return (0);
}
/*
* guidCompare
*
* qsort function
* sort on guid
*/
static int
{
int i;
for (i = 0; i < sizeof (stmfGuid); i++) {
return (1);
return (-1);
}
return (0);
}
/*
* stmfAddToHostGroup
*
* Purpose: Adds an initiator to an existing host group
*
* hostGroupName - name of an existing host group
* hostName - name of initiator to add
*/
int
{
int ret;
int fd;
if (hostGroupName == NULL ||
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
hostName)) != STMF_STATUS_SUCCESS) {
goto done;
}
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
goto done;
}
(char *)hostName->ident);
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_EXISTS:
break;
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfAddToHostGroup:psAddHostGroupMember:error(%d)",
ret);
break;
}
done:
return (ret);
}
/*
* stmfAddToTargetGroup
*
* Purpose: Adds a local port to an existing target group
*
* targetGroupName - name of an existing target group
* targetName - name of target to add
*/
int
{
int ret;
int fd;
if (targetGroupName == NULL ||
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
goto done;
}
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
goto done;
}
(char *)targetName->ident);
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_EXISTS:
break;
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfAddToTargetGroup:psAddTargetGroupMember:"
"error(%d)", ret);
break;
}
done:
return (ret);
}
/*
* addViewEntryIoctl
*
* Purpose: Issues ioctl to add a view entry
*
* lu - Logical Unit identifier to which the view entry is added
* viewEntry - view entry to add
* init - When set to B_TRUE, we are in the init state, i.e. don't call open
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int ioctlRet;
/*
* don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
* false on input
*/
sizeof (stmfGroupName));
}
sizeof (stmfGroupName));
}
if (viewEntry->luNbrValid) {
sizeof (ioctlViewEntry.ve_lu_nbr));
}
/*
* Issue ioctl to add to the view entry
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
break;
case EACCES:
switch (stmfIoctl.stmf_error) {
break;
default:
break;
}
break;
default:
switch (stmfIoctl.stmf_error) {
break;
break;
break;
case STMF_IOCERR_INVALID_HG:
break;
case STMF_IOCERR_INVALID_TG:
break;
default:
"addViewEntryIoctl"
":error(%d)",
break;
}
break;
}
goto done;
}
/* copy lu nbr back to caller's view entry on success */
if (ioctlViewEntry.ve_lu_number_valid) {
sizeof (ioctlViewEntry.ve_lu_nbr));
}
done:
return (ret);
}
/*
* stmfAddViewEntry
*
* Purpose: Adds a view entry to a logical unit
*
* lu - guid of the logical unit to which the view entry is added
* viewEntry - view entry structure to add
*/
int
{
int ret;
int fd;
return (STMF_ERROR_INVALID_ARG);
}
/* initialize and set internal view entry */
sizeof (iViewEntry.hostGroup));
} else {
}
if (!viewEntry->allTargets) {
sizeof (iViewEntry.targetGroup));
} else {
}
if (viewEntry->luNbrValid) {
sizeof (iViewEntry.luNbr));
}
/*
* set users return view entry index valid flag to false
* in case of failure
*/
/* Check to ensure service exists */
if (psCheckService() != STMF_STATUS_SUCCESS) {
return (STMF_ERROR_SERVICE_NOT_FOUND);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* First add the view entry to the driver
*/
if (ret != STMF_STATUS_SUCCESS) {
goto done;
}
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
goto done;
}
/*
* If the add to driver was successful, add it to the persistent
* store.
*/
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfAddViewEntry:psAddViewEntry:error(%d)", ret);
break;
}
done:
if (ret == STMF_STATUS_SUCCESS) {
/* set caller's view entry on success */
sizeof (iViewEntry.luNbr));
}
return (ret);
}
/*
* stmfClearProviderData
*
* Purpose: delete all provider data for specified provider
*
* providerName - name of provider for which data should be deleted
*/
int
{
int ret;
int fd;
int ioctlRet;
int savedErrno;
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
if (providerName == NULL) {
return (STMF_ERROR_INVALID_ARG);
}
if (providerType != STMF_LU_PROVIDER_TYPE &&
return (STMF_ERROR_INVALID_ARG);
}
/*
* Open control node for stmf
*/
return (ret);
switch (providerType) {
case STMF_LU_PROVIDER_TYPE:
break;
case STMF_PORT_PROVIDER_TYPE:
break;
default:
goto done;
}
if (ioctlRet != 0) {
savedErrno = errno;
switch (savedErrno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"stmfClearProviderData:ioctl error(%d)",
ioctlRet);
break;
}
if (savedErrno != ENOENT) {
goto done;
}
}
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
goto done;
}
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfClearProviderData:psClearProviderData"
":error(%d)", ret);
break;
}
done:
return (ret);
}
/*
* stmfCreateHostGroup
*
* Purpose: Create a new initiator group
*
* hostGroupName - name of host group to create
*/
int
{
int ret;
int fd;
if (hostGroupName == NULL ||
== sizeof (stmfGroupName))) {
return (STMF_ERROR_INVALID_ARG);
}
/* Check to ensure service exists */
if (psCheckService() != STMF_STATUS_SUCCESS) {
return (STMF_ERROR_SERVICE_NOT_FOUND);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
hostGroupName)) != STMF_STATUS_SUCCESS) {
goto done;
}
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
goto done;
}
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_EXISTS:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfCreateHostGroup:psCreateHostGroup:error(%d)",
ret);
break;
}
done:
return (ret);
}
/*
* stmfCreateLu
*
* Purpose: Create a logical unit
*
* hdl - handle to logical unit resource created via stmfCreateLuResource
*
* luGuid - If non-NULL, on success, contains the guid of the created logical
* unit
*/
int
{
int ret = STMF_STATUS_SUCCESS;
return (STMF_ERROR_INVALID_ARG);
}
luGuid);
} else {
return (STMF_ERROR_INVALID_ARG);
}
return (ret);
}
/*
* stmfCreateLuResource
*
* Purpose: Create resource handle for a logical unit
*
* dType - Type of logical unit resource to create
* Can be: STMF_DISK
*
* hdl - pointer to luResource
*/
int
{
int ret = STMF_STATUS_SUCCESS;
return (STMF_ERROR_INVALID_ARG);
}
return (STMF_ERROR_NOMEM);
}
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
return (STMF_STATUS_SUCCESS);
}
/*
* Creates a disk logical unit
*
* disk - pointer to diskResource structure that represents the properties
* for the disk logical unit to be created.
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int dataFileNameLen = 0;
int metaFileNameLen = 0;
int serialNumLen = 0;
int luAliasLen = 0;
int luMgmtUrlLen = 0;
int sluBufSize = 0;
int bufOffset = 0;
int fd = 0;
int ioctlRet;
int savedErrno;
stmf_iocdata_t sbdIoctl = {0};
/*
* Open control node for sbd
*/
return (ret);
/* data file name must be specified */
if (disk->luDataFileNameValid) {
} else {
return (STMF_ERROR_MISSING_PROP_VAL);
}
if (disk->luMetaFileNameValid) {
}
if (disk->luAliasValid) {
}
if (disk->luMgmtUrlValid) {
}
/*
* 8 is the size of the buffer set aside for
* concatenation of variable length fields
*/
return (STMF_ERROR_NOMEM);
}
sluBufSize - 8;
if (metaFileNameLen) {
metaFileNameLen + 1);
}
dataFileNameLen + 1);
/* currently, serial # is not passed null terminated to the driver */
if (disk->serialNumValid) {
}
if (disk->luAliasValid) {
luAliasLen + 1);
}
if (disk->luMgmtUrlValid) {
luMgmtUrlLen + 1);
}
if (disk->luSizeValid) {
}
if (disk->luGuidValid) {
}
}
}
}
if (disk->companyIdValid) {
}
if (disk->hostIdValid) {
}
if (disk->blkSizeValid) {
}
if (disk->writeProtectEnableValid) {
if (disk->writeProtectEnable) {
}
}
if (disk->writebackCacheDisableValid) {
if (disk->writebackCacheDisable) {
}
}
if (ioctlRet != 0) {
savedErrno = errno;
switch (savedErrno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
if (ret == STMF_STATUS_ERROR) {
"createDiskLu:ioctl "
"error(%d) (%d) (%d)", ioctlRet,
}
break;
}
}
if (ret != STMF_STATUS_SUCCESS) {
goto done;
}
/*
* on success, copy the resulting guid into the caller's guid if not
* NULL
*/
if (createdGuid) {
}
if (disk->luMetaFileNameValid) {
} else {
}
done:
return (ret);
}
/*
* stmfImportLu
*
* Purpose: Import a previously created logical unit
*
* dType - Type of logical unit
* Can be: STMF_DISK
*
* luGuid - If non-NULL, on success, contains the guid of the imported logical
* unit
*
* fname - A file name where the metadata resides
*
*/
int
{
int ret = STMF_STATUS_SUCCESS;
} else {
return (STMF_ERROR_INVALID_ARG);
}
return (ret);
}
/*
* importDiskLu
*
* filename - filename to import
* createdGuid - if not NULL, on success contains the imported guid
*
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int fd = 0;
int ioctlRet;
int savedErrno;
int metaFileNameLen;
int iluBufSize = 0;
stmf_iocdata_t sbdIoctl = {0};
return (STMF_ERROR_INVALID_ARG);
}
/*
* Open control node for sbd
*/
return (ret);
/*
* 8 is the size of the buffer set aside for
* concatenation of variable length fields
*/
return (STMF_ERROR_NOMEM);
}
/*
* Accept either a data file or meta data file.
* sbd will do the right thing here either way.
* i.e. if it's a data file, it assumes that the
* meta data is shared with the data.
*/
if (ioctlRet != 0) {
savedErrno = errno;
switch (savedErrno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
if (ret == STMF_STATUS_ERROR) {
"importDiskLu:ioctl "
"error(%d) (%d) (%d)", ioctlRet,
}
break;
}
}
if (ret != STMF_STATUS_SUCCESS) {
goto done;
}
/*
* on success, copy the resulting guid into the caller's guid if not
* NULL and add it to the persistent store for sbd
*/
if (createdGuid) {
sizeof (sbdLu->ilu_ret_guid));
} else {
sizeof (sbdLu->ilu_ret_guid));
}
done:
return (ret);
}
/*
* diskError
*
* Purpose: Translate sbd driver error
*/
static void
{
switch (stmfError) {
break;
case SBD_RET_INVALID_BLKSIZE:
break;
break;
break;
case SBD_RET_NO_META:
break;
break;
case SBD_RET_FILE_SIZE_ERROR:
break;
break;
case SBD_RET_LU_BUSY:
break;
break;
break;
default:
*ret = STMF_STATUS_ERROR;
break;
}
}
/*
* Creates a logical unit resource of type STMF_DISK.
*
* No defaults should be set here as all defaults are derived from the
* driver's default settings.
*/
static int
{
return (STMF_ERROR_NOMEM);
}
return (STMF_STATUS_SUCCESS);
}
/*
* stmfDeleteLu
*
* Purpose: Delete a logical unit
*
* hdl - handle to logical unit resource created via stmfCreateLuResource
*
* luGuid - If non-NULL, on success, contains the guid of the created logical
* unit
*/
int
{
int ret = STMF_STATUS_SUCCESS;
return (STMF_ERROR_INVALID_ARG);
}
/* Check logical unit provider name to call correct dtype function */
!= STMF_STATUS_SUCCESS) {
return (ret);
} else {
return (STMF_ERROR_NOT_FOUND);
} else {
return (STMF_ERROR_INVALID_ARG);
}
}
return (ret);
}
static int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
int savedErrno;
int ioctlRet;
sbd_delete_lu_t deleteLu = {0};
stmf_iocdata_t sbdIoctl = {0};
/*
* Open control node for sbd
*/
return (ret);
if (ret != STMF_STATUS_SUCCESS) {
goto done;
}
if (ioctlRet != 0) {
savedErrno = errno;
switch (savedErrno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
case ENOENT:
break;
default:
"deleteDiskLu:ioctl error(%d) (%d) (%d)",
break;
}
}
done:
return (ret);
}
/*
* stmfLuStandby
*
* Purpose: Sets access state to standby
*
* luGuid - guid of registered logical unit
*
*/
int
{
int ret = STMF_STATUS_SUCCESS;
return (STMF_ERROR_INVALID_ARG);
}
/* Check logical unit provider name to call correct dtype function */
!= STMF_STATUS_SUCCESS) {
return (ret);
} else {
return (STMF_ERROR_NOT_FOUND);
} else {
return (STMF_ERROR_INVALID_ARG);
}
}
return (ret);
}
static int
{
int ret = STMF_STATUS_SUCCESS;
stmf_iocdata_t sbdIoctl = {0};
sbd_set_lu_standby_t sbdLu = {0};
int ioctlRet;
int savedErrno;
int fd = 0;
/*
* Open control node for sbd
*/
return (ret);
if (ioctlRet != 0) {
savedErrno = errno;
switch (savedErrno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
if (ret == STMF_STATUS_ERROR) {
"setDiskStandby:ioctl "
"error(%d) (%d) (%d)", ioctlRet,
}
break;
}
}
return (ret);
}
/*
* stmfModifyLu
*
* Purpose: Modify properties of a logical unit
*
* luGuid - guid of registered logical unit
* prop - property to modify
* propVal - property value to set
*
*/
int
{
int ret = STMF_STATUS_SUCCESS;
return (STMF_ERROR_INVALID_ARG);
}
/* Check logical unit provider name to call correct dtype function */
!= STMF_STATUS_SUCCESS) {
return (ret);
} else {
return (STMF_ERROR_NOT_FOUND);
} else {
return (STMF_ERROR_INVALID_ARG);
}
}
return (ret);
}
/*
* stmfModifyLuByFname
*
* Purpose: Modify a device by filename. Device does not need to be registered.
*
* dType - type of device to modify
* STMF_DISK
*
* fname - filename or meta filename
* prop - valid property identifier
* propVal - property value
*
*/
int
const char *propVal)
{
int ret = STMF_STATUS_SUCCESS;
return (STMF_ERROR_INVALID_ARG);
}
} else {
return (STMF_ERROR_INVALID_ARG);
}
return (ret);
}
static int
const char *propVal)
{
int ret = STMF_STATUS_SUCCESS;
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
if (ret != STMF_STATUS_SUCCESS) {
(void) stmfFreeLuResource(hdl);
return (STMF_ERROR_INVALID_PROP);
}
if (ret != STMF_STATUS_SUCCESS) {
(void) stmfFreeLuResource(hdl);
return (ret);
}
luPropsHdl = hdl;
(void) stmfFreeLuResource(hdl);
return (ret);
}
static int
{
switch (prop) {
case STMF_LU_PROP_ALIAS:
case STMF_LU_PROP_SIZE:
case STMF_LU_PROP_MGMT_URL:
return (STMF_STATUS_SUCCESS);
break;
default:
return (STMF_STATUS_ERROR);
break;
}
}
static int
{
int ret = STMF_STATUS_SUCCESS;
int luAliasLen = 0;
int luMgmtUrlLen = 0;
int mluBufSize = 0;
int bufOffset = 0;
int fd = 0;
int ioctlRet;
int savedErrno;
int fnameSize = 0;
stmf_iocdata_t sbdIoctl = {0};
return (STMF_ERROR_INVALID_ARG);
}
if (fname) {
mluBufSize += fnameSize;
}
/*
* Open control node for sbd
*/
return (ret);
if (disk->luAliasValid) {
}
if (disk->luMgmtUrlValid) {
}
/*
* 8 is the size of the buffer set aside for
* concatenation of variable length fields
*/
return (STMF_ERROR_NOMEM);
}
if (disk->luAliasValid) {
luAliasLen + 1);
}
if (disk->luMgmtUrlValid) {
luMgmtUrlLen + 1);
}
if (disk->luSizeValid) {
}
if (disk->writeProtectEnableValid) {
if (disk->writeProtectEnable) {
}
}
if (disk->writebackCacheDisableValid) {
if (disk->writebackCacheDisable) {
}
}
if (luGuid) {
} else {
}
if (ioctlRet != 0) {
savedErrno = errno;
switch (savedErrno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
if (ret == STMF_STATUS_ERROR) {
"modifyDiskLu:ioctl "
"error(%d) (%d) (%d)", ioctlRet,
}
break;
}
}
if (ret != STMF_STATUS_SUCCESS) {
goto done;
}
done:
return (ret);
}
/*
* removeGuidFromDiskStore
*
* Purpose: delete a logical unit from the sbd provider data
*/
static int
{
}
/*
* addGuidToDiskStore
*
* Purpose: add a logical unit to the sbd provider data
*/
static int
{
}
/*
* persistDiskGuid
*
* Purpose: Persist or unpersist a guid for the sbd provider data
*
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int retryCnt = 0;
int stmfRet;
/* if we're persisting a guid, there must be a filename */
return (1);
}
/* guid is stored in lowercase ascii hex */
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
"%02x%02x%02x%02x%02x%02x",
do {
if (stmfRet != STMF_STATUS_SUCCESS) {
if (ret != 0) {
"unpersistGuid:nvlist_alloc(%d)",
ret);
goto done;
}
} else {
/*
* if we're persisting the data, it's
* an error. Otherwise, just return
*/
if (persist) {
}
goto done;
}
}
if (persist) {
} else {
ret = 0;
}
}
if (ret == 0) {
if (newData) {
} else {
}
if (stmfRet != STMF_STATUS_SUCCESS) {
if (stmfRet == STMF_ERROR_BUSY) {
if (retryCnt++ > MAX_PROVIDER_RETRY) {
break;
}
continue;
} else if (stmfRet ==
/* update failed, try again */
if (retryCnt++ > MAX_PROVIDER_RETRY) {
break;
}
continue;
} else {
"unpersistGuid:error(%x)", stmfRet);
}
break;
}
} else {
"unpersistGuid:error nvlist_add/remove(%d)",
ret);
}
} while (retryGetProviderData);
done:
return (ret);
}
/*
* stmfGetLuProp
*
* Purpose: Get current value for a resource property
*
* hdl - luResource from a previous call to stmfCreateLuResource
*
* resourceProp - a valid resource property type
*
* propVal - void pointer to a pointer of the value to be retrieved
*/
int
{
int ret = STMF_STATUS_SUCCESS;
return (STMF_ERROR_INVALID_ARG);
}
} else {
return (STMF_ERROR_INVALID_ARG);
}
return (ret);
}
/*
* stmfGetLuResource
*
* Purpose: Get a logical unit resource handle for a given logical unit.
*
* hdl - pointer to luResource
*/
int
{
int ret = STMF_STATUS_SUCCESS;
/* Check logical unit provider name to call correct dtype function */
!= STMF_STATUS_SUCCESS) {
return (ret);
} else {
return (STMF_ERROR_NOT_FOUND);
} else {
return (STMF_ERROR_INVALID_ARG);
}
}
return (ret);
}
/*
* getDiskAllProps
*
* Purpose: load all disk properties from sbd driver
*
* luGuid - guid of disk device for which properties are to be retrieved
* hdl - allocated luResource into which properties are to be copied
*
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
int ioctlRet;
int savedErrno;
stmf_iocdata_t sbdIoctl = {0};
/*
* Open control node for sbd
*/
return (ret);
return (STMF_ERROR_NOMEM);
}
return (STMF_ERROR_NOMEM);
}
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
if (ioctlRet != 0) {
savedErrno = errno;
switch (savedErrno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
case ENOENT:
break;
default:
"getDiskAllProps:ioctl error(%d) (%d) (%d)",
break;
}
}
if (ret == STMF_STATUS_SUCCESS) {
}
return (ret);
}
/*
* loadDiskPropsFromDriver
*
* Purpose: Retrieve all disk type properties from sbd driver
*
* hdl - Allocated luResourceImpl
* sbdProps - sbd_lu_props_t structure returned from sbd driver
*
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
/* copy guid */
sizeof (diskLu->luMetaFileName)) >=
sizeof (diskLu->luMetaFileName)) {
return (STMF_STATUS_ERROR);
}
}
if (sbdProps->slp_data_fname_valid) {
sizeof (diskLu->luDataFileName)) >=
sizeof (diskLu->luDataFileName)) {
return (STMF_STATUS_ERROR);
}
}
if (sbdProps->slp_serial_valid) {
}
if (sbdProps->slp_mgmt_url_valid) {
return (STMF_STATUS_ERROR);
}
}
if (sbdProps->slp_alias_valid) {
return (STMF_STATUS_ERROR);
}
} else { /* set alias to data filename if not set */
if (sbdProps->slp_data_fname_valid) {
return (STMF_STATUS_ERROR);
}
}
}
if (sbdProps->slp_write_protected) {
}
}
return (ret);
}
/*
* stmfGetGlobalLuProp
*
* Purpose: get a global property for a device type
*
*/
int
{
int ret = STMF_STATUS_SUCCESS;
return (STMF_ERROR_INVALID_ARG);
}
return (ret);
}
/*
* getDiskGlobalProp
*
* Purpose: get global property from sbd driver
*
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
void *sbd_realloc;
int retryCnt = 0;
int ioctlRet;
int savedErrno;
stmf_iocdata_t sbdIoctl = {0};
switch (prop) {
case STMF_LU_PROP_MGMT_URL:
break;
default:
return (STMF_ERROR_INVALID_PROP);
}
/*
* Open control node for sbd
*/
return (ret);
return (STMF_ERROR_NOMEM);
}
do {
if (ioctlRet != 0) {
savedErrno = errno;
switch (savedErrno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
case ENOMEM:
if (sbdIoctl.stmf_error ==
retryCnt++ < 3) {
sizeof (*sbdProps) +
sbdProps->
break;
}
} else {
}
break;
default:
"getDiskGlobalProp:ioctl error(%d)"
"(%d)(%d)", ioctlRet,
break;
}
}
} while (retry);
if (ret != STMF_STATUS_SUCCESS) {
goto done;
}
switch (prop) {
case STMF_LU_PROP_MGMT_URL:
if (sbdProps->mlu_mgmt_url_valid == 0) {
goto done;
}
goto done;
}
break;
}
done:
return (ret);
}
/*
* stmfSetGlobalLuProp
*
* Purpose: set a global property for a device type
*
*/
int
{
int ret = STMF_STATUS_SUCCESS;
return (STMF_ERROR_INVALID_ARG);
}
return (ret);
}
/*
* setDiskGlobalProp
*
* Purpose: set properties for resource of type disk
*
* resourceProp - valid resource identifier
* propVal - valid resource value
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int sbdGlobalPropsSize = 0;
int propLen;
int mluBufSize = 0;
int fd;
int savedErrno;
int ioctlRet;
stmf_iocdata_t sbdIoctl = {0};
switch (resourceProp) {
case STMF_LU_PROP_MGMT_URL:
break;
default:
return (STMF_ERROR_INVALID_PROP);
break;
}
/*
* Open control node for sbd
*/
return (ret);
/*
* 8 is the size of the buffer set aside for
* concatenation of variable length fields
*/
if (sbdGlobalProps == NULL) {
return (STMF_ERROR_NOMEM);
}
switch (resourceProp) {
case STMF_LU_PROP_MGMT_URL:
propLen + 1);
break;
default:
goto done;
}
if (ioctlRet != 0) {
savedErrno = errno;
switch (savedErrno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
if (ret == STMF_STATUS_ERROR) {
"modifyDiskLu:ioctl "
"error(%d) (%d) (%d)", ioctlRet,
}
break;
}
}
done:
return (ret);
}
/*
* stmfSetLuProp
*
* Purpose: set a property on an luResource
*
* hdl - allocated luResource
* prop - property identifier
* propVal - property value to be set
*/
int
{
int ret = STMF_STATUS_SUCCESS;
return (STMF_ERROR_INVALID_ARG);
}
} else {
return (STMF_ERROR_INVALID_ARG);
}
return (ret);
}
/*
* getDiskProp
*
* Purpose: retrieve a given property from a logical unit resource of type disk
*
* hdl - allocated luResourceImpl
* prop - property identifier
* propVal - pointer to character to contain the retrieved property value
* propLen - On input this is the length of propVal. On failure, it contains the
* number of bytes required for propVal
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
char accessState[20];
if (prop == STMF_LU_PROP_ACCESS_STATE) {
sizeof (accessState));
(void) strlcpy(accessState,
sizeof (accessState));
sizeof (accessState));
} else if (diskLu->accessState ==
(void) strlcpy(accessState,
sizeof (accessState));
}
return (STMF_ERROR_INVALID_ARG);
}
return (0);
}
return (STMF_ERROR_NO_PROP_STANDBY);
}
switch (prop) {
case STMF_LU_PROP_BLOCK_SIZE:
return (STMF_ERROR_NO_PROP);
}
return (STMF_ERROR_INVALID_ARG);
}
break;
case STMF_LU_PROP_FILENAME:
return (STMF_ERROR_NO_PROP);
}
return (STMF_ERROR_INVALID_ARG);
}
break;
return (STMF_ERROR_NO_PROP);
}
return (STMF_ERROR_INVALID_ARG);
}
break;
case STMF_LU_PROP_MGMT_URL:
return (STMF_ERROR_NO_PROP);
}
return (STMF_ERROR_INVALID_ARG);
}
break;
case STMF_LU_PROP_GUID:
return (STMF_ERROR_NO_PROP);
}
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
"%02X%02X%02X%02X",
return (STMF_ERROR_INVALID_ARG);
}
break;
case STMF_LU_PROP_SERIAL_NUM:
return (STMF_ERROR_NO_PROP);
}
return (STMF_ERROR_INVALID_ARG);
}
break;
case STMF_LU_PROP_SIZE:
return (STMF_ERROR_NO_PROP);
}
break;
case STMF_LU_PROP_ALIAS:
return (STMF_ERROR_NO_PROP);
}
return (STMF_ERROR_INVALID_ARG);
}
break;
case STMF_LU_PROP_VID:
return (STMF_ERROR_NO_PROP);
}
return (STMF_ERROR_INVALID_ARG);
}
break;
case STMF_LU_PROP_PID:
return (STMF_ERROR_NO_PROP);
}
return (STMF_ERROR_INVALID_ARG);
}
break;
return (STMF_ERROR_NO_PROP);
}
if (diskLu->writeProtectEnable) {
return (STMF_ERROR_INVALID_ARG);
}
} else {
return (STMF_ERROR_INVALID_ARG);
}
}
break;
return (STMF_ERROR_NO_PROP);
}
if (diskLu->writebackCacheDisable) {
return (STMF_ERROR_INVALID_ARG);
}
} else {
return (STMF_ERROR_INVALID_ARG);
}
}
break;
default:
break;
}
return (ret);
}
/*
* setDiskProp
*
* Purpose: set properties for resource of type disk
*
* hdl - allocated luResourceImpl
* resourceProp - valid resource identifier
* propVal - valid resource value
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int i;
unsigned long long numericProp = 0;
unsigned int hostId[HOST_ID_SIZE];
unsigned int guid[LU_GUID_SIZE];
int propSize;
return (STMF_ERROR_INVALID_ARG);
}
switch (resourceProp) {
case STMF_LU_PROP_ALIAS:
return (STMF_ERROR_INVALID_PROPSIZE);
}
break;
case STMF_LU_PROP_BLOCK_SIZE:
if (numericProp > UINT16_MAX) {
return (STMF_ERROR_INVALID_PROPSIZE);
}
break;
case STMF_LU_PROP_COMPANY_ID:
sizeof (ouiProp)) {
return (STMF_ERROR_INVALID_ARG);
}
if (checkHexUpper(ouiProp) != 0) {
return (STMF_ERROR_INVALID_ARG);
}
return (STMF_ERROR_INVALID_ARG);
}
break;
case STMF_LU_PROP_HOST_ID:
sizeof (hostIdProp))) >= sizeof (hostIdProp)) {
return (STMF_ERROR_INVALID_ARG);
}
if (checkHexUpper(hostIdProp) != 0) {
return (STMF_ERROR_INVALID_ARG);
}
return (STMF_ERROR_INVALID_ARG);
}
break;
case STMF_LU_PROP_GUID:
return (STMF_ERROR_INVALID_PROPSIZE);
}
sizeof (guidProp)) {
return (STMF_ERROR_INVALID_ARG);
}
if (checkHexUpper(guidProp) != 0) {
return (STMF_ERROR_INVALID_ARG);
}
"%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X",
}
break;
case STMF_LU_PROP_FILENAME:
sizeof (diskLu->luDataFileName))) >=
sizeof (diskLu->luDataFileName)) {
return (STMF_ERROR_INVALID_PROPSIZE);
}
break;
sizeof (diskLu->luMetaFileName))) >=
sizeof (diskLu->luMetaFileName)) {
return (STMF_ERROR_INVALID_PROPSIZE);
}
break;
case STMF_LU_PROP_MGMT_URL:
return (STMF_ERROR_INVALID_PROPSIZE);
}
break;
case STMF_LU_PROP_PID:
return (STMF_ERROR_INVALID_PROPSIZE);
}
break;
case STMF_LU_PROP_SERIAL_NUM:
return (STMF_ERROR_INVALID_PROPSIZE);
}
break;
case STMF_LU_PROP_SIZE:
return (STMF_ERROR_INVALID_ARG);
}
break;
case STMF_LU_PROP_VID:
return (STMF_ERROR_INVALID_PROPSIZE);
}
break;
} else {
return (STMF_ERROR_INVALID_ARG);
}
break;
} else {
return (STMF_ERROR_INVALID_ARG);
}
break;
break;
default:
break;
}
return (ret);
}
static int
checkHexUpper(char *buf)
{
int i;
continue;
}
return (-1);
}
return (0);
}
/*
* Given a numeric suffix, convert the value into a number of bits that the
* resulting value must be shifted.
* Code lifted from libzfs_util.c
*/
static int
strToShift(const char *buf)
{
const char *ends = "BKMGTPE";
int i;
if (buf[0] == '\0')
return (0);
return (10*i);
}
return (-1);
}
int
{
int ret = STMF_STATUS_SUCCESS;
return (STMF_ERROR_INVALID_ARG);
}
return (ret);
}
/*
* Convert a string of the form '100G' into a real number. Used when setting
* the size of a logical unit.
* Code lifted from libzfs_util.c
*/
static int
{
char *end;
int shift;
*num = 0;
/* Check to see if this looks like a number. */
return (-1);
}
/* Rely on stroull() to process the numeric portion. */
errno = 0;
/*
* Check for ERANGE, which indicates that the value is too large to fit
* in a 64-bit value.
*/
return (-1);
}
/*
* If we have a decimal value, then do the computation with floating
* point arithmetic. Otherwise, use standard arithmetic.
*/
if (*end == '.') {
return (-1);
}
if (fval > UINT64_MAX) {
return (-1);
}
} else {
return (-1);
}
/* Check for overflow */
return (-1);
}
}
return (0);
}
/*
* stmfCreateTargetGroup
*
* Purpose: Create a local port group
*
* targetGroupName - name of local port group to create
*/
int
{
int ret;
int fd;
if (targetGroupName == NULL ||
== sizeof (stmfGroupName))) {
return (STMF_ERROR_INVALID_ARG);
}
/* Check to ensure service exists */
if (psCheckService() != STMF_STATUS_SUCCESS) {
return (STMF_ERROR_SERVICE_NOT_FOUND);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Add the group to the driver
*/
targetGroupName)) != STMF_STATUS_SUCCESS) {
goto done;
}
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
goto done;
}
/*
* If the add to the driver was successful, add it to the persistent
* store.
*/
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_EXISTS:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfCreateTargetGroup:psCreateTargetGroup"
":error(%d)", ret);
break;
}
done:
return (ret);
}
/*
* stmfDeleteHostGroup
*
* Purpose: Delete an initiator or local port group
*
* hostGroupName - group to delete
*/
int
{
int ret;
int fd;
if (hostGroupName == NULL) {
return (STMF_ERROR_INVALID_ARG);
}
/* Check to ensure service exists */
if (psCheckService() != STMF_STATUS_SUCCESS) {
return (STMF_ERROR_SERVICE_NOT_FOUND);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Remove the group from the driver
*/
hostGroupName)) != STMF_STATUS_SUCCESS) {
goto done;
}
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
goto done;
}
/*
* If the remove from the driver was successful, remove it from the
* persistent store.
*/
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfDeleteHostGroup:psDeleteHostGroup:error(%d)",
ret);
break;
}
done:
return (ret);
}
/*
* stmfDeleteTargetGroup
*
* Purpose: Delete an initiator or local port group
*
* targetGroupName - group to delete
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
if (targetGroupName == NULL) {
return (STMF_ERROR_INVALID_ARG);
}
/* Check to ensure service exists */
if (psCheckService() != STMF_STATUS_SUCCESS) {
return (STMF_ERROR_SERVICE_NOT_FOUND);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Remove the group from the driver
*/
targetGroupName)) != STMF_STATUS_SUCCESS) {
goto done;
}
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
goto done;
}
/*
* If the remove from the driver was successful, remove it from the
* persistent store.
*/
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfDeleteTargetGroup:psDeleteTargetGroup"
":error(%d)", ret);
break;
}
done:
return (ret);
}
/*
* stmfDevidFromIscsiName
*
* Purpose: convert an iSCSI name to an stmf devid
*
* iscsiName - unicode nul terminated utf-8 encoded iSCSI name
* devid - on success, contains the converted iscsi name
*/
int
{
return (STMF_ERROR_INVALID_ARG);
/* Validate size of target */
return (STMF_ERROR_INVALID_ARG);
}
return (STMF_ERROR_INVALID_ARG);
}
/* copy UTF-8 bytes to ident */
return (STMF_STATUS_SUCCESS);
}
/*
* stmfDevidFromWwn
*
* Purpose: convert a WWN to an stmf devid
*
* wwn - 8-byte wwn identifier
* devid - on success, contains the converted wwn
*/
int
{
return (STMF_ERROR_INVALID_ARG);
/* Copy eui prefix */
/* Convert to ASCII uppercase hexadecimal string */
sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X",
return (STMF_STATUS_SUCCESS);
}
/*
* stmfFreeMemory
*
* Purpose: Free memory allocated by this library
*
* memory - previously allocated pointer of memory managed by library
*/
void
stmfFreeMemory(void *memory)
{
}
/*
* get host group, target group list from stmf
*
* groupType - HOST_GROUP, TARGET_GROUP
*/
static int
{
int ret;
int fd;
int ioctlRet;
int i;
int cmd;
/* framework group list */
return (STMF_ERROR_INVALID_ARG);
}
if (groupType == HOST_GROUP) {
} else if (groupType == TARGET_GROUP) {
} else {
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Allocate ioctl input buffer
*/
if (iGroupList == NULL) {
goto done;
}
/*
* Issue ioctl to get the group list
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"groupListIoctl:ioctl errno(%d)",
errno);
break;
}
goto done;
}
/*
* Check whether input buffer was large enough
*/
sizeof (stmf_group_name_t);
if (iGroupList == NULL) {
goto done;
}
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"groupListIoctl:ioctl errno(%d)",
errno);
break;
}
goto done;
}
}
/* allocate and copy to caller's buffer */
goto done;
}
for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
sizeof (stmfGroupName));
}
done:
return (ret);
}
/*
* get host group members, target group members from stmf
*
* groupProps - allocated on success
*
* groupType - HOST_GROUP, TARGET_GROUP
*/
static int
int groupType)
{
int ret;
int fd;
int ioctlRet;
int i;
int cmd;
/* framework group list */
return (STMF_ERROR_INVALID_ARG);
}
if (groupType == HOST_GROUP) {
} else if (groupType == TARGET_GROUP) {
} else {
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Allocate ioctl input buffer
*/
if (iGroupMembers == NULL) {
goto done;
}
/*
* Issue ioctl to get the group list
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"groupListIoctl:ioctl errno(%d)",
errno);
break;
}
goto done;
}
/*
* Check whether input buffer was large enough
*/
sizeof (stmf_ge_ident_t);
if (iGroupMembers == NULL) {
goto done;
}
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"groupListIoctl:ioctl errno(%d)",
errno);
break;
}
goto done;
}
}
/* allocate and copy to caller's buffer */
sizeof (stmfGroupProperties) +
if (*groupProps == NULL) {
goto done;
}
for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
iGroupMembers[i].ident_size);
}
done:
return (ret);
}
/*
* Purpose: access persistent config data for host groups and target groups
*/
static int
{
int ret;
return (STMF_ERROR_INVALID_ARG);
}
if (type == HOST_GROUP) {
} else if (type == TARGET_GROUP) {
} else {
return (STMF_ERROR_INVALID_ARG);
}
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfGetHostGroupList:psGetHostGroupList:error(%d)",
ret);
break;
}
return (ret);
}
/*
* stmfGetHostGroupList
*
* Purpose: Retrieves the list of initiator group oids
*
* hostGroupList - pointer to pointer to hostGroupList structure
* on success, this contains the host group list.
*/
int
{
int ret = STMF_STATUS_ERROR;
if (hostGroupList == NULL) {
return (STMF_ERROR_INVALID_ARG);
}
return (ret);
}
/*
* Purpose: access persistent config data for host groups and target groups
*/
static int
{
int ret;
return (STMF_ERROR_INVALID_ARG);
}
if (type == HOST_GROUP) {
} else if (type == TARGET_GROUP) {
} else {
return (STMF_ERROR_INVALID_ARG);
}
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"iLoadGroupMembersFromPs:psGetHostGroupList:"
"error(%d)", ret);
break;
}
return (ret);
}
/*
* stmfGetHostGroupMembers
*
* Purpose: Retrieves the group properties for a host group
*
* groupName - name of group for which to retrieve host group members.
* groupProp - pointer to pointer to stmfGroupProperties structure
* on success, this contains the list of group members.
*/
int
{
int ret;
return (STMF_ERROR_INVALID_ARG);
}
return (ret);
}
/*
* stmfGetProviderData
*
* Purpose: Get provider data list
*
* providerName - name of provider for which to retrieve the data
* nvl - pointer to nvlist_t pointer which will contain the nvlist data
* retrieved.
* providerType - type of provider for which to retrieve data.
* STMF_LU_PROVIDER_TYPE
* STMF_PORT_PROVIDER_TYPE
*/
int
{
NULL));
}
/*
* stmfGetProviderDataProt
*
* Purpose: Get provider data list with token
*
* providerName - name of provider for which to retrieve the data
* nvl - pointer to nvlist_t pointer which will contain the nvlist data
* retrieved.
* providerType - type of provider for which to retrieve data.
* STMF_LU_PROVIDER_TYPE
* STMF_PORT_PROVIDER_TYPE
* setToken - Returns the stale data token
*/
int
{
int ret;
return (STMF_ERROR_INVALID_ARG);
}
if (providerType != STMF_LU_PROVIDER_TYPE &&
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
}
/*
* stmfGetProviderDataList
*
* Purpose: Get the list of providers currently persisting data
*
* providerList - pointer to pointer to an stmfProviderList structure allocated
* by the caller. Will contain the list of providers on success.
*/
int
{
int ret;
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfGetProviderDataList:psGetProviderDataList"
":error(%d)", ret);
break;
}
return (ret);
}
/*
* stmfGetSessionList
*
* Purpose: Retrieves the session list for a target (devid)
*
* devid - devid of target for which to retrieve session information.
* sessionList - pointer to pointer to stmfSessionList structure
* on success, this contains the list of initiator sessions.
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
int ioctlRet;
int cmd = STMF_IOCTL_SESSION_LIST;
int i;
uint8_t ident[260];
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Allocate ioctl input buffer
*/
if (fSessionList == NULL) {
goto done;
}
devid->identLength);
/*
* Issue ioctl to get the session list
*/
stmfIoctl.stmf_ibuf_size = sizeof (ident);
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"stmfGetSessionList:ioctl errno(%d)",
errno);
break;
}
goto done;
}
/*
* Check whether input buffer was large enough
*/
sizeof (slist_scsi_session_t);
if (fSessionList == NULL) {
goto done;
}
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"stmfGetSessionList:ioctl "
"errno(%d)", errno);
break;
}
goto done;
}
}
/*
* allocate caller's buffer with the final size
*/
if (*sessionList == NULL) {
goto done;
}
/*
* copy session info to caller's buffer
*/
for (i = 0; i < (*sessionList)->cnt; i++) {
sizeof (time_t));
}
done:
return (ret);
}
/*
* stmfGetTargetGroupList
*
* Purpose: Retrieves the list of target groups
*
* targetGroupList - pointer to a pointer to an stmfGroupList structure. On
* success, it contains the list of target groups.
*/
int
{
int ret;
if (targetGroupList == NULL) {
return (STMF_ERROR_INVALID_ARG);
}
return (ret);
}
/*
* stmfGetTargetGroupMembers
*
* Purpose: Retrieves the group members for a target group
*
* groupName - name of target group for which to retrieve members.
* groupProp - pointer to pointer to stmfGroupProperties structure
* on success, this contains the list of group members.
*/
int
{
int ret;
return (STMF_ERROR_INVALID_ARG);
}
return (ret);
}
/*
* stmfGetTargetList
*
* Purpose: Retrieves the list of target ports
*
* targetList - pointer to a pointer to an stmfDevidList structure.
* On success, it contains the list of local ports (target).
*/
int
{
int ret;
int fd;
int ioctlRet;
int i;
/* framework target port list */
if (targetList == NULL) {
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Allocate ioctl input buffer
*/
if (fTargetList == NULL) {
goto done;
}
/*
* Issue ioctl to retrieve target list
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"stmfGetTargetList:ioctl errno(%d)", errno);
break;
}
goto done;
}
/*
* Check whether input buffer was large enough
*/
sizeof (slist_target_port_t);
if (fTargetList == NULL) {
goto done;
}
&stmfIoctl);
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"stmfGetTargetList:ioctl errno(%d)",
errno);
break;
}
goto done;
}
}
sizeof (stmfDevidList));
if (*targetList == NULL) {
goto done;
}
&(*targetList)->devid[i].ident,
}
done:
return (ret);
}
/*
* stmfGetTargetProperties
*
* Purpose: Retrieves the properties for a logical unit
*
* devid - devid of the target for which to retrieve properties
* targetProps - pointer to an stmfTargetProperties structure.
* On success, it contains the target properties for
* the specified devid.
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
int ioctlRet;
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
devid->identLength);
/*
* Issue ioctl to add to the host group
*/
&stmfIoctl);
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
case ENOENT:
break;
default:
"stmfGetTargetProperties:ioctl errno(%d)",
errno);
break;
}
goto done;
}
sizeof (targetProperties.tgt_provider_name));
}
sizeof (targetProps->alias));
done:
return (ret);
}
/*
* stmfGetLogicalUnitList
*
* Purpose: Retrieves list of logical unit Object IDs
*
* luList - pointer to a pointer to a stmfGuidList structure. On success,
* it contains the list of logical unit guids.
*
*/
int
{
int ret;
int fd;
int ioctlRet;
int cmd = STMF_IOCTL_LU_LIST;
int i;
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Allocate ioctl input buffer
*/
goto done;
}
/*
* Issue ioctl to get the LU list
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"stmfGetLogicalUnitList:ioctl errno(%d)",
errno);
break;
}
goto done;
}
/*
* Check whether input buffer was large enough
*/
sizeof (slist_lu_t);
goto done;
}
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"stmfGetLogicalUnitList:"
"ioctl errno(%d)", errno);
break;
}
goto done;
}
}
if (ret != STMF_STATUS_SUCCESS) {
goto done;
}
/*
* allocate caller's buffer with the final size
*/
goto done;
}
/* copy to caller's buffer */
for (i = 0; i < listCnt; i++) {
sizeof (stmfGuid));
}
/*
* sort the list. This gives a consistent view across gets
*/
sizeof (stmfGuid), guidCompare);
done:
/*
* free internal buffers
*/
return (ret);
}
/*
* stmfGetLogicalUnitProperties
*
* Purpose: Retrieves the properties for a logical unit
*
* lu - guid of the logical unit for which to retrieve properties
* stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success,
* it contains the logical unit properties for the specified guid.
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int stmfRet;
int fd;
int ioctlRet;
int cmd = STMF_IOCTL_GET_LU_PROPERTIES;
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Issue ioctl to add to the host group
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
case ENOENT:
if (stmfRet == STMF_STATUS_SUCCESS) {
if (viewEntryList->cnt > 0) {
} else {
}
} else {
}
break;
default:
"stmfGetLogicalUnit:ioctl errno(%d)",
errno);
break;
}
goto done;
}
sizeof (fLuProps.lu_provider_name));
}
done:
return (ret);
}
/*
* stmfGetState
*
* Purpose: retrieve the current state of the stmf module
*
* state - pointer to stmfState structure allocated by the caller
* On success, contains the state of stmf
*/
int
{
int ret;
return (STMF_ERROR_INVALID_ARG);
}
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
case STMF_STATE_ONLINE:
break;
case STMF_STATE_OFFLINE:
break;
case STMF_STATE_ONLINING:
break;
case STMF_STATE_OFFLINING:
break;
default:
break;
}
switch (iState.config_state) {
case STMF_CONFIG_NONE:
break;
case STMF_CONFIG_INIT:
break;
case STMF_CONFIG_INIT_DONE:
state->configState =
break;
default:
state->configState =
break;
}
return (STMF_STATUS_SUCCESS);
}
/*
* stmfGetViewEntryList
*
* Purpose: Retrieves the list of view entries for the specified
* logical unit.
*
* lu - the guid of the logical unit for which to retrieve the view entry list
* viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On
* success, contains the list of view entries.
*/
int
{
int ret;
int fd;
int ioctlRet;
int cmd = STMF_IOCTL_LU_VE_LIST;
int i;
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Allocate ioctl input buffer
*/
goto done;
}
/*
* Issue ioctl to get the LU list
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"stmfGetViewEntryList:ioctl errno(%d)",
errno);
break;
}
goto done;
}
/*
* Check whether input buffer was large enough
*/
sizeof (stmf_view_op_entry_t);
return (STMF_ERROR_NOMEM);
}
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"stmfGetLogicalUnitList:"
"ioctl errno(%d)", errno);
break;
}
goto done;
}
}
if (ret != STMF_STATUS_SUCCESS) {
goto done;
}
if (stmfIoctl.stmf_obuf_nentries == 0) {
goto done;
}
/*
* allocate caller's buffer with the final size
*/
if (*viewEntryList == NULL) {
goto done;
}
/* copy to caller's buffer */
for (i = 0; i < listCnt; i++) {
} else {
}
} else {
}
}
/*
* sort the list. This gives a consistent view across gets
*/
sizeof (stmfViewEntry), viewEntryCompare);
done:
/*
* free internal buffers
*/
return (ret);
}
/*
* loadHostGroups
*
* Purpose - issues the ioctl to load the host groups into stmf
*
* fd - file descriptor for the control node of stmf.
* groupList - populated host group list
*/
static int
{
int i, j;
int ret = STMF_STATUS_SUCCESS;
goto out;
}
&groupProps, HOST_GROUP);
for (j = 0; j < groupProps->cnt; j++) {
!= STMF_STATUS_SUCCESS) {
goto out;
}
}
}
out:
return (ret);
}
/*
* loadTargetGroups
*
* Purpose - issues the ioctl to load the target groups into stmf
*
* fd - file descriptor for the control node of stmf.
* groupList - populated target group list.
*/
static int
{
int i, j;
int ret = STMF_STATUS_SUCCESS;
goto out;
}
for (j = 0; j < groupProps->cnt; j++) {
!= STMF_STATUS_SUCCESS) {
goto out;
}
}
}
out:
return (ret);
}
/*
* loadStore
*
* Purpose: Load the configuration data from the store
*
* First load the host groups and target groups, then the view entries
* and finally the provider data
*
* fd - file descriptor of control node for stmf.
*/
static int
{
int ret;
int i, j;
int providerType;
/* load host groups */
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
if (ret != STMF_STATUS_SUCCESS) {
goto out;
}
/* load target groups */
if (ret != STMF_STATUS_SUCCESS) {
goto out;
}
if (ret != STMF_STATUS_SUCCESS) {
goto out;
}
/* Get the guid list */
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
break;
}
if (ret != STMF_STATUS_SUCCESS) {
goto out;
}
/*
* We have the guid list, now get the corresponding
* view entries for each guid
*/
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
break;
}
if (ret != STMF_STATUS_SUCCESS) {
goto out;
}
for (j = 0; j < viewEntryList->cnt; j++) {
&viewEntryList->ve[j]);
if (ret != STMF_STATUS_SUCCESS) {
goto out;
}
}
}
/* get the list of providers that have data */
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
break;
}
if (ret != STMF_STATUS_SUCCESS) {
goto out;
}
for (i = 0; i < providerList->cnt; i++) {
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
break;
}
if (ret != STMF_STATUS_SUCCESS) {
goto out;
}
/* call setProviderData */
providerType, NULL);
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
break;
}
if (ret != STMF_STATUS_SUCCESS) {
goto out;
}
}
out:
}
}
if (viewEntryList != NULL) {
}
}
return (ret);
}
/*
* stmfGetAluaState
*
* Purpose - Get the alua state
*
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
stmf_iocdata_t stmfIoctl = {0};
stmf_alua_state_desc_t alua_state = {0};
int ioctlRet;
return (STMF_ERROR_INVALID_ARG);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Issue ioctl to get the stmf state
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"getStmfState:ioctl errno(%d)", errno);
break;
}
} else {
} else {
}
}
return (ret);
}
/*
* stmfSetAluaState
*
*
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
stmf_iocdata_t stmfIoctl = {0};
stmf_alua_state_desc_t alua_state = {0};
int ioctlRet;
return (STMF_ERROR_INVALID_ARG);
}
if (enabled) {
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Issue ioctl to get the stmf state
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"getStmfState:ioctl errno(%d)", errno);
break;
}
}
if (ret == STMF_STATUS_SUCCESS) {
}
return (ret);
}
static void
{
int stmfRet;
int i;
char propVal[10];
if (stmfRet != STMF_STATUS_SUCCESS) {
return;
}
if (stmfRet != STMF_STATUS_SUCCESS) {
goto err;
}
&propValSize);
if (stmfRet != STMF_STATUS_SUCCESS) {
goto err;
}
if (propVal[0] == '0') {
(void) stmfFreeLuResource(hdl);
continue;
}
(void) stmfFreeLuResource(hdl);
}
err:
(void) stmfFreeLuResource(hdl);
}
/*
* stmfLoadConfig
*
* Purpose - load the configuration data from smf into stmf
*
*/
int
stmfLoadConfig(void)
{
int ret = STMF_STATUS_SUCCESS;
int fd;
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
!= STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Configuration not stored persistently; nothing to
* initialize so do not set to STMF_CONFIG_INIT.
*/
goto done;
}
/* Check to ensure service exists */
if (psCheckService() != STMF_STATUS_SUCCESS) {
return (STMF_ERROR_SERVICE_NOT_FOUND);
}
if (ret == STMF_STATUS_SUCCESS) {
return (STMF_ERROR_SERVICE_ONLINE);
}
} else {
return (STMF_STATUS_ERROR);
}
/*
* Open control node for stmf
*/
return (ret);
if (ret != STMF_STATUS_SUCCESS) {
goto done;
}
/* Load the persistent configuration data */
if (ret != 0) {
goto done;
}
done:
if (ret == STMF_STATUS_SUCCESS) {
}
return (ret);
}
/*
* getStmfState
*
* stmfState - pointer to stmf_state_desc_t structure. Will contain the state
* information of the stmf service on success.
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
int ioctlRet;
/*
* Open control node for stmf
*/
return (ret);
/*
* Issue ioctl to get the stmf state
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
default:
"getStmfState:ioctl errno(%d)", errno);
break;
}
}
return (ret);
}
/*
* setStmfState
*
* stmfState - pointer to caller set state structure
* objectType - one of:
* LOGICAL_UNIT_TYPE
* TARGET_TYPE
* STMF_SERVICE_TYPE
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int ioctlRet;
int cmd;
switch (objectType) {
case LOGICAL_UNIT_TYPE:
break;
case TARGET_TYPE:
break;
case STMF_SERVICE_TYPE:
break;
default:
goto done;
}
/*
* Issue ioctl to set the stmf state
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
case ENOENT:
break;
default:
"setStmfState:ioctl errno(%d)", errno);
break;
}
}
done:
return (ret);
}
/*
* stmfOnline
*
* Purpose: Online stmf service
*
*/
int
stmfOnline(void)
{
int ret;
int fd;
if (ret == STMF_STATUS_SUCCESS) {
return (STMF_ERROR_SERVICE_ONLINE);
}
} else {
return (STMF_STATUS_ERROR);
}
/*
* Open control node for stmf
* to make call to setStmfState()
*/
return (ret);
return (ret);
}
/*
* stmfOffline
*
* Purpose: Offline stmf service
*
*/
int
stmfOffline(void)
{
int ret;
int fd;
if (ret == STMF_STATUS_SUCCESS) {
return (STMF_ERROR_SERVICE_OFFLINE);
}
} else {
return (STMF_STATUS_ERROR);
}
/*
* Open control node for stmf
* to make call to setStmfState()
*/
return (ret);
return (ret);
}
/*
* stmfOfflineTarget
*
* Purpose: Change state of target to offline
*
* devid - devid of the target to offline
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
return (STMF_ERROR_INVALID_ARG);
}
devid->identLength);
/*
* Open control node for stmf
* to make call to setStmfState()
*/
return (ret);
return (ret);
}
/*
* stmfOfflineLogicalUnit
*
* Purpose: Change state of logical unit to offline
*
* lu - guid of the logical unit to offline
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
return (STMF_ERROR_INVALID_ARG);
}
/*
* Open control node for stmf
* to make call to setStmfState()
*/
return (ret);
return (ret);
}
/*
* stmfOnlineTarget
*
* Purpose: Change state of target to online
*
* devid - devid of the target to online
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
return (STMF_ERROR_INVALID_ARG);
}
devid->identLength);
/*
* Open control node for stmf
* to make call to setStmfState()
*/
return (ret);
return (ret);
}
/*
* stmfOnlineLogicalUnit
*
* Purpose: Change state of logical unit to online
*
* lu - guid of the logical unit to online
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
return (STMF_ERROR_INVALID_ARG);
}
/*
* Open control node for stmf
* to make call to setStmfState()
*/
return (ret);
return (ret);
}
/*
* stmfRemoveFromHostGroup
*
* Purpose: Removes an initiator from an initiator group
*
* hostGroupName - name of an initiator group
* hostName - name of host group member to remove
*/
int
{
int ret;
int fd;
if (hostGroupName == NULL ||
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
goto done;
}
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
goto done;
}
(char *)hostName->ident);
switch (ret) {
case STMF_PS_SUCCESS:
break;
break;
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfRemoveFromHostGroup"
"psRemoveHostGroupMember:error(%d)", ret);
break;
}
done:
return (ret);
}
/*
* stmfRemoveFromTargetGroup
*
* Purpose: Removes a local port from a local port group
*
* targetGroupName - name of a target group
* targetName - name of target to remove
*/
int
{
int ret;
int fd;
if (targetGroupName == NULL ||
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
goto done;
}
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
goto done;
}
(char *)targetName->ident);
switch (ret) {
case STMF_PS_SUCCESS:
break;
break;
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfRemoveFromTargetGroup"
"psRemoveTargetGroupMember:error(%d)", ret);
break;
}
done:
return (ret);
}
/*
* stmfRemoveViewEntry
*
* Purpose: Removes a view entry from a logical unit
*
* lu - guid of lu for which view entry is being removed
* viewEntryIndex - index of view entry to remove
*
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
int ioctlRet;
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Issue ioctl to add to the view entry
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
break;
case EACCES:
switch (stmfIoctl.stmf_error) {
break;
default:
break;
}
break;
case ENODEV:
case ENOENT:
break;
default:
"stmfRemoveViewEntry:ioctl errno(%d)",
errno);
break;
}
goto done;
}
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
goto done;
}
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)",
ret);
break;
}
done:
return (ret);
}
/*
* stmfSetProviderData
*
* Purpose: set the provider data
*
* providerName - unique name of provider
* nvl - nvlist to set
* providerType - type of provider for which to set data
* STMF_LU_PROVIDER_TYPE
* STMF_PORT_PROVIDER_TYPE
*/
int
{
NULL));
}
/*
* stmfSetProviderDataProt
*
* Purpose: set the provider data
*
* providerName - unique name of provider
* nvl - nvlist to set
* providerType - type of provider for which to set data
* STMF_LU_PROVIDER_TYPE
* STMF_PORT_PROVIDER_TYPE
* setToken - Stale data token returned in the stmfGetProviderDataProt()
* call or NULL.
*/
int
{
int ret;
int fd;
return (STMF_ERROR_INVALID_ARG);
}
if (providerType != STMF_LU_PROVIDER_TYPE &&
return (STMF_ERROR_INVALID_ARG);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
if (ret != STMF_STATUS_SUCCESS) {
goto done;
}
if (iGetPersistMethod() == STMF_PERSIST_NONE) {
goto done;
}
/* setting driver provider data successful. Now persist it */
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_EXISTS:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
break;
default:
"stmfSetProviderData"
"psSetProviderData:error(%d)", ret);
break;
}
done:
return (ret);
}
/*
* getProviderData
*
* Purpose: set the provider data from stmf
*
* providerName - unique name of provider
* providerType - logical unit or port provider
* setToken - returned stale data token
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int fd;
int ioctlRet;
int retryCnt = 0;
int retryCntMax = MAX_PROVIDER_RETRY;
if (providerName == NULL) {
return (STMF_ERROR_INVALID_ARG);
}
/*
* Open control node for stmf
*/
return (ret);
/* set provider name and provider type */
goto done;
}
switch (providerType) {
case STMF_LU_PROVIDER_TYPE:
break;
case STMF_PORT_PROVIDER_TYPE:
break;
default:
goto done;
}
do {
/* allocate memory for ioctl */
sizeof (stmf_ppioctl_data_t));
goto done;
}
/* set the size of the ioctl data to allocated buffer */
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
case EINVAL:
if (stmfIoctl.stmf_error ==
if (retryCnt++ > retryCntMax) {
} else {
ret =
}
} else {
"getProviderData:ioctl"
"unable to retrieve "
"nvlist");
}
break;
case ENOENT:
break;
default:
"getProviderData:ioctl errno(%d)",
errno);
break;
}
if (ret != STMF_STATUS_SUCCESS)
goto done;
}
goto done;
}
/* caller has asked for new token */
if (setToken) {
}
done:
return (ret);
}
/*
* setProviderData
*
* Purpose: set the provider data in stmf
*
* providerName - unique name of provider
* nvl - nvlist to set
* providerType - logical unit or port provider
* setToken - stale data token to check if not NULL
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int ioctlRet;
char *allocatedNvBuffer;
if (providerName == NULL) {
return (STMF_ERROR_INVALID_ARG);
}
/* get size of encoded nvlist */
return (STMF_STATUS_ERROR);
}
/* allocate memory for ioctl */
sizeof (stmf_ppioctl_data_t));
return (STMF_ERROR_NOMEM);
}
if (setToken) {
}
NV_ENCODE_XDR, 0) != 0) {
return (STMF_STATUS_ERROR);
}
/* set provider name and provider type */
switch (providerType) {
case STMF_LU_PROVIDER_TYPE:
break;
case STMF_PORT_PROVIDER_TYPE:
break;
default:
return (STMF_ERROR_INVALID_ARG);
}
/* set the size of the ioctl data to packed data size */
/*
* Subtracting 8 from the size as that is the size of the last member
* of the structure where the packed data resides
*/
sizeof (stmf_ppioctl_data_t) - 8;
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
case EACCES:
break;
case EINVAL:
if (stmfIoctl.stmf_error ==
} else {
}
break;
default:
"setProviderData:ioctl errno(%d)", errno);
break;
}
if (ret != STMF_STATUS_SUCCESS)
goto done;
}
/* caller has asked for new token */
if (setToken) {
}
done:
return (ret);
}
/*
* set the persistence method in the library only or library and service
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int oldPersist;
(void) pthread_mutex_lock(&persistenceTypeLock);
if (persistType == STMF_PERSIST_NONE ||
persistType == STMF_PERSIST_SMF) {
} else {
(void) pthread_mutex_unlock(&persistenceTypeLock);
return (STMF_ERROR_INVALID_ARG);
}
/* Is this for this library open or in SMF */
if (serviceSet == B_TRUE) {
if (ret != STMF_PS_SUCCESS) {
/* Set to old value */
}
}
(void) pthread_mutex_unlock(&persistenceTypeLock);
return (ret);
}
/*
* Only returns internal state for persist. If unset, goes to ps. If that
* fails, returns default setting
*/
static uint8_t
{
uint8_t persistType = 0;
(void) pthread_mutex_lock(&persistenceTypeLock);
if (iLibSetPersist) {
} else {
int ret;
if (ret != STMF_PS_SUCCESS) {
/* set to default */
}
}
(void) pthread_mutex_unlock(&persistenceTypeLock);
return (persistType);
}
/*
* Returns either library state or persistent config state depending on
* serviceState
*/
int
{
int ret = STMF_STATUS_SUCCESS;
if (persistType == NULL) {
return (STMF_ERROR_INVALID_ARG);
}
if (serviceState) {
if (ret != STMF_PS_SUCCESS) {
}
} else {
(void) pthread_mutex_lock(&persistenceTypeLock);
if (iLibSetPersist) {
} else {
}
(void) pthread_mutex_unlock(&persistenceTypeLock);
}
return (ret);
}
/*
* stmfPostProxyMsg
*
* Purpose: Post a message to the proxy port provider
*
* buf - buffer containing message to post
* buflen - buffer length
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int ioctlRet;
pppt_iocdata_t ppptIoctl = {0};
return (STMF_ERROR_INVALID_ARG);
}
/*
* Issue ioctl to post the message
*/
if (ioctlRet != 0) {
switch (errno) {
case EPERM:
case EACCES:
break;
default:
break;
}
}
return (ret);
}
/*
* stmfInitProxyDoor
*
* Purpose: Install door in proxy
*
* hdl - pointer to returned handle
* fd - door from door_create()
*/
int
{
int ret = STMF_STATUS_SUCCESS;
int ioctlRet;
int fd;
pppt_iocdata_t ppptIoctl = {0};
return (STMF_ERROR_INVALID_ARG);
}
/*
* Open control node for pppt
*/
return (ret);
}
/*
* Issue ioctl to install the door
*/
if (ioctlRet != 0) {
switch (errno) {
case EPERM:
case EACCES:
break;
case EINVAL:
break;
case EBUSY:
break;
default:
break;
}
}
/* return driver fd to caller */
return (ret);
}
void
stmfDestroyProxyDoor(int hdl)
{
}
/*
* validateLunNumIoctl
*
* Purpose: Issues ioctl to check and get available lun# in view entry
*
* viewEntry - view entry to use
*/
static int
{
int ret = STMF_STATUS_SUCCESS;
int ioctlRet;
/*
* don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
* false on input
*/
sizeof (stmfGroupName));
}
sizeof (stmfGroupName));
}
/* Validating the lun number */
if (viewEntry->luNbrValid) {
sizeof (ioctlViewEntry.ve_lu_nbr));
}
/*
* Issue ioctl to validate lun# in the view entry
*/
/* save available lun number */
if (!viewEntry->luNbrValid) {
sizeof (ioctlViewEntry.ve_lu_nbr));
}
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EPERM:
break;
case EACCES:
switch (stmfIoctl.stmf_error) {
break;
default:
break;
}
break;
default:
switch (stmfIoctl.stmf_error) {
break;
break;
break;
case STMF_IOCERR_INVALID_HG:
break;
case STMF_IOCERR_INVALID_TG:
break;
default:
"addViewEntryIoctl"
":error(%d)",
break;
}
break;
}
}
return (ret);
}
/*
* stmfValidateView
*
* Purpose: Validate or get lun # base on TG, HG of view entry
*
* viewEntry - view entry structure to use
*/
int
{
int ret;
int fd;
return (STMF_ERROR_INVALID_ARG);
}
/* initialize and set internal view entry */
sizeof (iViewEntry.hostGroup));
} else {
}
if (!viewEntry->allTargets) {
sizeof (iViewEntry.targetGroup));
} else {
}
if (viewEntry->luNbrValid) {
sizeof (iViewEntry.luNbr));
}
/*
* set users return view entry index valid flag to false
* in case of failure
*/
/* Check to ensure service exists */
if (psCheckService() != STMF_STATUS_SUCCESS) {
return (STMF_ERROR_SERVICE_NOT_FOUND);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
/*
* Validate lun# in the view entry from the driver
*/
/* save available lun number */
if (!viewEntry->luNbrValid) {
sizeof (iViewEntry.luNbr));
}
return (ret);
}