stmf.c revision fcf3ce441efd61da9bb2884968af01cb7c1452cc
/*
* 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 2008 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 <sys/stmf_ioctl.h>
#define EUI "eui."
#define WWN "wwn."
#define IQN "iqn."
#define WWN_ASCII_SIZE 16
#define IDENT_LENGTH_BYTE 3
#define MAX_TARGET_PORT 1024
#define MAX_PROVIDER 1024
#define MAX_GROUP 1024
#define MAX_SESSION 1024
#define MAX_ISCSI_NAME 223
#define OPEN_STMF 0
#define OPEN_EXCL_STMF O_EXCL
#define LOGICAL_UNIT_TYPE 0
#define TARGET_TYPE 1
#define STMF_SERVICE_TYPE 2
static int initializeConfig();
static int guidCompare(const void *, const void *);
static int getStmfState(stmf_state_desc_t *);
/*
* 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);
}
/*
* 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 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);
}
/*
* groupIoctl
*
*
* 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:
break;
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);
}
/*
* 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;
}
(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);
}
if (ret == STMF_STATUS_SUCCESS) {
return (STMF_ERROR_SERVICE_ONLINE);
}
} else {
return (STMF_STATUS_ERROR);
}
/* call init */
ret = initializeConfig();
if (ret != STMF_STATUS_SUCCESS) {
return (ret);
}
/*
* Open control node for stmf
*/
return (ret);
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 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 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 EACCES:
break;
default:
"stmfClearProviderData:ioctl error(%d)",
ioctlRet);
break;
}
if (savedErrno != ENOENT) {
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;
}
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);
}
/*
* 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 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 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 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)
{
}
/*
* 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;
if (hostGroupList == NULL) {
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);
}
/*
* 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);
}
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfGetHostGroupMembers:psGetHostGroupMembers"
":error(%d)", ret);
break;
}
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);
}
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_BUSY:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
break;
break;
default:
"stmfGetProviderData:psGetProviderData:error(%d)",
ret);
break;
}
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) {
return (STMF_ERROR_NOMEM);
}
devid->identLength);
/*
* Issue ioctl to get the session list
*/
stmfIoctl.stmf_ibuf_size = sizeof (ident);
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
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) {
return (STMF_ERROR_NOMEM);
}
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
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);
}
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfGetTargetGroupList:psGetTargetGroupList:"
"error(%d)", ret);
break;
}
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);
}
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_NOT_FOUND:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfGetTargetGroupMembers:psGetTargetGroupMembers:"
"error(%d)", ret);
break;
}
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 add to the host group
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EACCES:
break;
default:
"stmfGetTargetList:ioctl errno(%d)", errno);
break;
}
goto done;
}
/*
* Check whether input buffer was large enough
*/
sizeof (slist_lu_t);
if (fTargetList == NULL) {
return (STMF_ERROR_NOMEM);
}
&stmfIoctl);
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EACCES:
break;
default:
"stmfGetTargetList:ioctl errno(%d)",
errno);
break;
}
goto done;
}
}
sizeof (stmfDevidList));
&(*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 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, k;
/* framework lu list */
/* persistent store lu list */
int finalListSize = 0;
int newAllocSize;
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
*/
return (STMF_ERROR_NOMEM);
}
/*
* Issue ioctl to get the LU list
*/
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EACCES:
break;
default:
"stmfGetLogicalUnitList:ioctl errno(%d)",
errno);
break;
}
goto done;
}
/*
* Check whether input buffer was large enough
*/
sizeof (slist_lu_t);
return (STMF_ERROR_NOMEM);
}
if (ioctlRet != 0) {
switch (errno) {
case EBUSY:
break;
case EACCES:
break;
default:
"stmfGetLogicalUnitList:"
"ioctl errno(%d)", errno);
break;
}
goto done;
}
}
switch (ret) {
case STMF_PS_SUCCESS:
break;
case STMF_PS_ERROR_BUSY:
break;
break;
break;
default:
"stmfGetLogicalUnitList:psGetLogicalUnitList"
":error(%d)", ret);
break;
}
if (ret != STMF_STATUS_SUCCESS) {
goto done;
}
/*
* 2 lists must be merged
* reallocate the store list to add the list from the
* framework
*/
goto done;
}
/*
* add list from ioctl. Start from end of list retrieved from store.
*/
sizeof (stmfGuid));
}
/*
* sort the list for merging
*/
sizeof (stmfGuid), guidCompare);
/*
* get final list count
*/
sizeof (stmfGuid)) == 0) {
continue;
}
}
}
/*
* allocate caller's buffer with the final size
*/
finalListSize * sizeof (stmfGuid));
goto done;
}
/*
* copy guids to caller's buffer
*/
sizeof (stmfGuid)) == 0) {
continue;
}
}
sizeof (stmfGuid));
}
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;
}
/* 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 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;
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:
"stmfGetViewEntryList:error(%d)", ret);
break;
}
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);
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;
}
&groupProps);
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 */
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);
}
/*
* stmfLoadConfig
*
* Purpose - load the configuration data from smf into stmf
*
*/
int
stmfLoadConfig(void)
{
int ret;
int fd;
/* 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 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;
}
(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;
}
(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 EACCES:
switch (stmfIoctl.stmf_error) {
break;
default:
break;
}
break;
case ENODEV:
case ENOENT:
break;
default:
"stmfRemoveViewEntry:ioctl errno(%d)",
errno);
break;
}
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;
}
/* 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);
}
/*
* setProviderData
*
* Purpose: set the provider data
*
* providerName - unique name of provider
* nvl - nvlist to set
* providerType - logical unit or port provider
*/
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);
}
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 EACCES:
break;
default:
"setProviderData:ioctl errno(%d)", errno);
break;
}
if (ret != STMF_STATUS_SUCCESS)
goto done;
}
done:
return (ret);
}