diff options
author | John Forte <John.Forte@Sun.COM> | 2008-10-14 15:09:13 -0700 |
---|---|---|
committer | John Forte <John.Forte@Sun.COM> | 2008-10-14 15:09:13 -0700 |
commit | fcf3ce441efd61da9bb2884968af01cb7c1452cc (patch) | |
tree | 0e80d59ad41702571586195bf099ccc14222ce02 /usr/src/lib/mpapi | |
parent | 247b82a1f1cb5ebd2d163bd9afdb1a3065611962 (diff) | |
download | illumos-gate-fcf3ce441efd61da9bb2884968af01cb7c1452cc.tar.gz |
6745433 Merge NWS consolidation into OS/Net consolidation
Diffstat (limited to 'usr/src/lib/mpapi')
71 files changed, 14795 insertions, 0 deletions
diff --git a/usr/src/lib/mpapi/Makefile b/usr/src/lib/mpapi/Makefile new file mode 100644 index 0000000000..e51ae722b3 --- /dev/null +++ b/usr/src/lib/mpapi/Makefile @@ -0,0 +1,48 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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. +# + +SUBDIRS = libmpapi libmpscsi_vhci +HDRSUBDIRS = libmpapi + +all := TARGET= all +check := TARGET= check +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +install_h := TARGET= install_h + +.KEEP_STATE: + +libmpscsi_vhci: libmpapi + +all clean clobber install: $(SUBDIRS) + +check install_h: $(HDRSUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: diff --git a/usr/src/lib/mpapi/libmpapi/Makefile b/usr/src/lib/mpapi/libmpapi/Makefile new file mode 100644 index 0000000000..ebad6d797d --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/Makefile @@ -0,0 +1,53 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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 ../../Makefile.lib + +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +lint := TARGET= lint + +HDRS = mpapi.h mpapi-sun.h +HDRDIR = common + +.KEEP_STATE: + +all clean clobber install lint: $(SUBDIRS) + +install_h: $(ROOTHDRS) + +check: + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../../Makefile.targ diff --git a/usr/src/lib/mpapi/libmpapi/Makefile.com b/usr/src/lib/mpapi/libmpapi/Makefile.com new file mode 100644 index 0000000000..2ae558051c --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/Makefile.com @@ -0,0 +1,63 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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. +# + +LIBRARY= libMPAPI.a +VERS= .1 +OBJECTS= mpapi.o mpapi-sun.o + +include ../../../Makefile.lib +include ../../../Makefile.rootfs + +SRCDIR = ../common + +LIBS = $(DYNLIB) $(LINTLIB) +LDLIBS += -lc + +$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) -mt -v -D_POSIX_PTHREAD_SEMANTICS +CPPFLAGS += -DBUILD_TIME='"Wed Sep 24 12:00:00 2008"' +DYNFLAGS += -z finiarray=ExitLibrary +DYNFLAGS += -z initarray=InitLibrary + +ROOTETC = $(ROOT)/etc +CONFDIR = ../common +CONFFILE = $(CONFDIR)/mpapi.conf +IETCFILES = $(CONFFILE:$(CONFDIR)/%=$(ROOTETC)/%) +$(IETCFILES) := FILEMODE = 0644 +$(IETCFILES) := OWNER = root +$(IETCFILES) := GROUP = sys + +.KEEP_STATE: + +all: $(LIBS) $(IETCFILES) + +lint: + +$(ROOTETC)/%: $(CONFDIR)/% + $(INS.file) + +include ../../../Makefile.targ diff --git a/usr/src/lib/mpapi/libmpapi/amd64/Makefile b/usr/src/lib/mpapi/libmpapi/amd64/Makefile new file mode 100644 index 0000000000..bbc20fa470 --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/amd64/Makefile @@ -0,0 +1,29 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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 ../Makefile.com +include ../../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) diff --git a/usr/src/lib/mpapi/libmpapi/common/llib-lMPAPI b/usr/src/lib/mpapi/libmpapi/common/llib-lMPAPI new file mode 100644 index 0000000000..5fe92023db --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/common/llib-lMPAPI @@ -0,0 +1,31 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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. + */ + +/*LINTLIBRARY*/ +/*PROTOLIB1*/ + +#include <mpapi.h> +#include <mpapi-sun.h> diff --git a/usr/src/lib/mpapi/libmpapi/common/mapfile-vers b/usr/src/lib/mpapi/libmpapi/common/mapfile-vers new file mode 100644 index 0000000000..4f7e53bc03 --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/common/mapfile-vers @@ -0,0 +1,78 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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. +# + +SUNW_1.0 { + global: + MP_GetLibraryProperties; + MP_GetPluginOidList; + MP_GetPluginProperties; + MP_GetAssociatedPluginOid; + MP_GetObjectType; + MP_GetDeviceProductOidList; + MP_GetDeviceProductProperties; + MP_GetInitiatorPortOidList; + MP_GetInitiatorPortProperties; + MP_GetMultipathLus; + MP_GetMPLogicalUnitProperties; + MP_GetAssociatedPathOidList; + MP_GetPathLogicalUnitProperties; + MP_GetAssociatedTPGOidList; + MP_GetTargetPortGroupProperties; + MP_GetMPLuOidListFromTPG; + MP_GetProprietaryLoadBalanceOidList; + MP_GetProprietaryLoadBalanceProperties; + MP_GetTargetPortOidList; + MP_GetTargetPortProperties; + MP_AssignLogicalUnitToTPG; + MP_SetOverridePath; + MP_CancelOverridePath; + MP_EnableAutoFailback; + MP_DisableAutoFailback; + MP_EnableAutoProbing; + MP_DisableAutoProbing; + MP_EnablePath; + MP_DisablePath; + MP_SetLogicalUnitLoadBalanceType; + MP_SetPluginLoadBalanceType; + MP_SetPathWeight; + MP_SetFailbackPollingRate; + MP_SetProbingPollingRate; + MP_SetProprietaryProperties; + MP_SetTPGAccess; + MP_RegisterForObjectPropertyChanges; + MP_DeregisterForObjectPropertyChanges; + MP_RegisterForObjectVisibilityChanges; + MP_DeregisterForObjectVisibilityChanges; + MP_CompareOIDs; + MP_FreeOidList; + MP_RegisterPlugin; + MP_DeregisterPlugin; + MP_FreeOidList; + MP_RegisterPlugin; + MP_DeregisterPlugin; + Sun_MP_SendScsiCmd; + local: + *; +}; diff --git a/usr/src/lib/mpapi/libmpapi/common/mpapi-plugin.h b/usr/src/lib/mpapi/libmpapi/common/mpapi-plugin.h new file mode 100644 index 0000000000..e85f643635 --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/common/mpapi-plugin.h @@ -0,0 +1,291 @@ +/****************************************************************************** + * + * Description + * mpapi-plugin.h - interfaces for the MP API Version 1.0 plugin library. + * A compliant plugin library should implement interfaces with name without Fn + * suffix from function definitions below. + * + * License: + * The contents of this file are subject to the SNIA Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * TBD + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is iSCSI Management API and Multipath Management API + * plugin header file + * + * The Initial Developer of the Original Code is: + * Benjamin F. Kuo Troika Networks, Inc. (benk@troikanetworks.com) + * David Dillard VERITAS Software(david.dillard@veritas.com) + * Jeff Ding Adaptec, Inc. (jding@corp.adaptec.com) + * Hyon Kim Sun Microsystems(hyon.kim@sun.com) + * + * Contributor(s): + * Paul von Behren Sun Microsystems(paul.vonbehren@sun.com) + * + ****************************************************************************** + * + * Changes: + * 1/15/2005 Implemented SNIA MP API specification 1.0 + *****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef MPPLUGIN_H +#define MPPLUGIN_H + +/* + * MP API common library calls InitaizeFn as part of dynamically loading + * the plugins. For this version of implementation the common library + * passes the sequence number of the plugin oid through InitializeFn. The + * sequnece number will be used as the ownerId for the plugin generated OIDs. + */ +typedef MP_STATUS (* InitializeFn) ( + MP_UINT32 pluginOwnerID + ); + +/* + * MP API common library calls TerminateFn as part of dynamically unloading + * the plugins. + */ +typedef MP_STATUS (* TerminateFn) (void); + +/** + ****************************************************************************** + * + * Function table for OID and properties discovery API + * + ****************************************************************************** + */ + +typedef MP_STATUS (* MP_GetPluginPropertiesPluginFn)( + MP_PLUGIN_PROPERTIES *pProps +); + +typedef MP_STATUS (* MP_GetDeviceProductOidListPluginFn)( + MP_OID_LIST **ppList +); + +typedef MP_STATUS (* MP_GetDeviceProductPropertiesFn)( + MP_OID oid, + MP_DEVICE_PRODUCT_PROPERTIES *pProps +); + +typedef MP_STATUS (* MP_GetInitiatorPortOidListPluginFn)( + MP_OID_LIST **ppList +); + +typedef MP_STATUS (* MP_GetInitiatorPortPropertiesFn)( + MP_OID oid, + MP_INITIATOR_PORT_PROPERTIES *pProps +); + +typedef MP_STATUS (* MP_GetMultipathLusPluginFn)( + MP_OID_LIST **ppList +); + +typedef MP_STATUS (* MP_GetMultipathLusDevProdFn)( + MP_OID oid, + MP_OID_LIST **ppList +); + +typedef MP_STATUS (* MP_GetMPLogicalUnitPropertiesFn)( + MP_OID oid, + MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES *pProps +); + +typedef MP_STATUS (* MP_GetAssociatedPathOidListFn)( + MP_OID oid, + MP_OID_LIST **ppList +); + +typedef MP_STATUS (* MP_GetPathLogicalUnitPropertiesFn)( + MP_OID oid, + MP_PATH_LOGICAL_UNIT_PROPERTIES *pProps +); + +typedef MP_STATUS (* MP_GetAssociatedTPGOidListFn)( + MP_OID oid, + MP_OID_LIST **ppList +); + +typedef MP_STATUS (* MP_GetTargetPortGroupPropertiesFn)( + MP_OID oid, + MP_TARGET_PORT_GROUP_PROPERTIES *pProps +); + +typedef MP_STATUS (* MP_GetMPLuOidListFromTPGFn)( + MP_OID oid, + MP_OID_LIST **ppList +); + +typedef MP_STATUS (* MP_GetProprietaryLoadBalanceOidListPluginFn)( + MP_OID_LIST **ppList +); + +typedef MP_STATUS (* MP_GetProprietaryLoadBalancePropertiesFn)( + MP_OID oid, + MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES *pProps +); + +typedef MP_STATUS (* MP_GetTargetPortOidListFn)( + MP_OID oid, + MP_OID_LIST **ppList +); + +typedef MP_STATUS (* MP_GetTargetPortPropertiesFn)( + MP_OID oid, + MP_TARGET_PORT_PROPERTIES *pProps +); + +/** + ****************************************************************************** + * + * Function table for path management API + * + ****************************************************************************** + */ + +typedef MP_STATUS (* MP_AssignLogicalUnitToTPGFn)( + MP_OID tpgOid, + MP_OID luOid +); + +typedef MP_STATUS (* MP_SetOverridePathFn)( + MP_OID logicalUnitOid, + MP_OID pathOid +); + +typedef MP_STATUS (* MP_CancelOverridePathFn)( + MP_OID luOid +); + +typedef MP_STATUS (* MP_EnableAutoFailbackPluginFn)( +); + +typedef MP_STATUS (* MP_EnableAutoFailbackLuFn)( + MP_OID oid +); + +typedef MP_STATUS (* MP_EnableAutoProbingPluginFn)( +); + +typedef MP_STATUS (* MP_EnableAutoProbingLuFn)( + MP_OID oid +); + +typedef MP_STATUS (* MP_DisableAutoFailbackPluginFn)( +); + +typedef MP_STATUS (* MP_DisableAutoFailbackLuFn)( + MP_OID oid +); + +typedef MP_STATUS (* MP_DisableAutoProbingPluginFn)( +); + +typedef MP_STATUS (* MP_DisableAutoProbingLuFn)( + MP_OID oid +); + +typedef MP_STATUS (* MP_EnablePathFn)( + MP_OID oid +); + +typedef MP_STATUS (* MP_DisablePathFn)( + MP_OID oid +); + +typedef MP_STATUS (* MP_SetLogicalUnitLoadBalanceTypeFn)( + MP_OID logicalUnitoid, + MP_LOAD_BALANCE_TYPE loadBalance +); + +typedef MP_STATUS (* MP_SetPathWeightFn)( + MP_OID pathOid, + MP_UINT32 weight +); + +typedef MP_STATUS (* MP_SetPluginLoadBalanceTypePluginFn)( + MP_LOAD_BALANCE_TYPE loadBalance +); + +typedef MP_STATUS (* MP_SetFailbackPollingRatePluginFn)( + MP_UINT32 pollingRate +); + +typedef MP_STATUS (* MP_SetFailbackPollingRateLuFn)( + MP_OID oid, + MP_UINT32 pollingRate +); + +typedef MP_STATUS (* MP_SetProbingPollingRatePluginFn)( + MP_UINT32 pollingRate +); + +typedef MP_STATUS (* MP_SetProbingPollingRateLuFn)( + MP_OID oid, + MP_UINT32 pollingRate +); + +typedef MP_STATUS (* MP_SetProprietaryPropertiesFn)( + MP_OID oid, + MP_UINT32 count, + MP_PROPRIETARY_PROPERTY *pPropertyList +); + +typedef MP_STATUS (* MP_SetTPGAccessFn)( + MP_OID luOid, + MP_UINT32 count, + MP_TPG_STATE_PAIR *pTpgStateList +); + +/** + ****************************************************************************** + * + * Function table for event support API + * + ****************************************************************************** + */ + +typedef MP_STATUS (* MP_RegisterForObjectPropertyChangesPluginFn)( + MP_OBJECT_PROPERTY_FN pClientFn, + MP_OBJECT_TYPE objectType, + void *pCallerData +); + +typedef MP_STATUS (* MP_DeregisterForObjectPropertyChangesPluginFn)( + MP_OBJECT_PROPERTY_FN pClientFn, + MP_OBJECT_TYPE objectType +); + +typedef MP_STATUS (* MP_RegisterForObjectVisibilityChangesPluginFn)( + MP_OBJECT_VISIBILITY_FN pClientFn, + MP_OBJECT_TYPE objectType, + void *pCallerData +); + +typedef MP_STATUS (* MP_DeregisterForObjectVisibilityChangesPluginFn)( + MP_OBJECT_VISIBILITY_FN pClientFn, + MP_OBJECT_TYPE objectType +); + +typedef MP_STATUS (* Sun_MP_SendScsiCmdFn)( + MP_OID oid, struct uscsi_cmd *cmd +); + +#endif + +#ifdef __cplusplus +}; +#endif + diff --git a/usr/src/lib/mpapi/libmpapi/common/mpapi-sun.c b/usr/src/lib/mpapi/libmpapi/common/mpapi-sun.c new file mode 100644 index 0000000000..52ac002e85 --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/common/mpapi-sun.c @@ -0,0 +1,75 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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. + */ + +/* + * Description + * mpapi-sun.c - Implements the Sun Extension to the Multipath Management + * API Version 1.0 + */ + +#include <dlfcn.h> +#include <pthread.h> +#include "mpapi.h" +#include "mpapi-sun.h" +#include "mpapi-plugin.h" + +extern MPPLUGININFO_T plugintable[MP_MAX_NUM_PLUGINS]; + +extern pthread_mutex_t mp_lib_mutex; +extern MP_STATUS validate_object(MP_OID obj, MP_OBJECT_TYPE objType, + MP_UINT32 flag); + +MP_STATUS Sun_MP_SendScsiCmd( + MP_OID pathOid, struct uscsi_cmd *cmd) +{ + Sun_MP_SendScsiCmdFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if ((status = validate_object(pathOid, MP_OBJECT_TYPE_PATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = pathOid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (Sun_MP_SendScsiCmdFn) + dlsym(plugintable[index].hdlPlugin, + "Sun_MP_SendScsiCmd"); + + if (PassFunc != NULL) { + status = PassFunc(pathOid, cmd); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} diff --git a/usr/src/lib/mpapi/libmpapi/common/mpapi-sun.h b/usr/src/lib/mpapi/libmpapi/common/mpapi-sun.h new file mode 100644 index 0000000000..f8f625fe0e --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/common/mpapi-sun.h @@ -0,0 +1,71 @@ + +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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. + */ + +/* + * + * Description + * mpapi-sun.h - general header file for Sun extension to the Multipath + * Management API Version 1.0 client + * + */ + +#ifndef _MPAPI_SUN_H +#define _MPAPI_SUN_H + +#include <sys/scsi/impl/uscsi.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef MPAPI_SUN_H +#define MPAPI_SUN_H + +/** + ****************************************************************************** + * + * The APIs for path management. + * + * - Sun_MP_SendScsiCmd + * + ****************************************************************************** + */ + + +MP_STATUS Sun_MP_SendScsiCmd( + MP_OID pathOid, + struct uscsi_cmd *cmd +); + + +#endif + +#ifdef __cplusplus +}; +#endif + +#endif /* _MPAPI_SUN_H */ diff --git a/usr/src/lib/mpapi/libmpapi/common/mpapi.c b/usr/src/lib/mpapi/libmpapi/common/mpapi.c new file mode 100644 index 0000000000..466b911884 --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/common/mpapi.c @@ -0,0 +1,3668 @@ +/****************************************************************************** + * + * Description + * mpapi.c - Implements Multipath Management API Version 1.0 + * + * License: + * The contents of this file are subject to the SNIA Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://mp-mgmt-api.sourceforge.net + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is SNIA iSCSI Management API and Multipath Management + * API header files. + * + * The Initial Developer of the Original Code is: + * Benjamin F. Kuo Troika Networks, Inc. (benk@troikanetworks.com) + * David Dillard VERITAS Software(david.dillard@veritas.com) + * Jeff Ding Adaptec, Inc. (jding@corp.adaptec.com) + * Hyon Kim Sun Microsystems(hyon.kim@sun.com) + * + * Contributor(s): + * Paul von Behren Sun Microsystems(paul.vonbehren@sun.com) + * + ****************************************************************************** + * + * Changes: + * 1/15/2005 Implemented SNIA MP API specification 1.0 + * 10/11/2005 + * - License location was specified in the header comment. + * - validate_object() routine was updated per the latest + * specification. + * - is_zero_oid() routine was added. + * - MP_GetObjectType() was updated with validate_object(). + * - pplist argument checking added in MP_GetMultipathLus(). + * - Corrected typo in MP_GetTaregetPortGroupProperties() + * - MP_RegisterForObjectPropertyChanges() was updated with + * is_zero_oid() routine. + * - MP_DeregisterForObjectPropertyChanges() was updated with + * is_zero_oid() routine. + * - MP_RegisterForObjectVisibilityChanges() was updated with + * is_zero_oid() routine. + * - MP_DeregisterForObjectVisibilityChanges() was updated with + * is_zero_oid() routine. + * - Added stat() check in MP_RegisterPlugin() to validate the + * the given plugin file name. + * - Made MP_DeregisterPlugin() return MP_STATUS_UNKNOWN_FN + * to mach the specification description. + ****************************************************************************** + */ + +#include <sys/sem.h> +#include <dlfcn.h> +#include <stdarg.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> +#include <stdio.h> +#include <fcntl.h> +#include <time.h> +#include <pthread.h> +#include "mpapi.h" +#include "mpapi-sun.h" +#include "mpapi-plugin.h" + +#define LIBRARY_SUPPORTED_MP_VERSION 1 +#define LIBRARY_IMPLEMENTATION_VERSION L"1.0.0" +#define LIBRARY_VENDOR L"Sun Microsystems Inc." + +#define LIBRARY_FILE_NAME "libMPAPI.so" + + +MPPLUGININFO_T plugintable[MP_MAX_NUM_PLUGINS]; +pthread_mutex_t mp_lib_mutex = PTHREAD_MUTEX_INITIALIZER; + +static int number_of_plugins = -1; + + +void InitLibrary(); +void ExitLibrary(); +static int lock_register(int fd, int cmd, int type, off_t offset, int whence, + off_t len); +static int search_line(MP_CHAR *buf, size_t buflen, MP_CHAR *srch_id, + size_t id_len, int *write_offset, int *bytes_left); +static int is_zero_oid(MP_OID); + +/** + ****************************************************************************** + * + * Validate the oid. + * + * - Return MP_STATUS_OBJECT_NOT_FOUND when no plugin is found or the ownerId + * of input OID is not found. + * - Return MP_STATUS_INVALID_OBJECT_TYPE when no plugin is found or + * the type of input OID is not one of legitimate types defined SNIA + * Multipath Management spec. + * - Return MP_STATUS_INVALID_PARAMETER when the type of input OID is + * legitimate but its object type doesn't match with the object type + * argument. + * - Otherwise return MP_STATUS_SUCCESS. + * + ****************************************************************************** + */ +MP_STATUS validate_object(MP_OID obj, MP_OBJECT_TYPE objType, + MP_UINT32 flag) +{ + + if ((number_of_plugins == 0) || + (obj.ownerId > number_of_plugins || obj.ownerId <= 0)) { + return (MP_STATUS_OBJECT_NOT_FOUND); + } else if (obj.objectType < 0 || obj.objectType > MP_OBJECT_TYPE_MAX) { + return (MP_STATUS_INVALID_OBJECT_TYPE); + } else if (obj.objectType == MP_OBJECT_TYPE_PLUGIN) { + if (obj.objectSequenceNumber != 0) { + return (MP_STATUS_OBJECT_NOT_FOUND); + } + } + + if (flag == MP_OBJECT_TYPE_MATCH) { + if (obj.objectType != objType) { + return (MP_STATUS_INVALID_PARAMETER); + } + } + return (MP_STATUS_SUCCESS); +} + +/** + ****************************************************************************** + * + * Check if an oid is ZERO_OID or not. + * + * - Return 1 if the input OID is ZERO_OID + * + * - Return 0 if not. + * + ****************************************************************************** + */ +static int is_zero_oid(MP_OID oid) +{ + + if ((oid.objectType != MP_OBJECT_TYPE_UNKNOWN) || (oid.ownerId != 0) || + (oid.objectSequenceNumber != 0)) { + return (0); + } + + return (1); +} + +/** + ****************************************************************************** + * + * Initialize by loading plugin libraries and calling Initialize routine. + * Note: The build of libMPAPI.so should include a linker option to make this + * routine executed when it is loaded. + * + * - This routine bypasses a plugin library if it is not found. + * - The implementation of this routine is based on configuration file + * /etc/mpapi.conf that contains a list of plugin libraries. + * + ****************************************************************************** + */ +void InitLibrary() +{ + FILE *mpconf; + int fd_mpconf; + MP_WCHAR fullline[MAX_LINE_SIZE]; /* line read in from mpapi.conf */ + MP_WCHAR name[MAX_NAME_SIZE]; /* Read in from file mpapi.conf */ + char path[MAX_NAME_SIZE]; /* Read in from file mpapi.conf */ + char systemPath[MAX_NAME_SIZE], mpConfFilePath[MAX_NAME_SIZE]; + MP_WCHAR *charPtr; + MP_WCHAR *sol; + struct stat stat_buf; + + MP_UINT32 i = 0; /* index for plugin table */ + + if(number_of_plugins != -1) { + return; + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + number_of_plugins = 0; + + /* Open configuration file from known location */ + strncpy(mpConfFilePath, "/etc/mpapi.conf", MAX_NAME_SIZE); + + if ((fd_mpconf = open(mpConfFilePath, O_RDONLY)) < 0) { + (void) pthread_mutex_unlock(&mp_lib_mutex); + return; + } + + if (lock_register(fd_mpconf, F_SETLKW, F_RDLCK, 0, SEEK_SET, 0) < 0) { + close(fd_mpconf); + (void) pthread_mutex_unlock(&mp_lib_mutex); + return; + } + + if ((mpconf = fdopen(fd_mpconf, "r")) == NULL) { + lock_register(fd_mpconf, F_SETLK, F_UNLCK, 0, SEEK_SET, 0); + close(fd_mpconf); + (void) pthread_mutex_unlock(&mp_lib_mutex); + return; + } + + /* Read in each line and load library */ + while ((mpconf != NULL) && + (charPtr = fgetws(fullline, MAX_LINE_SIZE, mpconf))) { + if ((*charPtr != L'#') && (*charPtr != L'\n')) { + /* Take out the '\n' */ + if ((charPtr = wcschr(fullline, L'\n')) != NULL) + *charPtr = L'\0'; + + charPtr = fullline; + /* remove leading blank or taps. */ + while ((fullline[0] == L' ') || (fullline[0] == L'\t')) + charPtr++; + + sol = charPtr; + + /* + * look for first tab or space. + */ + if ((charPtr = wcschr(fullline, L'\t')) == NULL) + charPtr = wcschr(fullline, L' '); + + /* Set Null termination for library name if found */ + if (charPtr != NULL) { + *charPtr++ = L'\0'; + wcsncpy(name, sol, MAX_NAME_SIZE); + /* Skip space and tab until the next character found */ + while ((*charPtr == L' ') || (*charPtr == L'\t')) + charPtr++; + } else { + continue; /* May be invalid entry */ + } + + /* Copy library name and path */ + wcstombs(path, charPtr, MAX_NAME_SIZE); + + /* + * Continue to the next line if library name or path is + * invalid + */ + if ((wcslen(name) == 0) || + (strlen(path) == 0)) + continue; + + /* Load the plugin now */ + if (stat(path, &stat_buf) != -1) { + plugintable[i].hdlPlugin = dlopen(path, RTLD_LAZY); + } else { + continue; + } + + if (plugintable[i].hdlPlugin != NULL) { + InitializeFn PassFunc; + MP_STATUS status; + + wcsncpy(plugintable[i].pluginName, + name, MAX_NAME_SIZE); + strncpy(plugintable[i].pluginPath, + path, MAX_NAME_SIZE); + + plugintable[i].ownerId = i + 1; + + PassFunc = (InitializeFn) + dlsym(plugintable[i].hdlPlugin, "Initialize"); + if (PassFunc != NULL) { + status = PassFunc(plugintable[i].ownerId); + } + + i++; + } + } + } + + if (lock_register(fd_mpconf, F_SETLK, F_UNLCK, 0, SEEK_SET, 0) < 0) { + fclose(mpconf); + close(fd_mpconf); + (void) pthread_mutex_unlock(&mp_lib_mutex); + return; + } + fclose(mpconf); + close(fd_mpconf); + + number_of_plugins = i; + (void) pthread_mutex_unlock(&mp_lib_mutex); +} + +/** + ****************************************************************************** + * + * Exit by calling Terminate routine of plugin libraries. + * + * Note: The build of libMPAPI.so should include a linker option to make this + * routine executed when it is unloaded. + * + ****************************************************************************** + */ +void ExitLibrary() +{ + MP_UINT32 i, j; + + if(number_of_plugins == -1) + return; + + (void) pthread_mutex_lock(&mp_lib_mutex); + for (i = 0; i < number_of_plugins; i++) { + if (plugintable[i].hdlPlugin != NULL) { + TerminateFn ExitPassFunc; + + ExitPassFunc = (TerminateFn) + dlsym(plugintable[i].hdlPlugin, "Terminate"); + + if (ExitPassFunc != NULL) { + ExitPassFunc(); + } + + /* Unload plugin from memory */ + dlclose(plugintable[i].hdlPlugin); + } + } + + number_of_plugins = -1; + + (void) pthread_mutex_unlock(&mp_lib_mutex); + (void) pthread_mutex_destroy(&mp_lib_mutex); +} + +/** + ****************************************************************************** + * + * Gets the properties of the MP API library that is being used. + * + * @param pProps + * A pointer to an @ref MP_LIBRARY_PROPERTIES structure allocated by + * the caller. On successful return this structure will contain the + * properties of the MP library. + * + * @return An MP_STATUS indicating if the operation was successful or + * if an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned if the library properties were successfully returned. + * + * @retval MP_STATUS_INVALID_PARAMETER Returned if @a pProps is NULL or + * specifies a memory area to which data cannot be written. + * + ****************************************************************************** + */ +MP_STATUS MP_GetLibraryProperties( + MP_LIBRARY_PROPERTIES *pProps) +{ + char mpPath[MAX_NAME_SIZE]; + + if(pProps == NULL) { + return MP_STATUS_INVALID_PARAMETER; + } + + /* Fill in properties */ + if (mbstowcs(pProps->buildTime, BUILD_TIME, 256) != + strlen(BUILD_TIME)) { + return (MP_STATUS_INVALID_PARAMETER); + } + pProps->supportedMpVersion = LIBRARY_SUPPORTED_MP_VERSION; + + wcsncpy(pProps->implementationVersion, + LIBRARY_IMPLEMENTATION_VERSION, MAX_NAME_SIZE); + wcsncpy(pProps->vendor, LIBRARY_VENDOR, MAX_NAME_SIZE); + + snprintf(pProps->fileName, MAX_NAME_SIZE, "%s", + LIBRARY_FILE_NAME); + + return MP_STATUS_SUCCESS; +} + + +/** + ****************************************************************************** + * + * Gets a list of the object IDs of all currently loaded plugins. + * + * @param ppList A pointer to a pointer to an @ref MP_OID_LIST. On successful + * return this will contain a pointer to an @ref MP_OID_LIST + * which contains the object IDs of all of the plugins currently loaded + * by the library. + * @return An MP_STATUS indicating if the operation was successful or if + * an error + * occurred. + * @retval MP_SUCCESS Returned if the plugin ID list was successfully returned. + * @retval MP_STATUS_INVALID_PARAMETER Returned if @a ppList is NULL or + * specifies a memory area to which data cannot be written. + * + ****************************************************************************** + */ +MP_STATUS MP_GetPluginOidList( + MP_OID_LIST **ppList) +{ + MP_UINT32 i; + + if (ppList == NULL) + return (MP_STATUS_INVALID_PARAMETER); + + (void) pthread_mutex_lock(&mp_lib_mutex); + + if (number_of_plugins == 0) { + *ppList = (MP_OID_LIST*)calloc(1, sizeof(MP_OID_LIST)); + } else { + *ppList = (MP_OID_LIST*)calloc(1, + sizeof(MP_OID_LIST) + (number_of_plugins - 1)* sizeof(MP_OID) ); + } + + if ((*ppList) == NULL) { + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (*ppList)->oidCount = number_of_plugins; + + if (number_of_plugins != 0) { + for (i = 0; i < number_of_plugins; i++) { + (*ppList)->oids[i].objectType = MP_OBJECT_TYPE_PLUGIN; + (*ppList)->oids[i].ownerId = plugintable[i].ownerId; + (*ppList)->oids[i].objectSequenceNumber = 0; + } + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return MP_STATUS_SUCCESS; +} + +/** + ******************************************************************************* + * + * Gets the properties of the specified vendor plugin. + * + * @param oid + * The ID of the plugin whose properties are being retrieved. + * + * @param pProps + * A pointer to an @ref MP_PLUGIN_PROPERTIES structure allocated by + * the caller. On successful return this will contain the properties + * of the plugin specified by pluginOid. + * + * @return An MP_STATUS indicating if the operation was successful or if an + * error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned if the plugin properties were successfully returned. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if 'pProps' is NULL or specifies a memory area to + * which data cannot be written. + * + ******************************************************************************* + */ +MP_STATUS MP_GetPluginProperties( + MP_OID pluginOid, + MP_PLUGIN_PROPERTIES *pProps) +{ + MP_GetPluginPropertiesPluginFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if(pProps == NULL) + return (MP_STATUS_INVALID_PARAMETER); + + if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = pluginOid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetPluginPropertiesPluginFn) + dlsym(plugintable[index].hdlPlugin, "MP_GetPluginPropertiesPlugin"); + + if (PassFunc != NULL) { + status = PassFunc(pProps); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return status; +} + +/** + ******************************************************************************* + * + * Gets the object ID for the plugin associated with the specified object ID. + * + * @param oid + * The object ID of an object that has been received from a previous + * library call. + * + * @param pPluginOid + * A pointer to an MP_OID structure allocated by the caller. On + * successful return this will contain the object ID of the plugin + * associated with the object specified by @a objectId. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned if the associated plugin ID was successfully returned. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid does not specify a plugin that is currently known to + * the system. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if 'oid' specifies an object not owned by a plugin or + * if pPluginOid is NULL or specifies a memory area to which data + * cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if 'oid' specifies an object with an invalid type. + * + ******************************************************************************* + */ +MP_STATUS MP_GetAssociatedPluginOid( + MP_OID objectId, + MP_OID *pPluginId) +{ + MP_UINT32 i; + MP_STATUS status; + + if (pPluginId == NULL) + return (MP_STATUS_INVALID_PARAMETER); + + if ((status = validate_object(objectId, 0, MP_OBJECT_TYPE_ANY)) != + MP_STATUS_SUCCESS) { + return (status); + } + + pPluginId->objectType = MP_OBJECT_TYPE_PLUGIN; + pPluginId->ownerId = objectId.ownerId; + pPluginId->objectSequenceNumber = 0; + + return (MP_STATUS_SUCCESS); +} + +/** + ******************************************************************************* + * + * Gets the object type of an initialized object ID. + * + * @param oid + * The object ID of an object that has been received from a previous + * library call. + * + * @param pObjectType + * A pointer to an MP_OBJECT_TYPE variable allocated by the caller. + * On successful return this will contain the object type of oid. + * + * @return An MP_STATUS indicating if the operation was successful or + * if an error occurred. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + ******************************************************************************* + */ +MP_STATUS MP_GetObjectType( + MP_OID oid, + MP_OBJECT_TYPE *pObjectType) +{ + MP_STATUS status; + + if (pObjectType == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, 0, MP_OBJECT_TYPE_ANY)) + != MP_STATUS_SUCCESS) { + return (status); + } + + *pObjectType = oid.objectType; + return MP_STATUS_SUCCESS; +} + +/** + ******************************************************************************* + * + * Gets a list of the object IDs of all the device product properties + * associated with this plugin. + * + * @param oid + * The object ID of plugin. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the device + * product descriptors associated with the specified plugin. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the device product list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the API is not supported. + * + ******************************************************************************* + */ +MP_STATUS MP_GetDeviceProductOidList( + MP_OID oid, + MP_OID_LIST **ppList) +{ + MP_GetDeviceProductOidListPluginFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (ppList == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetDeviceProductOidListPluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetDeviceProductOidListPlugin"); + if (PassFunc != NULL) { + status = PassFunc(ppList); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return status; +} + +/** + ******************************************************************************* + * + * Gets the device product properties of the specified plugin oid. + * + * @param oid + * The object ID of the plugin. + * + * @param ppProps + * A pointer to a pointer to an MP_DEVICE_PRODUCT_PROPERTIES structure + * allocated by the caller. On successful return it will contain + * a pointer to an MP_DEVICE_PRODUCT_PROPERTIES structure allocated + * by the library. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppProps pointer passed as placeholder for holding + * the device product properties is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the API is not supported. + * + ******************************************************************************* + */ +MP_STATUS MP_GetDeviceProductProperties( + MP_OID oid, + MP_DEVICE_PRODUCT_PROPERTIES *pProps) +{ + MP_GetDeviceProductPropertiesFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (pProps == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_DEVICE_PRODUCT, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetDeviceProductPropertiesFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetDeviceProductProperties"); + + if (PassFunc != NULL) { + status = PassFunc(oid, pProps); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return status; +} + +/** + ******************************************************************************* + * + * Gets a list of the object IDs of all the initiator ports associated + * with this plugin. + * + * @param oid + * The object ID of plugin. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the initiator + * ports associated with the specified plugin. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the initiator port list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the API is not supported. + * + ******************************************************************************* + */ +MP_STATUS MP_GetInitiatorPortOidList( + MP_OID oid, + MP_OID_LIST **ppList) +{ + MP_GetInitiatorPortOidListPluginFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (ppList == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetDeviceProductOidListPluginFn) + dlsym(plugintable[index].hdlPlugin, "MP_GetInitiatorPortOidListPlugin"); + + if (PassFunc != NULL) { + status = PassFunc(ppList); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Gets the properties of the specified initiator port. + * + * @param oid + * The object ID of the initiator port. + * + * @param pProps + * A pointer to an MP_INITIATOR_PORT_PROPERTIES structure + * allocated by the caller. On successful return, this structure + * will contain the properties of the port specified by oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pProps is NULL or specifies a memory area to + * which data cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetInitiatorPortProperties( + MP_OID oid, + MP_INITIATOR_PORT_PROPERTIES *pProps) +{ + MP_GetInitiatorPortPropertiesFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (pProps == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_INITIATOR_PORT, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetInitiatorPortPropertiesFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetInitiatorPortProperties"); + + if (PassFunc != NULL) { + status = PassFunc(oid, pProps); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return status; +} + +/** + ******************************************************************************* + * + * Gets a list of multipath logical units associated to a plugin. + * + * @param oid + * The object ID of plugin. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the multipath + * logical units associated with the specified plugin. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the multipath logical unit list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the API is not supported. + * + ******************************************************************************* + */ +MP_STATUS MP_GetMultipathLus( + MP_OID oid, + MP_OID_LIST **ppList) +{ + MP_UINT32 index; + MP_STATUS status; + + if (ppList == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) && + ((status = validate_object(oid, MP_OBJECT_TYPE_DEVICE_PRODUCT, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) { + MP_GetMultipathLusPluginFn PassFunc; + PassFunc = (MP_GetMultipathLusPluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetMultipathLusPlugin"); + + if (PassFunc != NULL) { + status = PassFunc(ppList); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else if (oid.objectType == MP_OBJECT_TYPE_DEVICE_PRODUCT) { + MP_GetMultipathLusDevProdFn PassFunc; + PassFunc = (MP_GetMultipathLusDevProdFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetMultipathLusDevProd"); + + if (PassFunc != NULL) { + status = PassFunc(oid, ppList); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_INVALID_PARAMETER; + } + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + + +/** + ******************************************************************************* + * + * Gets the properties of the specified logical unit. + * + * @param oid + * The object ID of the multipath logical unit. + * + * @param pProps + * A pointer to an MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES structure + * allocated by the caller. On successful return, this structure + * will contain the properties of the port specified by oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pProps is NULL or specifies a memory area to + * which data cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetMPLogicalUnitProperties( + MP_OID oid, + MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES *pProps) +{ + MP_GetMPLogicalUnitPropertiesFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (pProps == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetMPLogicalUnitPropertiesFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetMPLogicalUnitProperties"); + + if (PassFunc != NULL) { + status = PassFunc(oid, pProps); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Gets a list of the object IDs of all the path logical units associated + * with the specified multipath logical unit, initiator port, or target port. + * + * @param oid + * The object ID of multipath logical unit, initiator port, or + * target port. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the mp path + * logical units associated with the specified OID. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the device product list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetAssociatedPathOidList( + MP_OID oid, + MP_OID_LIST **ppList) +{ + MP_GetAssociatedPathOidListFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (ppList == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if (((status = validate_object(oid, MP_OBJECT_TYPE_INITIATOR_PORT, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) && + ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) && + ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetAssociatedPathOidListFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetAssociatedPathOidList"); + + if (PassFunc != NULL) { + status = PassFunc(oid, ppList); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Gets the properties of the specified path logical unit. + * + * @param oid + * The object ID of the path logical unit. + * + * @param pProps + * A pointer to an MP_PATH_LOGICAL_UNIT_PROPERTIES structure + * allocated by the caller. On successful return, this structure + * will contain the properties of the port specified by oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pProps is NULL or specifies a memory area to + * which data cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetPathLogicalUnitProperties( + MP_OID oid, + MP_PATH_LOGICAL_UNIT_PROPERTIES *pProps) +{ + MP_GetPathLogicalUnitPropertiesFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (pProps == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_PATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetPathLogicalUnitPropertiesFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetPathLogicalUnitProperties"); + + if (PassFunc != NULL) { + status = PassFunc(oid, pProps); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Gets a list of the object IDs of all the target port group associated + * with the specified multipath logical unit. + * + * @param oid + * The object ID of the multiple logical unit. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the target + * port group associated with the specified multipath logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the target port group list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * + ******************************************************************************* + */ +MP_STATUS MP_GetAssociatedTPGOidList( + MP_OID oid, + MP_OID_LIST **ppList) +{ + MP_GetAssociatedTPGOidListFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (ppList == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetAssociatedTPGOidListFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetAssociatedTPGOidList"); + + if (PassFunc != NULL) { + status = PassFunc(oid, ppList); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Gets the properties of the specified target port group. + * + * @param oid + * The object ID of the target port group. + * + * @param pProps + * A pointer to an MP_TARGET_PORT_GROUP_PROPERTIES structure + * allocated by the caller. On successful return, this structure + * will contain the properties of the port specified by oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pProps is NULL or specifies a memory area to + * which data cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetTargetPortGroupProperties( + MP_OID oid, + MP_TARGET_PORT_GROUP_PROPERTIES *pProps) +{ + MP_GetTargetPortGroupPropertiesFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (pProps == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT_GROUP, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetTargetPortGroupPropertiesFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetTargetPortGroupProperties"); + + if (PassFunc != NULL) { + status = PassFunc(oid, pProps); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Gets a list of multipath logical units associated with the specific target + * port group. + * + * @param oid + * The object ID of the target port group. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the multipath + * logical units associated with the specified target port group. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the multipath logical unit list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + ******************************************************************************* + */ +MP_STATUS MP_GetMPLuOidListFromTPG( + MP_OID oid, + MP_OID_LIST **ppList) +{ + MP_GetMPLuOidListFromTPGFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (ppList == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT_GROUP, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetMPLuOidListFromTPGFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetMPLuOidListFromTPG"); + + if (PassFunc != NULL) { + status = PassFunc(oid, ppList); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Gets a list of the object IDs of all the proprietary load balance + * algorithms associated with this plugin. + * + * @param oid + * The object ID of the plugin. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the proprietary + * load balance algorithms associated with the specified plugin. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the proprietary load balance oid list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the API is not supported. + * + ******************************************************************************* + */ +MP_STATUS MP_GetProprietaryLoadBalanceOidList( + MP_OID oid, + MP_OID_LIST **ppList) +{ + MP_GetProprietaryLoadBalanceOidListPluginFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (ppList == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetProprietaryLoadBalanceOidListPluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetProprietaryLoadBalanceOidListPlugin"); + + if (PassFunc != NULL) { + status = PassFunc(ppList); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Gets the properties of the specified load balance properties structure. + * + * @param oid + * The object ID of the load balance properties structure. + * + * @param pProps + * A pointer to an MP_LOAD_BALANCE_PROPRIETARY_TYPE structure + * allocated by the caller. On successful return, this structure + * will contain the properties of the proprietary load balance algorithm + * specified by oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pProps is NULL or specifies a memory area to + * which data cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetProprietaryLoadBalanceProperties ( + MP_OID oid, + MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES *pProps) +{ + MP_GetProprietaryLoadBalancePropertiesFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (pProps == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetProprietaryLoadBalancePropertiesFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetProprietaryLoadBalanceProperties"); + + if (PassFunc != NULL) { + status = PassFunc(oid, pProps); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Gets a list of the object IDs of the target ports in the specified target + * port group. + * + * @param oid + * The object ID of the target port group. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the target ports + * associated with the specified target port group. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the multipath logical unit list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + ******************************************************************************* + */ +MP_STATUS MP_GetTargetPortOidList( + MP_OID oid, + MP_OID_LIST **ppList) +{ + MP_GetTargetPortOidListFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (ppList == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT_GROUP, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetTargetPortOidListFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetTargetPortOidList"); + + if (PassFunc != NULL) { + status = PassFunc(oid, ppList); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Gets the properties of the specified target port. + * + * @param oid + * The object ID of the target port. + * + * @param pProps + * A pointer to an MP_TARGET_PORT_PROPERTIES structure + * allocated by the caller. On successful return, this structure + * will contain the properties of the port specified by oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pProps is NULL or specifies a memory area to + * which data cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetTargetPortProperties( + MP_OID oid, + MP_TARGET_PORT_PROPERTIES *pProps) +{ + MP_GetTargetPortPropertiesFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (pProps == NULL) + return MP_STATUS_INVALID_PARAMETER; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_GetTargetPortPropertiesFn) + dlsym(plugintable[index].hdlPlugin, + "MP_GetTargetPortProperties"); + + if (PassFunc != NULL) { + status = PassFunc(oid, pProps); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + + +/** + ******************************************************************************* + * + * Assign a multipath logical unit to a target port group. + * + * @param tpgOid + * An MP_TARGET_PORT_GROUP oid. The target port group currently in + * active access state that the administrator would like the LU + * assigned to. + * + * @param luOid + * An MP_MULTIPATH_LOGICAL_UNIT oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned when luOid is not associated with tpgOid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_AssignLogicalUnitToTPG( + MP_OID tpgOid, + MP_OID luOid) +{ + MP_AssignLogicalUnitToTPGFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (luOid.ownerId != tpgOid.ownerId) { + return (MP_STATUS_INVALID_PARAMETER); + } + + if ((status = validate_object(tpgOid, MP_OBJECT_TYPE_TARGET_PORT_GROUP, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + if ((status = validate_object(luOid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = tpgOid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_AssignLogicalUnitToTPGFn) + dlsym(plugintable[index].hdlPlugin, + "MP_AssignLogicalUnitToTPG"); + + if (PassFunc != NULL) { + status = PassFunc(tpgOid, luOid); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Manually override the path for a logical unit. The path exclusively used to + * access the logical unit until cleared. + * + * @param logicalUnitOid + * The object ID of the multipath logical unit. + * + * @param pathOid + * The object ID of the path logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if the oid of the object is not valid + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_PATH_NONOPERATIONAL + * Returned when the driver cannot communicate through selected path. + * + ******************************************************************************* + */ +MP_STATUS MP_SetOverridePath( + MP_OID logicalUnitOid, + MP_OID pathOid) +{ + MP_SetOverridePathFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if ((status = validate_object(logicalUnitOid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + if ((status = validate_object(pathOid, MP_OBJECT_TYPE_PATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = pathOid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_SetOverridePathFn) + dlsym(plugintable[index].hdlPlugin, + "MP_SetOverridePath"); + + if (PassFunc != NULL) { + status = PassFunc(logicalUnitOid, pathOid); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Cancel a path override and re-enable load balancing. + * + * @param luOid + * An MP_MULTIPATH_LOGICAL_UNIT oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if MP_MULTIPATH_LOGICAL_UNIT with the luOid is not found. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_CancelOverridePath( + MP_OID luOid) +{ + MP_CancelOverridePathFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if ((status = validate_object(luOid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = luOid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_CancelOverridePathFn) + dlsym(plugintable[index].hdlPlugin, + "MP_CancelOverridePath"); + + if (PassFunc != NULL) { + status = PassFunc(luOid); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Enables Auto-failback. + * + * @param oid + * The oid of the plugin. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid is NULL or specifies a memory area that is not + * a valid plugin oid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_EnableAutoFailback( + MP_OID oid) +{ + MP_UINT32 index; + MP_STATUS status; + + if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) && + ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) { + MP_EnableAutoFailbackPluginFn PassFunc; + PassFunc = (MP_EnableAutoFailbackPluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_EnableAutoFailbackPlugin"); + + if (PassFunc != NULL) { + status = PassFunc(); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) { + MP_EnableAutoFailbackLuFn PassFunc; + PassFunc = (MP_EnableAutoFailbackLuFn) + dlsym(plugintable[index].hdlPlugin, + "MP_EnableAutoFailbackLu"); + + if (PassFunc != NULL) { + status = PassFunc(oid); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_INVALID_PARAMETER; + } + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Enables Auto-probing. + * + * @param oid + * The oid of the plugin or the multipath logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid is NULL or specifies a memory area that is not + * a valid plugin oid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_EnableAutoProbing( + MP_OID oid) +{ + MP_UINT32 index; + MP_STATUS status; + + if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) && + ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) { + MP_EnableAutoProbingPluginFn PassFunc; + PassFunc = (MP_EnableAutoProbingPluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_EnableAutoProbingPlugin"); + + if (PassFunc != NULL) { + status = PassFunc(); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) { + MP_EnableAutoProbingLuFn PassFunc; + PassFunc = (MP_EnableAutoProbingLuFn) + dlsym(plugintable[index].hdlPlugin, + "MP_EnableAutoProbingLu"); + + if (PassFunc != NULL) { + status = PassFunc(oid); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_INVALID_PARAMETER; + } + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Disables Auto-failback. + * + * @param oid + * The oid of the plugin. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid is NULL or specifies a memory area that is not + * a valid plugin oid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_DisableAutoFailback( + MP_OID oid) +{ + MP_UINT32 index; + MP_STATUS status; + + if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) && + ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) { + MP_DisableAutoFailbackPluginFn PassFunc; + PassFunc = (MP_DisableAutoFailbackPluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_DisableAutoFailbackPlugin"); + + if (PassFunc != NULL) { + status = PassFunc(); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) { + MP_DisableAutoFailbackLuFn PassFunc; + PassFunc = (MP_DisableAutoFailbackLuFn) + dlsym(plugintable[index].hdlPlugin, + "MP_DisableAutoFailbackLu"); + + if (PassFunc != NULL) { + status = PassFunc(oid); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_INVALID_PARAMETER; + } + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Disables Auto-probing. + * + * @param oid + * The oid of the plugin or the multipath logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid is NULL or specifies a memory area that is not + * a valid plugin oid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_DisableAutoProbing( + MP_OID oid) +{ + MP_UINT32 index; + MP_STATUS status; + + if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) && + ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) { + MP_DisableAutoProbingPluginFn PassFunc; + PassFunc = (MP_DisableAutoProbingPluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_DisableAutoProbingPlugin"); + + if (PassFunc != NULL) { + status = PassFunc(); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) { + MP_DisableAutoFailbackLuFn PassFunc; + PassFunc = (MP_DisableAutoProbingLuFn) + dlsym(plugintable[index].hdlPlugin, + "MP_DisableAutoProbingLu"); + + if (PassFunc != NULL) { + status = PassFunc(oid); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_INVALID_PARAMETER; + } + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Enables a path. This API may cause failover in a logical unit with + * asymmetric access. + * + * @param oid + * The oid of the path. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid is NULL or specifies a memory area that is not + * a valid path oid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_EnablePath( + MP_OID oid) +{ + MP_EnablePathFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_PATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_EnablePathFn) + dlsym(plugintable[index].hdlPlugin, + "MP_EnablePath"); + + if (PassFunc != NULL) { + status = PassFunc(oid); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Disables a path. This API may cause failover in a logical unit with + * asymmetric access. This API may cause a logical unit to become unavailable. + * + * @param oid + * The oid of the path. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid is NULL or specifies a memory area that is not + * a valid path oid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_DisablePath( + MP_OID oid) +{ + MP_DisablePathFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_PATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_DisablePathFn) + dlsym(plugintable[index].hdlPlugin, + "MP_DisablePath"); + + if (PassFunc != NULL) { + status = PassFunc(oid); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Set the multipath logical unit s load balancing policy. + * + * @param logicalUnitoid + * The object ID of the multipath logical unit. + * + * @param loadBanlance + * The desired load balance policy for the specified logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if no MP_MULTIPATH_LOGICAL_UNIT associated with + * @ref ligicalUnitrOid is found or invalid MP_LOAD_BALANCE_TYPE is + * specified. + * + * @retval MP_STATUS_FAILED + * Returned when the specified loadBalance type cannot be handled + * by the plugin. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_SetLogicalUnitLoadBalanceType( + MP_OID logicalUnitOid, + MP_LOAD_BALANCE_TYPE loadBalance) +{ + MP_SetLogicalUnitLoadBalanceTypeFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if ((status = validate_object(logicalUnitOid, + MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = logicalUnitOid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_SetLogicalUnitLoadBalanceTypeFn) + dlsym(plugintable[index].hdlPlugin, + "MP_SetLogicalUnitLoadBalanceType"); + + if (PassFunc != NULL) { + status = PassFunc(logicalUnitOid, loadBalance); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Set the weight to be assigned to a particular path. + * + * @param pathOid + * The object ID of the path logical unit. + * + * @param weight + * weight that will be assigned to the path logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned when the MP Path specified by the PathOid could not be + * found. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the operation failed. + * + * @retval MP_STATUS_PATH_NONOPERATIONAL + * Returned when the driver cannot communicate through selected path. + * + * @retval MP_STATUS_INVALID_WEIGHT + * Returned when the weight parameter is greater than the plugin's + * maxWeight property. + * + ******************************************************************************* + */ +MP_STATUS MP_SetPathWeight( + MP_OID pathOid, + MP_UINT32 weight) +{ + MP_SetPathWeightFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if ((status = validate_object(pathOid, MP_OBJECT_TYPE_PATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = pathOid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_SetPathWeightFn) + dlsym(plugintable[index].hdlPlugin, + "MP_SetPathWeight"); + + if (PassFunc != NULL) { + status = PassFunc(pathOid, weight); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Set the default load balance policy for the plugin. + * + * @param oid + * The object ID of the plugin + * + * @param loadBalance + * The desired default load balance policy for the specified plugin. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned when the the plugin specified by @ref oid could not be + * found. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if the oid of the object is not valid. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the specified loadBalance type cannot be handled + * by the plugin. + * + ******************************************************************************* + */ +MP_STATUS MP_SetPluginLoadBalanceType( + MP_OID oid, + MP_LOAD_BALANCE_TYPE loadBalance) +{ + MP_SetPluginLoadBalanceTypePluginFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_SetPluginLoadBalanceTypePluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_SetPluginLoadBalanceTypePlugin"); + + if (PassFunc != NULL) { + status = PassFunc(loadBalance); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Set the failback polling rates. Setting both rates to zero disables polling. + * + * @param pluginOid + * The object ID of the plugin or multipath lu. + * + * @param pollingRate + * The value to be set in MP_PLUGIN_PROPERTIES currentPollingRate.or + * MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES pollingRate. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned when the the plugin specified by @ref oid could not be + * found. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if one of the polling values is outside the range + * supported by the driver. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_SetFailbackPollingRate( + MP_OID oid, + MP_UINT32 pollingRate) +{ + MP_UINT32 index; + MP_STATUS status; + + if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) && + ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) { + MP_SetFailbackPollingRatePluginFn PassFunc; + PassFunc = (MP_SetFailbackPollingRatePluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_SetFailbackPollingRatePlugin"); + + if (PassFunc != NULL) { + status = PassFunc(pollingRate); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) { + MP_SetFailbackPollingRateLuFn PassFunc; + PassFunc = (MP_SetFailbackPollingRateLuFn) + dlsym(plugintable[index].hdlPlugin, + "MP_SetFailbackPollingRateLu"); + + if (PassFunc != NULL) { + status = PassFunc(oid, pollingRate); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_INVALID_PARAMETER; + } + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Set the probing polling rates. Setting both rates to zero disables polling. + * + * @param pluginOid + * The object ID of either the plugin or a multipath logical unit. + * + * @param pollingRate + * The value to be set in MP_PLUGIN_PROPERTIES current pollingRate or + * MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES pollingRate. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned when the the plugin specified by @ref oid could not be + * found. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if one of the polling values is outside the range + * supported by the driver. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_SetProbingPollingRate( + MP_OID oid, + MP_UINT32 pollingRate) +{ + MP_UINT32 index; + MP_STATUS status; + + if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) && + ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) { + MP_SetProbingPollingRatePluginFn PassFunc; + PassFunc = (MP_SetProbingPollingRatePluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_SetProbingPollingRatePlugin"); + + if (PassFunc != NULL) { + status = PassFunc(pollingRate); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) { + MP_SetProbingPollingRateLuFn PassFunc; + PassFunc = (MP_SetProbingPollingRateLuFn) + dlsym(plugintable[index].hdlPlugin, + "MP_SetProbingPollingRateLu"); + + if (PassFunc != NULL) { + status = PassFunc(oid, pollingRate); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_INVALID_PARAMETER; + } + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Set proprietary properties in supported object instances. + * + * @param pluginOid + * The object ID of MP_LOAD_BALANCE_PROPRIETARY_TYPE, MP_PLUGIN_PROPERTIES + * or MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES. + * + * @param count + * The number of valid items in pPropertyList. + * + * @param pPropertyList + * A pointer to an array of property name/value pairs. This array must + * contain the same number of elements as count. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned when the the plugin specified by @ref oid could not be + * found. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if one of the polling values is outside the range + * supported by the driver. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_SetProprietaryProperties( + MP_OID oid, + MP_UINT32 count, + MP_PROPRIETARY_PROPERTY *pPropertyList) +{ + MP_SetProprietaryPropertiesFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) && + ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) && + ((status = validate_object(oid, MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = oid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_SetProprietaryPropertiesFn) + dlsym(plugintable[index].hdlPlugin, + "MP_SetProprietaryProperties"); + + if (PassFunc != NULL) { + status = PassFunc(oid, count, pPropertyList); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Set the access state for a list of target port groups. This allows + * a client to force a failover or failback to a desired set of target port + * groups. + * + * @param luOid + * The object ID of the logical unit where the command is sent. + * + * @param count + * The number of valid items in the pTpgStateList. + * + * @param pTpgStateList + * A pointer to an array of TPG/access-state values. This array must + * contain the same number of elements as @ref count. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned when the MP_MULTIPATH_LOGICAL_UNIT associated with @ref + * oid could not be found. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pTpgStateList is null or if one of the TPGs referenced + * in the list is not associated with the specified MP logical unit. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_ACCESS_STATE_INVALID + * Returned if the target device returns a status indicating the caller + * is attempting to establish an illegal combination of access states. + * + * @retval MP_STATUS_FAILED + * Returned if the underlying interface failed the commend for some + * reason other than MP_STATUS_ACCESS_STATE_INVALID + * + ******************************************************************************* + */ +MP_STATUS MP_SetTPGAccess( + MP_OID luOid, + MP_UINT32 count, + MP_TPG_STATE_PAIR *pTpgStateList) +{ + MP_SetTPGAccessFn PassFunc; + MP_UINT32 index; + MP_STATUS status; + + if ((status = validate_object(luOid, MP_OBJECT_TYPE_MULTIPATH_LU, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + index = luOid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_SetTPGAccessFn) + dlsym(plugintable[index].hdlPlugin, + "MP_SetTPGAccess"); + + if (PassFunc != NULL) { + status = PassFunc(luOid, count, pTpgStateList); + } else { + status = MP_STATUS_UNSUPPORTED; + } + } else { + status = MP_STATUS_FAILED; + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Registers a client function that is to be called + * whenever the property of an an object changes. + * + * @param pClientFn, + * A pointer to an MP_OBJECT_PROPERTY_FN function defined by the + * client. On successful return this function will be called to + * inform the client of objects that have had one or more properties + * change. + * + * @param objectType + * The type of object the client wishes to deregister for + * property change callbacks. If null, then all objects types are + * deregistered. + * + * @param pCallerData + * A pointer that is passed to the callback routine with each event. + * This may be used by the caller to correlate the event to source of + * the registration. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pClientFn is NULL or specifies a memory area + * that is not executable. + * + * @retval MP_STATUS_FN_REPLACED + * Returned when an existing client function is replaced with the one + * specified in pClientFn. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_RegisterForObjectPropertyChanges( + MP_OBJECT_PROPERTY_FN pClientFn, + MP_OBJECT_TYPE objectType, + void *pCallerData, + MP_OID pluginOid) +{ + MP_RegisterForObjectPropertyChangesPluginFn PassFunc; + MP_UINT32 i; + MP_UINT32 index; + MP_STATUS status; + + if (pClientFn == NULL) { + return (MP_STATUS_INVALID_PARAMETER); + } + + if (objectType > MP_OBJECT_TYPE_MAX) { + return (MP_STATUS_INVALID_OBJECT_TYPE); + } + + if (!(is_zero_oid(pluginOid))) { + if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + if (is_zero_oid(pluginOid)) { + for (i = 0; i < number_of_plugins; i++) { + if (plugintable[i].hdlPlugin != NULL) { + PassFunc = (MP_RegisterForObjectPropertyChangesPluginFn) + dlsym(plugintable[i].hdlPlugin, + "MP_RegisterForObjectPropertyChangesPlugin"); + } + + if (PassFunc != NULL) { + status = + PassFunc(pClientFn, objectType, pCallerData); + /* ignore an error and continue */ + } + } + } else { + index = pluginOid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_RegisterForObjectPropertyChangesPluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_RegisterForObjectPropertyChangesPlugin"); + } + + if (PassFunc != NULL) { + status = PassFunc(pClientFn, objectType, pCallerData); + } + } + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Deregisters a previously registered client function that is to be invoked + * whenever an object's property changes. + * + * @param pClientFn, + * A pointer to an MP_OBJECT_PROPERTY_FN function defined by the + * client that was previously registered using + * the MP_RegisterForObjectPropertyChanges API. On successful return + * this function will no longer be called to inform the client of + * object property changes. + * + * @param objectType + * The type of object the client wishes to deregister for + * property change callbacks. If null, then all objects types are + * deregistered. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pClientFn is NULL or specifies a memory area + * that is not executable. + * + * @retval MP_STATUS_UNKNOWN_FN + * Returned if pClientFn is not the same as the previously registered + * function. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned if pClientFn deregistration is not possible at this time. + * + ******************************************************************************* + */ +MP_STATUS MP_DeregisterForObjectPropertyChanges( + MP_OBJECT_PROPERTY_FN pClientFn, + MP_OBJECT_TYPE objectType, + MP_OID pluginOid) +{ + MP_DeregisterForObjectPropertyChangesPluginFn PassFunc; + MP_UINT32 i; + MP_UINT32 index; + MP_STATUS status; + + if (pClientFn == NULL) { + return (MP_STATUS_INVALID_PARAMETER); + } + + if (objectType > MP_OBJECT_TYPE_MAX) { + return (MP_STATUS_INVALID_OBJECT_TYPE); + } + + if (!(is_zero_oid(pluginOid))) { + if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + if (is_zero_oid(pluginOid)) { + for (i = 0; i < number_of_plugins; i++) { + if (plugintable[i].hdlPlugin != NULL) { + PassFunc = (MP_DeregisterForObjectPropertyChangesPluginFn) + dlsym(plugintable[i].hdlPlugin, + "MP_DeregisterForObjectPropertyChangesPlugin"); + } + + if (PassFunc != NULL) { + status = PassFunc(pClientFn, objectType); + } + } + } else { + index = pluginOid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_DeregisterForObjectPropertyChangesPluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_DeregisterForObjectPropertyChangesPlugin"); + } + + if (PassFunc != NULL) { + status = PassFunc(pClientFn, objectType); + } + } + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Registers a client function that is to be called + * whenever a high level object appears or disappears. + * + * @param pClientFn, + * A pointer to an MP_OBJECT_VISIBILITY_FN function defined by the + * client. On successful return this function will be called to + * inform the client of objects whose visibility has changed. + * + * @param objectType + * The type of object the client wishes to deregister for + * property change callbacks. If null, then all objects types are + * deregistered. + * + * @param pCallerData + * A pointer that is passed to the callback routine with each event. + * This may be used by the caller to correlate the event to source of + * the registration. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pClientFn is NULL or specifies a memory area + * that is not executable. + * + * @retval MP_STATUS_FN_REPLACED + * Returned when an existing client function is replaced with the one + * specified in pClientFn. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if objectType does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_RegisterForObjectVisibilityChanges( + MP_OBJECT_VISIBILITY_FN pClientFn, + MP_OBJECT_TYPE objectType, + void *pCallerData, + MP_OID pluginOid) +{ + MP_RegisterForObjectVisibilityChangesPluginFn PassFunc; + MP_UINT32 i; + MP_UINT32 index; + MP_STATUS status; + + if (pClientFn == NULL) { + return (MP_STATUS_INVALID_PARAMETER); + } + + if (objectType > MP_OBJECT_TYPE_MAX) { + return (MP_STATUS_INVALID_OBJECT_TYPE); + } + + if (!(is_zero_oid(pluginOid))) { + if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + if (is_zero_oid(pluginOid)) { + for (i = 0; i < number_of_plugins; i++) { + if (plugintable[i].hdlPlugin != NULL) { + PassFunc = (MP_RegisterForObjectVisibilityChangesPluginFn) + dlsym(plugintable[i].hdlPlugin, + "MP_RegisterForObjectVisibilityChangesPlugin"); + } + + if (PassFunc != NULL) { + status = PassFunc(pClientFn, objectType, pCallerData); + /* ignore an error and continue. */ + } + } + } else { + index = pluginOid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_RegisterForObjectVisibilityChangesPluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_RegisterForObjectVisibilityChangesPlugin"); + } + + if (PassFunc != NULL) { + status = PassFunc(pClientFn, objectType, pCallerData); + } + } + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); + +} + +/** + ******************************************************************************* + * + * Deregisters a previously registered client function that is to be invoked + * whenever a high level object appears or disappears. + * + * @param pClientFn, + * A pointer to an MP_OBJECT_VISIBILITY_FN function defined by the + * client that was previously registered using + * the MP_RegisterForObjectVisibilityChanges API. On successful return + * this function will no longer be called to inform the client of + * object property changes. + * + * @param objectType + * The type of object the client wishes to deregister for visibility + * change callbacks. If null, then all objects types are + * deregistered. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pClientFn is NULL or specifies a memory area + * that is not executable. + * + * @retval MP_STATUS_UNKNOWN_FN + * Returned if pClientFn is not the same as the previously registered + * function. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if objectType does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned if pClientFn deregistration is not possible at this time. + * + ******************************************************************************* + */ +MP_STATUS MP_DeregisterForObjectVisibilityChanges( + MP_OBJECT_VISIBILITY_FN pClientFn, + MP_OBJECT_TYPE objectType, + MP_OID pluginOid) +{ + MP_DeregisterForObjectVisibilityChangesPluginFn PassFunc; + MP_UINT32 i; + MP_UINT32 index; + MP_STATUS status; + + if (pClientFn == NULL) { + return (MP_STATUS_INVALID_PARAMETER); + } + + if (objectType > MP_OBJECT_TYPE_MAX) { + return (MP_STATUS_INVALID_OBJECT_TYPE); + } + + if (!(is_zero_oid(pluginOid))) { + if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN, + MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) { + return (status); + } + } + + (void) pthread_mutex_lock(&mp_lib_mutex); + + if (is_zero_oid(pluginOid)) { + for (i = 0; i < number_of_plugins; i++) { + if (plugintable[i].hdlPlugin != NULL) { + PassFunc = (MP_DeregisterForObjectVisibilityChangesPluginFn) + dlsym(plugintable[i].hdlPlugin, + "MP_DeregisterForObjectVisibilityChangesPlugin"); + if (PassFunc != NULL) { + status = PassFunc(pClientFn, objectType); + } + } + } + } else { + index = pluginOid.ownerId - 1; + if (plugintable[index].hdlPlugin != NULL) { + PassFunc = (MP_DeregisterForObjectVisibilityChangesPluginFn) + dlsym(plugintable[index].hdlPlugin, + "MP_DeregisterForObjectVisibilityChangesPlugin"); + if (PassFunc != NULL) { + status = PassFunc(pClientFn, objectType); + } + } + } + + (void) pthread_mutex_unlock(&mp_lib_mutex); + return (status); +} + +/** + ******************************************************************************* + * + * Compare two Oids for equality to see whether they refer to the same object. + * + * @param oid1 + * Oid to compare. + * + * @param oid2 + * Oid to compare. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the two Oids do refer to the same object. + * + * @retval MP_STATUS_FAILED + * Returned if the Oids don't compare. + * + ******************************************************************************* + */ +MP_STATUS MP_CompareOIDs( + MP_OID oid1, + MP_OID oid2) +{ + if ((oid1.objectType == oid2.objectType) && (oid1.ownerId == oid2.ownerId) + && (oid1.objectSequenceNumber == oid2.objectSequenceNumber)) { + return (MP_STATUS_SUCCESS); + } else { + return (MP_STATUS_FAILED); + } +} + +/** + ******************************************************************************* + * + * Frees memory returned by an MP API. + * + * @param pOidList + * A pointer to the memory returned by an MP API. On successful + return, the allocated memory is freed. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when pPluginId is deregistered successfully. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pMemory is NULL or specifies a memory area to which + * data cannot be written. + * + ******************************************************************************* + */ +MP_STATUS MP_FreeOidList(MP_OID_LIST *pOidList) +{ + if (pOidList == NULL) { + return (MP_STATUS_INVALID_PARAMETER); + } + + free(pOidList); + + return (MP_STATUS_SUCCESS); +} + +static MP_CHAR *HDR = +"#\n" +"# This file contains names and references to MP API plugin libraries\n" +"#\n" +"# Do NOT manually edit this file\n" +"#\n" +"# Format:\n" +"#\n" +"# <library ID> <library pathname>\n" +"#\n"; + +#define CLEANUP_N_RET(fd, ret) \ + if (lock_register(fd, F_SETLK, F_UNLCK, 0, SEEK_SET, 0) < 0) { \ + close(fd); \ + return (MP_STATUS_FAILED); \ + } \ + close(fd); \ + return (ret) + +/* + * This function sets an advisory lock on the file pointed to by the argument + * fd, which is a file descriptor. The lock is set using fcntl() which uses + * flock structure. + */ +static int +lock_register(int fd, int cmd, int type, off_t offset, int whence, off_t len) +{ + struct flock lock; + + lock.l_type = type; + lock.l_start = offset; + lock.l_whence = whence; + lock.l_len = len; + + return (fcntl(fd, cmd, &lock)); +} + +/* + * This function searches for "srch_str" (of length "slen") in "buf" (of length + * "buflen"). If it is not found, "write_offset" has the offset in "buf" where + * "srch_str" would have to be added in "buf". If "srch_str" is found in "buf", + * "write_offset" has its offset in "buf" + * + * ARGUMENTS : + * buf - buffer to search in + * buflen - length of buffer + * srch_id - id to search + * id_len - length of srch_id + * write_offset - Set in function on exit + * - It is the offset in buf where srch_str is or should be + * bytes_left - Set in function on exit + * - It is the # of bytes left beyond write_offset in buf + * RETURN VALUES : + * Zero - "srch_id" found in "buf"... "write_offset" has offset in "buf" + * != 0 - "srch_str" NOT found in "buf" ... "write_offset" points to the end of + * "buf". + */ +static int +search_line(MP_CHAR *buf, size_t buflen, MP_CHAR *srch_id, size_t id_len, + int *write_offset, int *bytes_left) +{ + int retval, sizeof_conf_hdr = strlen(HDR); + MP_CHAR *sol; /* Pointer to Start-Of-Line */ + MP_CHAR *cur_pos; /* current position */ + + *bytes_left = buflen; + *write_offset = 0; + + if (buf == NULL || buflen <= 0) + return (-1); + + if (srch_id == NULL || id_len <= 0) + return (0); + + sol = cur_pos = buf; + + /* + * mp conf file should not be edited but takes care of + * any extra white space when parsing the line. + * + * The line should have id + delimiter + name + newline. + */ + while (*bytes_left >= (id_len + 3)) { + /* skip leading blank or space. */ + while ((*cur_pos == ' ') || (*cur_pos == '\t')) { + cur_pos++; + } + + if (strncmp(cur_pos, srch_id, id_len) == 0) { + /* id matched. */ + cur_pos += id_len; + + while (*cur_pos != '\n') { + cur_pos++; + } + *write_offset = (sol - buf); + *bytes_left = buflen - ((cur_pos + 1) - buf); + return (0); + } else { + /* move to the next line */ + while (*cur_pos != '\n') { + cur_pos++; + } + *bytes_left = buflen - ((cur_pos + 1) - buf); + } + sol = cur_pos = cur_pos + 1; + } + + /* Given strings are not found. */ + *write_offset = buflen; + return (-1); +} + +/** + ******************************************************************************* + * + * Registers a plugin with common library. The implementation of this routine + * is based on configuration file /etc/mpapi.conf that contains a list of + * plugin libraries. + * + * @param pPluginId + * A pointer to the key name shall be the reversed domain name of + * the vendor followed by followed by the vendor specific name for + * the plugin that uniquely identifies the plugin. Should be NULL + * terminated. + * + * @param pFileName + * The full path to the plugin library. + * Should be NULL terminated. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when pPluginId is deregistered successfully. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pPluginId is NULL or specifies a memory area that + * is not executable. + * + * @retval MP_STATUS_FAILED + * Returned if pClientFn deregistration is not possible at this time. + * + ******************************************************************************* + */ +MP_STATUS MP_RegisterPlugin( + MP_WCHAR *pPluginId, + char *pFileName) +{ + int mpconf, bytes_left, write_offset; + MP_CHAR fullline[MAX_LINE_SIZE]; /* Full line to add to mpapi.conf */ + MP_CHAR *mpconf_buf; + MP_CHAR pluginid[MAX_NAME_SIZE]; + char systemPath[MAX_NAME_SIZE], mpConfFilePath[MAX_NAME_SIZE]; + MP_UINT32 new_file_flag = 0; + MP_UINT32 sizeof_conf_hdr = strlen(HDR); + struct stat stbuf; + + if ((pPluginId == NULL) || (pFileName == NULL)) { + return (MP_STATUS_INVALID_PARAMETER); + } + + if (stat(pFileName, &stbuf) != 0) { + return (MP_STATUS_INVALID_PARAMETER); + } + + if (wcstombs(pluginid, pPluginId, MAX_NAME_SIZE) != wcslen(pPluginId)) { + return (MP_STATUS_INVALID_PARAMETER); + } + + *fullline = '\0'; + strncpy(fullline, pluginid, MAX_NAME_SIZE); + /* add tab */ + strncat(fullline, "\t", MAX_LINE_SIZE - strlen(pluginid)); + strncat(fullline, pFileName, MAX_LINE_SIZE - strlen(pluginid) - 1); + /* add a new line. */ + strncat(fullline, "\n", + MAX_LINE_SIZE - strlen(pluginid) - strlen(pFileName) -1); + + /* Open configuration file from known location */ + strncpy(mpConfFilePath, "/etc/mpapi.conf", MAX_NAME_SIZE); + + if ((chmod(mpConfFilePath, S_IRUSR|S_IRGRP|S_IROTH) == -1) && + (errno == ENOENT)) { + new_file_flag = 1; + } + + if ((mpconf = open(mpConfFilePath, O_RDWR | O_CREAT)) == -1) { + return (MP_STATUS_FAILED); + } + + if (fchmod(mpconf, S_IRUSR | S_IRGRP | S_IROTH) < 0) { + close(mpconf); + return (MP_STATUS_FAILED); + } + + if (lock_register(mpconf, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0) < 0) { + close(mpconf); + return (MP_STATUS_FAILED); + } + + if (fstat(mpconf, &stbuf) == -1) { + CLEANUP_N_RET(mpconf, MP_STATUS_FAILED); + } + + if ((new_file_flag) || (stbuf.st_size == 0)) { + if (write(mpconf, HDR, sizeof_conf_hdr) != + sizeof_conf_hdr) { + CLEANUP_N_RET(mpconf, MP_STATUS_FAILED); + } + + if (pwrite(mpconf, fullline, strlen(fullline), + sizeof_conf_hdr) != + strlen(fullline)) { + CLEANUP_N_RET(mpconf, MP_STATUS_FAILED); + } + CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS); + } + + if ((mpconf_buf = (MP_CHAR *)mmap(0, stbuf.st_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, mpconf, 0)) == MAP_FAILED) { + CLEANUP_N_RET(mpconf, MP_STATUS_FAILED); + } + + if (search_line(mpconf_buf, stbuf.st_size, + pluginid, strlen(pluginid), &write_offset, &bytes_left) == 0) { + /* found a match. */ + munmap((void *)mpconf_buf, stbuf.st_size); + CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS); + } else { + munmap((void *)mpconf_buf, stbuf.st_size); + /* append the fullline to the mpconf. */ + if (pwrite(mpconf, fullline, strlen(fullline), + write_offset) != + strlen(fullline)) { + CLEANUP_N_RET(mpconf, MP_STATUS_FAILED); + } else { + CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS); + } + } +} + +/** + ******************************************************************************* + * + * Deregisters a plugin from the common library. This routine is based on + * configuration file /etc/mpapi.conf that contains a list of plugin libraries. + * + * @param pPluginId + * A pointer to a Plugin ID previously registered using + * the MP_RegisterPlugin API.. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when pPluginId is deregistered successfully. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pPluginId is NULL or specifies a memory area that + * is not executable. + * + * @retval MP_STATUS_FAILED + * Returned if pClientFn deregistration is not possible at this time. + * + ******************************************************************************* + */ +MP_STATUS MP_DeregisterPlugin( + MP_WCHAR *pPluginId) +{ + int mpconf, tmp_mpconf, bytes_left, write_offset; + char systemPath[MAX_NAME_SIZE], mpConfFilePath[MAX_NAME_SIZE], + tmp_mpConfFilePath[MAX_NAME_SIZE + sizeof(pid_t)]; + MP_CHAR pluginid[MAX_NAME_SIZE]; + MP_CHAR *mpconf_buf; + MP_UINT32 sizeof_conf_hdr = strlen(HDR); + struct stat stbuf; + + if (pPluginId == NULL) { + return (MP_STATUS_INVALID_PARAMETER); + } + + if (wcstombs(pluginid, pPluginId, MAX_NAME_SIZE) != wcslen(pPluginId)) { + return (MP_STATUS_INVALID_PARAMETER); + } + + /* Open configuration file from known location */ + strncpy(mpConfFilePath, "/etc/mpapi.conf", MAX_NAME_SIZE); + + if ((chmod(mpConfFilePath, S_IRUSR|S_IRGRP|S_IROTH) == -1) && + (errno == ENOENT)) { + /* no file found */ + return (MP_STATUS_UNKNOWN_FN); + } + + if ((mpconf = open(mpConfFilePath, O_RDWR)) == -1) { + return (MP_STATUS_FAILED); + } + + if (fchmod(mpconf, S_IRUSR | S_IRGRP | S_IROTH) < 0) { + close(mpconf); + return (MP_STATUS_FAILED); + } + + if (lock_register(mpconf, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0) < 0) { + close(mpconf); + return (MP_STATUS_FAILED); + } + + if (fstat(mpconf, &stbuf) == -1) { + CLEANUP_N_RET(mpconf, MP_STATUS_FAILED); + } + + if (stbuf.st_size == 0) { + CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS); + } + + if ((mpconf_buf = (MP_CHAR *)mmap(0, stbuf.st_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, mpconf, 0)) == MAP_FAILED) { + CLEANUP_N_RET(mpconf, MP_STATUS_FAILED); + } + + if (search_line(mpconf_buf, stbuf.st_size, pluginid, strlen(pluginid), + &write_offset, &bytes_left) != 0) { + munmap((void *)mpconf_buf, stbuf.st_size); + CLEANUP_N_RET(mpconf, MP_STATUS_UNKNOWN_FN); + } else { + /* + * found a match. + * construct temp file name using pid. + */ + (void) snprintf(tmp_mpConfFilePath, MAX_NAME_SIZE, + "%s%ld", "/etc/mpapi.conf", getpid()); + + if ((tmp_mpconf = open(tmp_mpConfFilePath, + O_RDWR|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR)) < 0) { + CLEANUP_N_RET(mpconf, MP_STATUS_FAILED); + } + + if (write(tmp_mpconf, mpconf_buf, write_offset) != write_offset) { + close(tmp_mpconf); + CLEANUP_N_RET(mpconf, MP_STATUS_FAILED); + } + + if (pwrite(tmp_mpconf, mpconf_buf + (stbuf.st_size - bytes_left), + bytes_left, write_offset) != bytes_left) { + close(tmp_mpconf); + CLEANUP_N_RET(mpconf, MP_STATUS_FAILED); + } + + close(tmp_mpconf); + munmap((void *)mpconf_buf, stbuf.st_size); + + /* rename temp file to mpConfFile before unlock and close. */ + if (rename(tmp_mpConfFilePath, mpConfFilePath) != 0) { + CLEANUP_N_RET(mpconf, MP_STATUS_FAILED); + } else { + CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS); + } + } +} diff --git a/usr/src/lib/mpapi/libmpapi/common/mpapi.conf b/usr/src/lib/mpapi/libmpapi/common/mpapi.conf new file mode 100644 index 0000000000..f7ea9c6b2d --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/common/mpapi.conf @@ -0,0 +1,32 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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. +# +# This file contains names and references to MP API plugin libraries +# +# Do NOT manually edit this file +# +# Format: +# +# <library ID> <library pathname> +# diff --git a/usr/src/lib/mpapi/libmpapi/common/mpapi.h b/usr/src/lib/mpapi/libmpapi/common/mpapi.h new file mode 100644 index 0000000000..3c2e0f180c --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/common/mpapi.h @@ -0,0 +1,2593 @@ +/****************************************************************************** + * + * Description + * mpapi.h - general header file for Multipath Management API Version 1.0 + * client + * + * License: + * The contents of this file are subject to the SNIA Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://mp-mgmt-api.sourceforge.net + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is SNIA iSCSI Management API and Multipath Management API + * general header file + * + * The Initial Developer of the Original Code is: + * Benjamin F. Kuo Troika Networks, Inc. (benk@troikanetworks.com) + * David Dillard VERITAS Software(david.dillard@veritas.com) + * Jeff Ding Adaptec, Inc. (jding@corp.adaptec.com) + * Dave Wysochanski Network Appliance, Inc. (davidw@netapp.com) + * Hyon Kim Sun Microsystems(hyon.kim@sun.com) + * + * Contributor(s): + * Paul von Behren Sun Microsystems(paul.vonbehren@sun.com) + * + ****************************************************************************** + * + * Changes: + * 1/15/2005 Implemented SNIA MP API specification 1.0 + * 10/11/2005 + * - Added the license location in the header comment. + * - Added an implementation note in constants and macros + * declarations section. + * - Fixed field name value in struct _MP_PROPRIETARY_PROPERTY. + * - Fixed typo in logicalUnitGroupID in + * _MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES + * - Fixed typo in desiredState in struct _MP_TPG_STATE_PAIR. + * - Fixed typo in API name MP_GetTargetPortGroupProperties. + * - Clarified description of MP_STATUS_INVALID_PARAMETER error + * in MP_GetObjectType(). + * - Fixed typo in API name + * MP_GetProprietaryLoadBalanceProperties(). + * 3/6/2006 + * - mpapi.h header file is updated for + * MP_LOAD_BALANCE_TYPE change in the spec. + *****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef MPAPI_H +#define MPAPI_H + +#include <time.h> +#include <wchar.h> +#include <string.h> +#include <stdlib.h> + + +/* Library version string */ +#define MP_LIBVERSION 1 + +/** + ******************************************************************************* + * + * Generic MP Constant Definitions + * + ******************************************************************************* + */ +#define RL_LIBRARY_SEQNUM 0 + +/** +* Value which can be assigned to an MP_BOOL and or an MP_XBOOL. +*/ +#define MP_TRUE 1 + +/** +* Value which can be assigned to an MP_BOOL and or an MP_XBOOL. +*/ +#define MP_FALSE 0 + +/** +* Value which can be assigned to an MP_XBOOL. +*/ +#define MP_UNKNOWN 0xFFFFFFFF + +#define MP_MAX_NUM_PLUGINS 64 +#define MP_OBJECT_TYPE_MATCH 1 +#define MP_OBJECT_TYPE_ANY 2 +#define MAX_NAME_SIZE 256 +#define MAX_LINE_SIZE 515 + + +/** + ****************************************************************************** + * + * Base MP API Type Definitions + * + ****************************************************************************** + */ + +typedef unsigned char MP_UINT8; /* unsigned 8 bits */ +typedef char MP_INT8; /* signed 8 bits */ +typedef unsigned short MP_UINT16; /* unsigned 16 bits */ +typedef short MP_INT16; /* signed 16 bits */ +typedef unsigned int MP_UINT32; /* unsigned 32 bits */ +typedef int MP_INT32; /* signed 32 bits */ +typedef void* MP_PVOID; /* pointer to void */ +typedef MP_UINT32 MP_VOID32; /* opaque 32 bits */ +typedef long long MP_INT64; /* signed 64 bits */ +typedef unsigned long long MP_UINT64; /* unsigned 64 bits */ + +/** + * A character. + */ +typedef char MP_CHAR; + +/** + * A wide character. + */ +typedef wchar_t MP_WCHAR; + +/** + * An unsigned character. + */ +typedef unsigned char MP_BYTE; + +/** + * A boolean. + */ +typedef MP_UINT32 MP_BOOL; + +/** + * An extended boolean: can have the values @ref MP_TRUE, @ref MP_FALSE, and + * @ref MP_UNKNOWN. + */ +typedef MP_UINT32 MP_XBOOL; + +/** + ****************************************************************************** + * + * Constants and macros declarations related to MP_STATUS + * Implementation Notes: This library does validation for OID argument and + * returns the following errors. + * + * 1. MP_STATUS_INVALID_OBJECT_TYPE when input OID type is not + * one of legitimate types defined SNIA Multipath Management + * Spec. + * 2. MP_STATUS_INVALID_PARAMETER when input OID type is + * legitimate but not a proper type for API. + * 3. MP_STATUS_OBJECT_NOT_FOUND when the ownerId of input OID is + * not found or no object instance with matching + * sequenceNumber is found. + * The ownerId is validated by the common library and the + * sequence number is validated by the plugin library. + * + ****************************************************************************** + */ +typedef enum { + MP_STATUS_SUCCESS = 0, + MP_STATUS_INVALID_PARAMETER = 1, + MP_STATUS_UNKNOWN_FN = 2, + MP_STATUS_FAILED = 3, + MP_STATUS_INSUFFICIENT_MEMORY = 4, + MP_STATUS_INVALID_OBJECT_TYPE = 5, + MP_STATUS_OBJECT_NOT_FOUND = 6, + MP_STATUS_UNSUPPORTED = 7, + MP_STATUS_FN_REPLACED = 8, + MP_STATUS_ACCESS_STATE_INVALID = 9, + MP_STATUS_INVALID_WEIGHT = 10, + MP_STATUS_PATH_NONOPERATIONAL = 11, + MP_STATUS_TRY_AGAIN = 12, + MP_STATUS_NOT_PERMITTED = 13 + +} MP_STATUS; + +/** + ****************************************************************************** + * + * Declaration of the MP_PATH_STATE constants + * + ****************************************************************************** + */ +#define MP_PATH_STATE_OKAY 0 +#define MP_PATH_STATE_PATH_ERR 1 +#define MP_PATH_STATE_LU_ERR 2 +#define MP_PATH_STATE_RESERVED 3 +#define MP_PATH_STATE_REMOVED 4 +#define MP_PATH_STATE_TRANSITIONING 5 +#define MP_PATH_STATE_OPERATIONAL_CLOSED 6 +#define MP_PATH_STATE_INVALID_CLOSED 7 +#define MP_PATH_STATE_OFFLINE_CLOSED 8 +#define MP_PATH_STATE_UNKNOWN 9 + +typedef MP_UINT32 MP_PATH_STATE; + +/** + ******************************************************************************* + * + * Declaration of the MP_OBJECT_TYPE constants + * + ******************************************************************************* + */ +#define MP_OBJECT_TYPE_UNKNOWN 0 +#define MP_OBJECT_TYPE_PLUGIN 1 +#define MP_OBJECT_TYPE_INITIATOR_PORT 2 +#define MP_OBJECT_TYPE_TARGET_PORT 3 +#define MP_OBJECT_TYPE_MULTIPATH_LU 4 +#define MP_OBJECT_TYPE_PATH_LU 5 +#define MP_OBJECT_TYPE_DEVICE_PRODUCT 6 +#define MP_OBJECT_TYPE_TARGET_PORT_GROUP 7 +#define MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE 8 + +/* set to the highest constant of object type. */ +#define MP_OBJECT_TYPE_MAX 8 + +typedef MP_UINT32 MP_OBJECT_TYPE; + +/** + ******************************************************************************* + * + * Declaration of the MP_PORT_TRANSPORT_TYPE + * + ******************************************************************************* + */ +#define MP_PORT_TRANSPORT_TYPE_UNKNOWN 0 +#define MP_PORT_TRANSPORT_TYPE_MPNODE 1 +#define MP_PORT_TRANSPORT_TYPE_FC 2 +#define MP_PORT_TRANSPORT_TYPE_SPI 3 +#define MP_PORT_TRANSPORT_TYPE_ISCSI 4 +#define MP_PORT_TRANSPORT_TYPE_IFB 5 + +typedef MP_UINT32 MP_PORT_TRANSPORT_TYPE; + +/** + ******************************************************************************* + * + * Declaration of the MP_ACCESS_STATE_TYPE constants + * + ******************************************************************************* + */ +#define MP_ACCESS_STATE_ACTIVE_OPTIMIZED (0x0) +#define MP_ACCESS_STATE_ACTIVE_NONOPTIMIZED (0x1) +#define MP_ACCESS_STATE_STANDBY (0x2) +#define MP_ACCESS_STATE_UNAVAILABLE (0x3) +#define MP_ACCESS_STATE_TRANSITIONING (0xF) +#define MP_ACCESS_STATE_ACTIVE (0x10) + +typedef MP_UINT32 MP_ACCESS_STATE_TYPE; + +/** + ******************************************************************************* + * + * Declaration of the MP_LOAD_BALANCE_TYPE constants + * + ******************************************************************************* + */ +#define MP_LOAD_BALANCE_TYPE_UNKNOWN (1<<0) +#define MP_LOAD_BALANCE_TYPE_ROUNDROBIN (1<<1) +#define MP_LOAD_BALANCE_TYPE_LEASTBLOCKS (1<<2) +#define MP_LOAD_BALANCE_TYPE_LEASTIO (1<<3) +#define MP_LOAD_BALANCE_TYPE_DEVICE_PRODUCT (1<<4) +#define MP_LOAD_BALANCE_TYPE_LBA_REGION (1<<5) +#define MP_LOAD_BALANCE_TYPE_FAILOVER_ONLY (1<<6) +/** + * Proprietary load balance type should start from 0x10000(1<<16) or greater. + * It is exposed through API MP_GetProprietaryLoadBalanceProperties if exists. + */ + +typedef MP_UINT32 MP_LOAD_BALANCE_TYPE; + +typedef struct mpPluginInfo { + MP_WCHAR pluginName[MAX_NAME_SIZE]; + MP_CHAR pluginPath[MAX_NAME_SIZE]; + void* hdlPlugin; + MP_UINT32 ownerId; +} MPPLUGININFO_T; + + +/** + ******************************************************************************* + * + * Declaration of the MP_PROPRIETARY_PROPERTY + * + ******************************************************************************* + */ +typedef struct _MP_PROPRIETARY_PROPERTY +{ + MP_WCHAR name[16]; + MP_WCHAR value[48]; + +} MP_PROPRIETARY_PROPERTY; + +/** + ******************************************************************************* + * + * Declaration of the MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES + * + ******************************************************************************* + */ +typedef struct _MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES +{ + MP_LOAD_BALANCE_TYPE typeIndex; + MP_WCHAR name[256]; + MP_WCHAR vendorName[256]; + MP_UINT32 proprietaryPropertyCount; + MP_PROPRIETARY_PROPERTY proprietaryProperties[8]; + +} MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES; + +/** + ******************************************************************************* + * + * Declaration of the MP_UINT32 MP_LOGICAL_UNIT_NAME_TYPE constants + * + ******************************************************************************* + */ +#define MP_LU_NAME_TYPE_UNKNOWN 0 +#define MP_LU_NAME_TYPE_VPD83_TYPE1 1 +#define MP_LU_NAME_TYPE_VPD83_TYPE2 2 +#define MP_LU_NAME_TYPE_VPD83_TYPE3 3 +#define MP_LU_NAME_TYPE_DEVICE_SPECIFIC 4 + +typedef MP_UINT32 MP_LOGICAL_UNIT_NAME_TYPE; + +/** + ******************************************************************************* + * + * Declaration of the MP_UINT32 MP_AUTOFAILBACK_SUPPORT constants + * + ******************************************************************************* + */ +#define MP_AUTOFAILBACK_SUPPORT_NONE 0 +#define MP_AUTOFAILBACK_SUPPORT_PLUGIN 1 +#define MP_AUTOFAILBACK_SUPPORT_MPLU 2 +#define MP_AUTOFAILBACK_SUPPORT_PLUGINANDMPLU 3 + +typedef MP_UINT32 MP_AUTOFAILBACK_SUPPORT; + +/** + ******************************************************************************* + * + * Declaration of the MP_UINT32 MP_AUTOPROBING_SUPPORT constants + * + ******************************************************************************* + */ +#define MP_AUTOPROBING_SUPPORT_NONE 0 +#define MP_AUTOPROBING_SUPPORT_PLUGIN 1 +#define MP_AUTORPOBING_SUPPORT_MPLU 2 +#define MP_AUTORPOBING_SUPPORT_PLUGINANDMPLU 3 + +typedef MP_UINT32 MP_AUTOPROBING_SUPPORT; + +/** + ******************************************************************************* + * + * Declaration of the MP_OID structure + * + * This structure should be treated as opaque by clients of the API. + * Appropriate APIs should be used to extract information from the structure. + * + * Also ZERO_OID is defined for APIs that may handle multiple plugin OIDs. + * + ******************************************************************************* + */ +typedef struct _MP_OID +{ + /** + * The type of the object. When an object ID is supplied as a parameter + * to an API the library uses this value to insure that the supplied + * object ID's type is appropriate for the API. + */ + MP_OBJECT_TYPE objectType; + + /** + * A value determined by the library which it uses to uniquely identify the + * owner of an object. The owner of an object is either the library itself + * or a plugin. When an object ID is supplied as a parameter to an API the + * library uses this value to determine if it should handle the call itself + * or direct the call to one or more plugins. + */ + MP_UINT32 ownerId; + + /** + * A value determined by a plugin which a plugin uses, perhaps in + * combination with the object type, to uniquely identify one of its + * objects. + */ + MP_UINT64 objectSequenceNumber; + +} MP_OID; + +#define ZERO_OID ((const MP_OID){MP_OBJECT_TYPE_UNKNOWN,0,0}) + +/** + ******************************************************************************* + * + * Declaration of the MP_OID_LIST structure + * + * This structure is used by a number of APIs to return lists of objects. Any + * instance of this structure returned by an API must be freed by a client + * using the MP_FreeOidList API. Although oids is declared to be an + * array of one + * @ref MP_OID structure it can in fact contain any number of + * @ref MP_OID structures. The oidCount indicates the number of @ref MP_OID + * structures in the oids array. + * + * @note The @a oids array is a variable length array, despite its declaration + * below it can be of any length. + * + ******************************************************************************* + */ +typedef struct _MP_OID_LIST +{ + /** + * The number of object IDs in the @a oids array. + */ + MP_UINT32 oidCount; + + /** + * A variable length array of zero or more object IDs. There are + * 'oidCount' object IDs in this array. + */ + MP_OID oids[1]; + +} MP_OID_LIST; + +/** + ******************************************************************************* + * + * Declaration of the MP_LIBRARY_PROPERTIES structure + * + * This structure is returned by the MP_GetLibraryProperties() API. + * + ******************************************************************************* + */ +typedef struct _MP_LIBRARY_PROPERTIES +{ + /** + * The version of the Multipath Management API implemented by the library. + */ + MP_UINT32 supportedMpVersion; + + /** + * A null terminated ASCII string containing the name of the vendor that + * created the binary version of the library. + */ + MP_WCHAR vendor[256]; + + /** + * A null terminated ASCII string containing the implementation version + * of the library from the vendor specified in the 'vendor' field. + */ + MP_WCHAR implementationVersion[256]; + + /** + * A null terminated ASCII string ideally containing the path and file + * name of the library that is being used by the currently executing + * process can be found. If the path cannot be determined then it is + * acceptable to fill this field with only the name (and extension if + * applicable) of the file of the library. If this cannot be determined + * then this field should be an empty string. + */ + MP_CHAR fileName[256]; + + /** + * The time and date that the library that is executing was built. + */ + MP_WCHAR buildTime[256]; + +} MP_LIBRARY_PROPERTIES; + +/** + ******************************************************************************* + * + * Declaration of the MP_PLUGIN_PROPERTIES structure + * + * This structure is returned by the MP_GetPluginProperties() API. + * + ******************************************************************************* + */ +typedef struct _MP_PLUGIN_PROPERTIES +{ + /** + * The version of the Multipath Management API implemented by a plugin. + */ + MP_UINT32 supportedMpVersion; + + /** + * A null terminated Unicode string containing the name of the vendor that + * created the binary version of the plugin. + */ + MP_WCHAR vendor[256]; + + /** + * A null terminated Unicode string containing the implementation version + * of the plugin from the vendor specified in vendor. + */ + MP_WCHAR implementationVersion[256]; + + /** + * A null terminated ASCII string ideally containing the path and file + * name of the plugin that is filling in this structure. + */ + MP_CHAR fileName[256]; + + /** + * The time and date that the plugin that is executing was built. + */ + MP_WCHAR buildTime[256]; + + /** + * A null terminated Unicode string containing the name of the multipath + * driver vendor associated with this plugin. + */ + MP_WCHAR driverVendor[256]; + + /** + * A null terminated Unicode string ideally containing the path and file + * name of the plugin that is filling in this structure. + */ + MP_CHAR driverName[256]; + + /** + * A null terminated Unicode string containing the version number of + * the multipath driver. + */ + MP_WCHAR driverVersion[256]; + + /** + * A set of flags representing the load balance types + * (MP_LOAD_BALANCE_TYPES) supported by the plugin/driver as a plugin-wide + * property. + */ + MP_UINT32 supportedLoadBalanceTypes; + + /** + * boolean indicating whether the implementation supports activating target + * port groups. + */ + MP_BOOL canSetTPGAccess; + + /** + * A Boolean indicating whether the implementations supports overriding + * paths. Setting this to true indicates MP_SetOverridePath and + * MP_CancelOverridePath are supported. + */ + MP_BOOL canOverridePaths; + + /** + * A boolean indicating whether the implementation exposes (or leaves + * exposed) device files for the individual paths encapsulated by the + * multipath device file. This is typically true for MP drivers that sit + * near the top of the driver stack.. + */ + MP_BOOL exposesPathDeviceFiles; + + /** + * A string representing the primary file names the driver uses for + * multipath logical units. + */ + MP_CHAR deviceFileNamespace[256]; + + /** + * A boolean indicating whether the driver limits multipath capabilities + * to certain device types. If true, then the driver only provides multipath + * support to devices exposed through MP_DEVICE_PRODUCT_PROPERTIES + * instances. If false, then the driver supports any device that provides + * standard SCSI logical unit identifiers. + */ + MP_BOOL onlySupportsSpecifiedProducts; + + /** + * Describes the range of administer settable path weights supported by the + * driver. A driver with no path preference capabilities should set + * this property to zero. A driver with the ability to enable/disable + * paths should set this property to 1. Drivers with more weight settings + * can set the property appropriately. + */ + MP_UINT32 maximumWeight; + + /** + * The autofailback support indicates whether the implementation supports + * auto-failback (to reenable paths that revert to a good state) at the + * plugin level, the multipath logical unit level, both levels or whether + * auto-failback is unsupported. + */ + MP_AUTOFAILBACK_SUPPORT autoFailbackSupport; + + /** + * A Boolean indicating whether plugin-wide autofailback is currently + * enabled. This parameter is undefined if autoFailbackSupport is + * MP_AUTOFAILBACK_SUPPORT_NONE or MP_AUTOFAILBACK_SUPPORT_MPLU. + */ + MP_BOOL pluginAutoFailbackEnabled; + + /** + * The maximum plugin-wide polling rate (in seconds) for auto-failback + * supported by the driver. A value of zero indicates the driver/plugin + * does not support polling. Undefined if autoFailbackSupport is + * MP_AUTOFAILBACK_SUPPORT_NONE or MP_AUTOFAILBACK_SUPPORT_MPLU. If the + * plugin/driver supports auto-failback without polling or does not provide + * a way to set the polling rate, then this must be set to zero (0). + * This value is set by the plugin and cannot be modified by users. + */ + MP_UINT32 failbackPollingRateMax; + + /** + * The current plugin-wide auto-failback polling rate (in seconds). + * Undefined if autofailbackSupport is MP_AUTOFAILBACK_SUPPORT_NONE or + * MP_AUTOFAILBACK_SUPPORT_MPLU. Cannot be more that plooingRateMax. + */ + MP_UINT32 currentFailbackPollingRate; + + /** + * An enumerated type indicating whether the implementation supports + * auto-probing at the plugin level, the multipath logical unit level, both + * levels or whether auto-probing is unsupported. + */ + MP_AUTOPROBING_SUPPORT autoProbingSupport; + + /** + * A boolean indicating that plugin-wide auto-probing is enabled. This + * property is undefined if autoProbingSupport is + * MP_AUTOPROBING_SUPPORT_NONE or MP_AUTOPROBING_SUPPORT_MPLU. + */ + MP_BOOL pluginAutoProbingEnabled; + + /** + * The maximum plugin-wide polling rate (in seconds) for auto-probing + * supported by the driver. Undefined if autoProbingSupport is + * MP_AUTOPROBING_SUPPORT_NONE or MP_AUTOPROBING_SUPPORT_MPLU. If the + * plugin/driver supports auto-probing without polling or does not provide a + * way to set the probing polling rate, then this must be set to zero (0). + * This value is set by the plugin and cannot be modified by users. + */ + MP_UINT32 probingPollingRateMax; + + /** + * The current plugin-wide auto-probing polling rate (in seconds). + * Undefined if autoProbingSupport is MP_AUTOPROBING_SUPPORT_NONE or + * MP_AUTOPROBING_SUPPORT_MPLU. Cannot be more that probingPollingRateMax. + */ + MP_UINT32 currentProbingPollingRate; + + /** + * The load balance type that will be used by the driver for devices + * (without a corresponding MP_DEVICE_PRODUCT_PROPERTIES instance) unless + * overridden by the administrator. Any logical unit with vendor, product, + * and revision properties matching a MP_DEVICE_PRODUCT_PROPERTIES instance + * will default to a device-specific load balance type. + */ + MP_LOAD_BALANCE_TYPE defaultloadBalanceType; + + /** + * The count of proprietary properties (less that or equal to eight) + * supported. + */ + MP_UINT32 proprietaryPropertyCount; + + /** + * A list of proprietary property name/value pairs. + */ + MP_PROPRIETARY_PROPERTY proprietaryProperties[8]; + +} MP_PLUGIN_PROPERTIES; + +/** + ******************************************************************************* + * + * Declaration of the MP_DEVICE_PRODUCT_PROPERTIES structure. + * + * This structure is returned by the MP_GetDeviceProductProperties() API. + * + ******************************************************************************* + */ +typedef struct _MP_DEVICE_PRODUCT_PROPERTIES +{ + MP_CHAR vendor[8]; + MP_CHAR product[16]; + MP_CHAR revision[4]; + MP_UINT32 supportedLoadBalanceTypes; + +} MP_DEVICE_PRODUCT_PROPERTIES; + +/** + ******************************************************************************* + * + * Declaration of the MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES structure. + * + * This structure is returned by the MP_GetMPLogicalUnitProperties() API. + * + ******************************************************************************* + */ +typedef struct _MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES +{ + MP_CHAR vendor[8]; + MP_CHAR product[16]; + MP_CHAR revision[4]; + MP_CHAR name[256]; + MP_LOGICAL_UNIT_NAME_TYPE nameType; + MP_CHAR deviceFileName[256]; + MP_BOOL asymmetric; + MP_OID overridePath; + MP_LOAD_BALANCE_TYPE currentLoadBalanceType; + MP_UINT32 logicalUnitGroupID; + MP_XBOOL autoFailbackEnabled; + MP_UINT32 failbackPollingRateMax; + MP_UINT32 currentFailbackPollingRate; + MP_XBOOL autoProbingEnabled; + MP_UINT32 probingPollingRateMax; + MP_UINT32 currentProbingPollingRate; + MP_UINT32 proprietaryPropertyCount; + MP_PROPRIETARY_PROPERTY proprietaryProperties[8]; + +} MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES; + +/** + ******************************************************************************* + * + * Declaration of the MP_PATH_LOGICAL_UNIT_PROPERTIES structure. + * + * This structure is returned by the MP_GetPathLogicalUnitProperties() API. + * + ******************************************************************************* + */ +typedef struct _MP_PATH_LOGICAL_UNIT_PROPERTIES +{ + MP_UINT32 weight; + MP_PATH_STATE pathState; + MP_BOOL disabled; + MP_OID initiatorPortOid; + MP_OID targetPortOid; + MP_OID logicalUnitOid; + MP_UINT64 logicalUnitNumber; + MP_CHAR deviceFileName[256]; + MP_UINT32 busNumber; + MP_UINT32 portNumber; + +} MP_PATH_LOGICAL_UNIT_PROPERTIES; + +/** + ******************************************************************************* + * + * Declaration of the MP_INITIATOR_PORT_PROPERTIES structure. + * + * This structure is returned by the MP_GetInitiatorPortProperties() API. + * + ******************************************************************************* + */ +typedef struct _MP_INITIATOR_PORT_PROPERTIES +{ + MP_CHAR portID[256]; + MP_PORT_TRANSPORT_TYPE portType; + MP_CHAR osDeviceFile[256]; + MP_WCHAR osFriendlyName[256]; + +} MP_INITIATOR_PORT_PROPERTIES; + +/** + ******************************************************************************* + * + * Declaration of the MP_TARGET_PORT_PROPERTIES structure. + * + * This structure is returned by the MP_GetTargetPortProperties() API. + * + ******************************************************************************* + */ +typedef struct _MP_TARGET_PORT_PROPERTIES +{ + MP_CHAR portID[256]; + MP_UINT32 relativePortID; + +} MP_TARGET_PORT_PROPERTIES; + +/** + ******************************************************************************* + * + * Declaration of the MP_TARGET_PORT_GROUP_PROPERTIES structure. + * + * This structure is returned by the MP_GetTargetPortGroupProperties() API. + * + ******************************************************************************* + */ +typedef struct _MP_TARGET_PORT_GROUP_PROPERTIES +{ + MP_ACCESS_STATE_TYPE accessState; + MP_BOOL explicitFailover; + MP_BOOL supportsLuAssignment; + MP_BOOL preferredLuPath; + MP_UINT32 tpgID; + +} MP_TARGET_PORT_GROUP_PROPERTIES; + +/** + ******************************************************************************* + * + * Declaration of the MP_TPG_STATE_PAIR structure. + * + * This structure is used as an argument for the MP_SetTPGAcess() API. + * + ******************************************************************************* + */ +typedef struct _MP_TPG_STATE_PAIR +{ + MP_OID tpgOid; + MP_ACCESS_STATE_TYPE desiredState; + +} MP_TPG_STATE_PAIR; + +/** + ******************************************************************************* + * + * Declaration of call back function type for event support + * + ******************************************************************************* + */ +typedef void (* MP_OBJECT_PROPERTY_FN) ( + MP_OID_LIST *pOidList, void *pCallerData +); + +typedef void (* MP_OBJECT_VISIBILITY_FN) ( + MP_BOOL becomingVisible, MP_OID_LIST *pOidList, void *pCallerData +); + +void InitLibrary(); +void ExitLibrary(); + +/** + ****************************************************************************** + * + * The APIs for property and object related discovery. + * + * - MP_GetLibraryProperties + * - MP_GetPluginOidList + * - MP_GetPluginProperties + * - MP_GetAssociatedPluginOid + * - MP_GetObjectType + * - MP_GetDeviceProductOidList + * - MP_GetDeviceProductProperties + * - MP_GetInitiatorPortOidList + * - MP_GetInitiatorPortProperties + * - MP_GetMultipathLus + * - MP_GetMPLogicalUnitProperties + * - MP_GetAssociatedPathOidList + * - MP_GetPathLogicalUnitProperties + * - MP_GetAssociatedTPGOidList + * - MP_GetTargetPortGroupProperties + * - MP_GetMPLuOidListFromTPG + * - MP_GetProprietaryLoadBalanceOidList + * - MP_GetProprietaryLoadBalanceProperties + * - MP_GetTargetPortOidList + * - MP_GetTargetPortProperties + * + ****************************************************************************** + */ + +/** + ******************************************************************************* + * + * Gets the properties of the MP API library that is being used. + * + * @param pProps + * A pointer to an MP_LIBRARY_PROPERTIES structure allocated by + * the caller. On successful return this structure will contain the + * properties of the MP API library. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned if the library properties were successfully returned. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding the + * library properties is found to be invalid. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API. + * + ****************************************************************************** + */ +MP_STATUS MP_GetLibraryProperties( + MP_LIBRARY_PROPERTIES *pProps +); + +/** + ****************************************************************************** + * + * Gets a list of the object IDs of all currently loaded plugins. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST. On successful + * return this will contain a pointer to an @ref MP_OID_LIST + * which contains the object IDs of all of the plugins currently + * loaded by the library. + * + * @return MP_STATUS indicating if the operation was successful or + * if an error occurred. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. This is + * most likely to happen if an uninitialized object ID is passed to + * the API. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList is NULL or specifies a memory area to which data + * cannot be written. MP_STATUS_SUCCESS Returned when the operation is + * successful. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs* + * + * @retval MP_STATUS_SUCCESS + * Returned if the plugin ID list was successfully returned. + * + ****************************************************************************** + */ +MP_STATUS MP_GetPluginOidList( + MP_OID_LIST **ppList +); + +/** + ******************************************************************************* + * + * Gets the properties of the specified vendor plugin. + * + * @param oid + * The ID of the plugin whose properties are being retrieved. + * + * @param pProps + * A pointer to an @ref MP_PLUGIN_PROPERTIES structure allocated by + * the caller. On successful return this will contain the properties + * of the plugin specified by pluginOid. + * + * @return An MP_STATUS indicating if the operation was successful or if an + * error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned if the plugin properties were successfully returned. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if 'pProps' is NULL or specifies a memory area to + * which data cannot be written. + * + ******************************************************************************* + */ +MP_STATUS MP_GetPluginProperties( + MP_OID oid, + MP_PLUGIN_PROPERTIES *pProps +); + + +/** + ******************************************************************************* + * + * Gets the object ID for the plugin associated with the specified object ID. + * + * @param oid + * The object ID of an object that has been received from a previous + * library call. + * + * @param pPluginOid + * A pointer to an MP_OID structure allocated by the caller. On + * successful return this will contain the object ID of the plugin + * associated with the object specified by @a objectId. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned if the associated plugin ID was successfully returned. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid does not specify a plugin that is currently known to + * the system. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if 'oid' specifies an object not owned by a plugin or + * if pPluginOid is NULL or specifies a memory area to which data + * cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if 'oid' specifies an object with an invalid type. + * + ******************************************************************************* + */ +MP_STATUS MP_GetAssociatedPluginOid( + MP_OID oid, + MP_OID *pPluginOid +); + + +/** + ******************************************************************************* + * + * Gets the object type of an initialized object ID. + * + * @param oid + * The object ID of an object that has been received from a previous + * library call. + * + * @param pObjectType + * A pointer to an MP_OBJECT_TYPE variable allocated by the caller. + * On successful return this will contain the object type of oid. + * + * @return An MP_STATUS indicating if the operation was successful or + * if an error occurred. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + ******************************************************************************* + */ +MP_STATUS MP_GetObjectType( + MP_OID oid, + MP_OBJECT_TYPE *pObjectType +); + + +/** + ******************************************************************************* + * + * Gets a list of the object IDs of all the device product properties + * associated with this plugin. + * + * @param oid + * The object ID of plugin. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the device + * product descriptors associated with the specified plugin. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the device product list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the API is not supported. + * + ******************************************************************************* + */ +MP_STATUS MP_GetDeviceProductOidList( + MP_OID oid, + MP_OID_LIST **ppList +); + +/** + ******************************************************************************* + * + * Gets the device product properties of the specified plugin oid. + * + * @param oid + * The object ID of the plugin. + * + * @param ppProps + * A pointer to an MP_DEVICE_PRODUCT_PROPERTIES structure + * allocated by the caller. On successful return it will contain + * a pointer to an MP_DEVICE_PRODUCT_PROPERTIES structure allocated + * by the library. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppProps pointer passed as placeholder for holding + * the device product properties is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the API is not supported. + * + ******************************************************************************* + */ +MP_STATUS MP_GetDeviceProductProperties( + MP_OID oid, + MP_DEVICE_PRODUCT_PROPERTIES *pProps +); + +/** + ******************************************************************************* + * + * Gets a list of the object IDs of all the initiator ports associated + * with this plugin. + * + * @param oid + * The object ID of plugin. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the initiator + * ports associated with the specified plugin. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the initiator port list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the API is not supported. + * + ******************************************************************************* + */ +MP_STATUS MP_GetInitiatorPortOidList( + MP_OID oid, + MP_OID_LIST **ppList +); + +/** + ******************************************************************************* + * + * Gets the properties of the specified initiator port. + * + * @param oid + * The object ID of the initiator port. + * + * @param pProps + * A pointer to an MP_INITIATOR_PORT_PROPERTIES structure + * allocated by the caller. On successful return, this structure + * will contain the properties of the port specified by oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pProps is NULL or specifies a memory area to + * which data cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetInitiatorPortProperties( + MP_OID oid, + MP_INITIATOR_PORT_PROPERTIES *pProps +); + +/** + ******************************************************************************* + * + * Gets a list of multipath logical units associated to a plugin. + * + * @param oid + * The object ID of plugin. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the multipath + * logical units associated with the specified plugin. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the multipath logical unit list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the API is not supported. + * + ******************************************************************************* + */ +MP_STATUS MP_GetMultipathLus( + MP_OID oid, + MP_OID_LIST **ppList +); + +/** + ******************************************************************************* + * + * Gets the properties of the specified logical unit. + * + * @param oid + * The object ID of the multipath logical unit. + * + * @param pProps + * A pointer to an MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES structure + * allocated by the caller. On successful return, this structure + * will contain the properties of the port specified by oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pProps is NULL or specifies a memory area to + * which data cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetMPLogicalUnitProperties( + MP_OID oid, + MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES *pProps +); + +/** + ******************************************************************************* + * + * Gets a list of the object IDs of all the path logical units associated + * with the specified multipath logical unit, initiator port, or target port. + * + * @param oid + * The object ID of multipath logical unit, initiator port, or + * target port. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the mp path + * logical units associated with the specified OID. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the device product list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetAssociatedPathOidList( + MP_OID oid, + MP_OID_LIST **ppList +); + +/** + ******************************************************************************* + * + * Gets the properties of the specified path logical unit. + * + * @param oid + * The object ID of the path logical unit. + * + * @param pProps + * A pointer to an MP_PATH_LOGICAL_UNIT_PROPERTIES structure + * allocated by the caller. On successful return, this structure + * will contain the properties of the port specified by oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pProps is NULL or specifies a memory area to + * which data cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetPathLogicalUnitProperties( + MP_OID oid, + MP_PATH_LOGICAL_UNIT_PROPERTIES *pProps +); + +/** + ******************************************************************************* + * + * Gets a list of the object IDs of all the target port group associated + * with the specified multipath logical unit. + * + * @param oid + * The object ID of the multiple logical unit. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the target + * port group associated with the specified multipath logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the target port group list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * + ******************************************************************************* + */ +MP_STATUS MP_GetAssociatedTPGOidList( + MP_OID oid, + MP_OID_LIST **ppList +); + +/** + ******************************************************************************* + * + * Gets the properties of the specified target port group. + * + * @param oid + * The object ID of the target port group. + * + * @param pProps + * A pointer to an MP_TARGET_PORT_GROUP_PROPERTIES structure + * allocated by the caller. On successful return, this structure + * will contain the properties of the port specified by oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pProps is NULL or specifies a memory area to + * which data cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetTargetPortGroupProperties( + MP_OID oid, + MP_TARGET_PORT_GROUP_PROPERTIES *pProps +); + +/** + ******************************************************************************* + * + * Gets a list of multipath logical units associated with the specific target + * port group. + * + * @param oid + * The object ID of the target port group. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the multipath + * logical units associated with the specified target port group. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the multipath logical unit list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + ******************************************************************************* + */ +MP_STATUS MP_GetMPLuOidListFromTPG( + MP_OID oid, + MP_OID_LIST **ppList +); + +/** + ******************************************************************************* + * + * Gets a list of the object IDs of all the proprietary load balance + * algorithms associated with this plugin. + * + * @param oid + * The object ID of the plugin. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the proprietary + * load balance algorithms associated with the specified plugin. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the proprietary load balance oid list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the API is not supported. + * + ******************************************************************************* + */ +MP_STATUS MP_GetProprietaryLoadBalanceOidList( + MP_OID oid, + MP_OID_LIST **ppList +); + +/** + ******************************************************************************* + * + * Gets the properties of the specified load balance properties structure. + * + * @param oid + * The object ID of the proprietary load balance structure. + * + * @param pProps + * A pointer to an MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES structure + * allocated by the caller. On successful return, this structure + * will contain the properties of the port specified by oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pProps is NULL or specifies a memory area to + * which data cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetProprietaryLoadBalanceProperties( + MP_OID oid, + MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES *pProps +); + +/** + ******************************************************************************* + * + * Gets a list of the object IDs of the target ports in the specified target + * port group. + * + * @param oid + * The object ID of the target port group. + * + * @param ppList + * A pointer to a pointer to an MP_OID_LIST structure. + * On a successful return, this will contain a pointer to + * an MP_OID_LIST that contains the object IDs of all the target ports + * associated with the specified target port group. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if ppList pointer passed as placeholder for holding + * the multipath logical unit list is found to be invalid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the plugin for the specified oid is not found. + * + * @retval MP_STATUS_INSUFFICIENT_MEMORY + * Returned when memory allocation failure occurs + * + ******************************************************************************* + */ +MP_STATUS MP_GetTargetPortOidList( + MP_OID oid, + MP_OID_LIST **ppList +); + +/** + ******************************************************************************* + * + * Gets the properties of the specified target port. + * + * @param oid + * The object ID of the target port. + * + * @param pProps + * A pointer to an MP_TARGET_PORT_PROPERTIES structure + * allocated by the caller. On successful return, this structure + * will contain the properties of the port specified by oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pProps is NULL or specifies a memory area to + * which data cannot be written. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_GetTargetPortProperties( + MP_OID oid, + MP_TARGET_PORT_PROPERTIES *pProps +); + +/** + ****************************************************************************** + * + * The APIs for path management. + * + * - MP_AssignLogicalUnitToTPG + * - MP_SetOverridePath + * - MP_CancelOverridePath + * - MP_EnableAutoFailback + * - MP_DisableAutoFailback + * - MP_EnableAutoProbing + * - MP_DisableAutoProbing + * - MP_EnablePath + * - MP_DisablePath + * - MP_SetLogicalUnitLoadBalanceType + * - MP_SetPluginLoadBalanceType + * - MP_SetPathWeight + * - MP_SetFailbackPollingRates + * - MP_SetProbingPollingRates + * - MP_SetProprietaryProperties + * - MP_SetTPGAccess + * + ****************************************************************************** + */ + +/** + ******************************************************************************* + * + * Assign a multipath logical unit to a target port group. + * + * @param tpgOid + * An MP_TARGET_PORT_GROUP oid. The target port group currently in + * active access state that the administrator would like the LU + * assigned to. + * + * @param luOid + * An MP_MULTIPATH_LOGICAL_UNIT oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned when luOid is not associated with tpgOid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_AssignLogicalUnitToTPG( + MP_OID tpgOid, + MP_OID luOid +); + +/** + ******************************************************************************* + * + * Manually override the path for a logical unit. The path exclusively used to + * access the logical unit until cleared. + * + * @param logicalUnitOid + * The object ID of the multipath logical unit. + * + * @param pathOid + * The object ID of the path logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if the oid of the object is not valid + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_PATH_NONOPERATIONAL + * Returned when the driver cannot communicate through selected path. + * + ******************************************************************************* + */ +MP_STATUS MP_SetOverridePath( + MP_OID logicalUnitOid, + MP_OID pathOid +); + +/** + ******************************************************************************* + * + * Cancel a path override and re-enable load balancing. + * + * @param luOid + * An MP_MULTIPATH_LOGICAL_UNIT oid. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if MP_MULTIPATH_LOGICAL_UNIT with the luOid is not found. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned if oid has an owner that is not currently known to + * the system. + * + ******************************************************************************* + */ +MP_STATUS MP_CancelOverridePath( + MP_OID logicalUnitOid +); + +/** + ******************************************************************************* + * + * Enables Auto-failback. + * + * @param oid + * The oid of the plugin or the multipath logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid is NULL or specifies a memory area that is not + * a valid plugin oid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_EnableAutoFailback( + MP_OID oid +); + +/** + ******************************************************************************* + * + * Disables Auto-failback. + * + * @param oid + * The oid of the plugin or the multipath logical unit.. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid is NULL or specifies a memory area that is not + * a valid plugin oid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_DisableAutoFailback( + MP_OID oid +); + +/** + ******************************************************************************* + * + * Enables Auto-probing. + * + * @param oid + * The oid of the plugin or the multipath logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid is NULL or specifies a memory area that is not + * a valid plugin oid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_EnableAutoProbing( + MP_OID oid +); + +/** + ******************************************************************************* + * + * Disables Auto-probing. + * + * @param oid + * The oid of the plugin or the multipath logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid is NULL or specifies a memory area that is not + * a valid plugin oid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_DisableAutoProbing( + MP_OID oid +); + +/** + ******************************************************************************* + * + * Enables a path. This API may cause failover in a logical unit with + * asymmetric access. + * + * @param oid + * The oid of the path. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid is NULL or specifies a memory area that is not + * a valid path oid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_EnablePath( + MP_OID oid +); + +/** + ******************************************************************************* + * + * Disables a path. This API may cause failover in a logical unit with + * asymmetric access. This API may cause a logical unit to become unavailable. + * + * @param oid + * The oid of the path. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if oid is NULL or specifies a memory area that is not + * a valid path oid. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the API is not supported. + * + * @retval MP_STATUS_TRY_AGAIN + * Returned when path cannot be disabled at this time. + * + * @retval MP_STATUS_NOT_PERMITTED + * Returned when disabling thsi path would cause the login unit to + * become unavailable. + * + ******************************************************************************* + */ +MP_STATUS MP_DisablePath( + MP_OID oid +); + +/** + ******************************************************************************* + * + * Set the multipath logical unit s load balancing policy. + * + * @param logicalUnitoid + * The object ID of the multipath logical unit. + * + * @param loadBanlance + * The desired load balance policy for the specified logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if no MP_MULTIPATH_LOGICAL_UNIT associated with + * @ref ligicalUnitrOid is found or invalid MP_LOAD_BALANCE_TYPE is + * specified. + * + * @retval MP_STATUS_FAILED + * Returned when the specified loadBalance type cannot be handled + * by the plugin. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_SetLogicalUnitLoadBalanceType( + MP_OID logicalUnitOid, + MP_LOAD_BALANCE_TYPE loadBalance +); + +/** + ******************************************************************************* + * + * Set the weight to be assigned to a particular path. + * + * @param pathOid + * The object ID of the path logical unit. + * + * @param weight + * weight that will be assigned to the path logical unit. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned when the MP Path specified by the PathOid could not be + * found. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the operation failed. + * + * @retval MP_STATUS_INVALID_WEIGHT + * Returned when the weight parameter is greater than the plugin's + * maxWeight property. + * + ******************************************************************************* + */ +MP_STATUS MP_SetPathWeight( + MP_OID pathOid, + MP_UINT32 weight +); + +/** + ******************************************************************************* + * + * Set the default load balance policy for the plugin. + * + * @param oid + * The object ID of the plugin + * + * @param loadBalance + * The desired default load balance policy for the specified plugin. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned when the the plugin specified by @ref oid could not be + * found. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if the oid of the object is not valid. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned when the specified loadBalance type cannot be handled + * by the plugin. + * + ******************************************************************************* + */ +MP_STATUS MP_SetPluginLoadBalanceType( + MP_OID oid, + MP_LOAD_BALANCE_TYPE loadBalance +); + +/** + ******************************************************************************* + * + * Set the failback polling rates. Setting both rates to zero disables polling. + * + * @param pluginOid + * The object ID of either the plugin or a multipath logical unit. + * + * @param pollingRate + * The value to be set in MP_PLUGIN_PROPERTIES current pollingRate or + * MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES pollingRate. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned when the the plugin specified by @ref oid could not be + * found. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if one of the polling values is outside the range + * supported by the driver. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_SetFailbackPollingRate( + MP_OID oid, + MP_UINT32 pollingRate +); + +/** + ******************************************************************************* + * + * Set the probing polling rates. Setting both rates to zero disables polling. + * + * @param pluginOid + * The object ID of either the plugin or a multipath logical unit. + * + * @param pollingRate + * The value to be set in MP_PLUGIN_PROPERTIES current pollingRate or + * MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES pollingRate. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned when the the plugin specified by @ref oid could not be + * found. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if one of the polling values is outside the range + * supported by the driver. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_SetProbingPollingRate( + MP_OID oid, + MP_UINT32 pollingRate +); + +/** + ******************************************************************************* + * + * Set proprietary properties in supported object instances. + * + * @param pluginOid + * The object ID of MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES, + * MP_PLUGIN_PROPERTIES or MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES. + * + * @param count + * The number of valid items in pPropertyList. + * + * @param pPropertyList + * A pointer to an array of property name/value pairs. This array must + * contain the same number of elements as count. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned when the the plugin specified by @ref oid could not be + * found. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if one of the polling values is outside the range + * supported by the driver. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_SetProprietaryProperties( + MP_OID oid, + MP_UINT32 count, + MP_PROPRIETARY_PROPERTY *pPropertyList +); + +/** + ******************************************************************************* + * + * Set the access state for a list of target port groups. This allows + * a client to force a failover or failback to a desired set of target port + * groups. + * + * @param luOid + * The object ID of the logical unit where the command is sent. + * + * @param count + * The number of valid items in the pTpgStateList. + * + * @param pTpgStateList + * A pointer to an array of TPG/access-state values. This array must + * contain the same number of elements as @ref count. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_OBJECT_NOT_FOUND + * Returned when the MP_MULTIPATH_LOGICAL_UNIT associated with @ref + * oid could not be found. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pTpgStateList is null or if one of the TPGs referenced + * in the list is not associated with the specified MP logical unit. + * + * @retval MP_STATUS_UNSUPPORTED + * Returned when the implementation does not support the API + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if oid does not specify any valid object type. + * + * @retval MP_STATUS_ACCESS_STATE_INVALID + * Returned if the target device returns a status indicating the caller + * is attempting to establish an illegal combination of access states. + * + * @retval MP_STATUS_FAILED + * Returned if the underlying interface failed the commend for some + * reason other than MP_STATUS_ACCESS_STATE_INVALID + * + ******************************************************************************* + */ +MP_STATUS MP_SetTPGAccess( + MP_OID luOid, + MP_UINT32 count, + MP_TPG_STATE_PAIR *pTpgStateList +); + +/** + ****************************************************************************** + * + * The APIs that are associated with event support. + * + * - MP_RegisterForObjectPropertyChanges + * - MP_DeregisterForObjectPropertyChanges + * - MP_RegisterForObjectVisibilityChanges + * - MP_DeregisterForObjectVisibilityChanges + * + ****************************************************************************** + */ + +/** + ******************************************************************************* + * + * Registers a client function that is to be called + * whenever the property of an an object changes. + * + * @param pClientFn, + * A pointer to an MP_OBJECT_PROPERTY_FN function defined by the + * client. On successful return this function will be called to + * inform the client of objects that have had one or more properties + * change. + * + * @param objectType + * The type of object the client wishes to deregister for + * property change callbacks. If null, then all objects types are + * deregistered. + * + * @param pCallerData + * A pointer that is passed to the callback routine with each event. + * This may be used by the caller to correlate the event to source of + * the registration. + * + * @param pluginOid + * A plugin oid that the client wishes to deregister for property change. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pClientFn is NULL or specifies a memory area + * that is not executable. + * + * @retval MP_STATUS_FN_REPLACED + * Returned when an existing client function is replaced with the one + * specified in pClientFn. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if objectType does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_RegisterForObjectPropertyChanges( + MP_OBJECT_PROPERTY_FN pClientFn, + MP_OBJECT_TYPE objectType, + void *pCallerData, + MP_OID pluginOid +); + +/** + ******************************************************************************* + * + * Deregisters a previously registered client function that is to be invoked + * whenever an object's property changes. + * + * @param pClientFn, + * A pointer to an MP_OBJECT_PROPERTY_FN function defined by the + * client that was previously registered using + * the MP_RegisterForObjectPropertyChanges API. On successful return + * this function will no longer be called to inform the client of + * object property changes. + * + * @param objectType + * The type of object the client wishes to deregister for + * property change callbacks. If null, then all objects types are + * deregistered. + * + * @param pluginOid + * A plugin oid that the client wishes to deregister for property change. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pClientFn is NULL or specifies a memory area + * that is not executable. + * + * @retval MP_STATUS_UNKNOWN_FN + * Returned if pClientFn is not the same as the previously registered + * function. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if objectType does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned if pClientFn deregistration is not possible at this time. + * + ******************************************************************************* + */ +MP_STATUS MP_DeregisterForObjectPropertyChanges( + MP_OBJECT_PROPERTY_FN pClientFn, + MP_OBJECT_TYPE objectType, + MP_OID pluginOid +); + +/** + ******************************************************************************* + * + * Registers a client function that is to be called + * whenever a high level object appears or disappears. + * + * @param pClientFn, + * A pointer to an MP_OBJECT_VISIBILITY_FN function defined by the + * client. On successful return this function will be called to + * inform the client of objects whose visibility has changed. + * + * @param objectType + * The type of object the client wishes to deregister for + * property change callbacks. If null, then all objects types are + * deregistered. + * + * @param pCallerData + * A pointer that is passed to the callback routine with each event. + * This may be used by the caller to correlate the event to source of + * the registration. + * + * @param pluginOid + * A plugin oid that the client wishes to deregister for property change. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pClientFn is NULL or specifies a memory area + * that is not executable. + * + * @retval MP_STATUS_FN_REPLACED + * Returned when an existing client function is replaced with the one + * specified in pClientFn. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if objectType does not specify any valid object type. + * + ******************************************************************************* + */ +MP_STATUS MP_RegisterForObjectVisibilityChanges( + MP_OBJECT_VISIBILITY_FN pClientFn, + MP_OBJECT_TYPE objectType, + void *pCallerData, + MP_OID pluginOid +); + +/** + ******************************************************************************* + * + * Deregisters a previously registered client function that is to be invoked + * whenever a high level object appears or disappears. + * + * @param pClientFn, + * A pointer to an MP_OBJECT_VISIBILITY_FN function defined by the + * client that was previously registered using + * the MP_RegisterForObjectVisibilityChanges API. On successful return + * this function will no longer be called to inform the client of + * object property changes. + * + * @param objectType + * The type of object the client wishes to deregister for visibility + * change callbacks. If null, then all objects types are + * deregistered. + * + * @param pluginOid + * A plugin oid that the client wishes to deregister for property change. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the operation is successful. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pClientFn is NULL or specifies a memory area + * that is not executable. + * + * @retval MP_STATUS_UNKNOWN_FN + * Returned if pClientFn is not the same as the previously registered + * function. + * + * @retval MP_STATUS_INVALID_OBJECT_TYPE + * Returned if objectType does not specify any valid object type. + * + * @retval MP_STATUS_FAILED + * Returned if pClientFn deregistration is not possible at this time. + * + ******************************************************************************* + */ +MP_STATUS MP_DeregisterForObjectVisibilityChanges( + MP_OBJECT_VISIBILITY_FN pClientFn, + MP_OBJECT_TYPE objectType, + MP_OID pluginOid +); + +/** + ****************************************************************************** + * + * The utility APIs + * + * - MP_CompareOIDs + * - MP_FreeOidList + * - MP_RegisterPlugin + * - MP_DeregisterPlugin + * + ****************************************************************************** + */ + +/** + ******************************************************************************* + * + * Compare two Oids for equality to see whether they refer to the same object. + * + * @param oid1 + * Oid to compare. + * + * @param oid2 + * Oid to compare. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when the two Oids do refer to the same object. + * + * @retval MP_STATUS_FAILED + * Returned if the Oids don't compare. + * + ******************************************************************************* + */ +MP_STATUS MP_CompareOIDs( + MP_OID oid1, + MP_OID oid2 +); + +/** + ******************************************************************************* + * + * Frees memory returned by an MP API. + * + * @param pMemory + * A pointer to the memory returned by an MP API. On successful + return, the allocated memory is freed. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when pPluginId is deregistered successfully. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pMemory is NULL or specifies a memory area to which + * data cannot be written. + * + ******************************************************************************* + */ +MP_STATUS MP_FreeOidList( + MP_OID_LIST *pOidList +); + +/** + ******************************************************************************* + * + * Registers a plugin with common library. The implementation of this routine + * is based on configuration file /etc/mpapi.conf that contains a list of + * plugin libraries. + * + * @param pPluginId + * A pointer to the key name shall be the reversed domain name of + * the vendor followed by followed by the vendor specific name for + * the plugin that uniquely identifies the plugin. + * + * @param pFileName + * The full path to the plugin library. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when pPluginId is deregistered successfully. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pPluginId is NULL or specifies a memory area that + * is not executable. + * + * @retval MP_STATUS_FAILED + * Returned if pClientFn deregistration is not possible at this time. + * + ******************************************************************************* + */ +MP_STATUS MP_RegisterPlugin( + MP_WCHAR *pPluginId, + MP_CHAR *pFileName +); + +/** + ******************************************************************************* + * + * Deregisters a plugin from the common library. + * + * @param pPluginId + * A pointer to a Plugin ID previously registered using + * the MP_RegisterPlugin API.. + * + * @return An MP_STATUS indicating if the operation was successful or if + * an error occurred. + * + * @retval MP_STATUS_SUCCESS + * Returned when pPluginId is deregistered successfully. + * + * @retval MP_STATUS_INVALID_PARAMETER + * Returned if pPluginId is NULL or specifies a memory area that + * is not executable. + * + * @retval MP_STATUS_FAILED + * Returned if pClientFn deregistration is not possible at this time. + * + ******************************************************************************* + */ +MP_STATUS MP_DeregisterPlugin( + MP_WCHAR *pPluginId +); + +#endif + +#ifdef __cplusplus +}; +#endif + diff --git a/usr/src/lib/mpapi/libmpapi/i386/Makefile b/usr/src/lib/mpapi/libmpapi/i386/Makefile new file mode 100644 index 0000000000..c7cca61bea --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/i386/Makefile @@ -0,0 +1,28 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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 ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/mpapi/libmpapi/sparc/Makefile b/usr/src/lib/mpapi/libmpapi/sparc/Makefile new file mode 100644 index 0000000000..c7cca61bea --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/sparc/Makefile @@ -0,0 +1,28 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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 ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/mpapi/libmpapi/sparcv9/Makefile b/usr/src/lib/mpapi/libmpapi/sparcv9/Makefile new file mode 100644 index 0000000000..bbc20fa470 --- /dev/null +++ b/usr/src/lib/mpapi/libmpapi/sparcv9/Makefile @@ -0,0 +1,29 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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 ../Makefile.com +include ../../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/Makefile b/usr/src/lib/mpapi/libmpscsi_vhci/Makefile new file mode 100644 index 0000000000..f7e3396ef5 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/Makefile @@ -0,0 +1,50 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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 ../../Makefile.lib + +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +lint := TARGET= lint + +.KEEP_STATE: + +all clean clobber install lint: $(SUBDIRS) + +install_h: + +check: + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../../Makefile.targ diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/Makefile.com b/usr/src/lib/mpapi/libmpscsi_vhci/Makefile.com new file mode 100644 index 0000000000..4a357345fa --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/Makefile.com @@ -0,0 +1,74 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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. +# + +LIBRARY= libmpscsi_vhci.a +VERS= .1 +OBJECTS= Initialize.o MP_AssignLogicalUnitToTPG.o \ + MP_CancelOverridePath.o MP_DeregForObjPropChangesPlugin.o \ + MP_DeregForObjVisChangesPlugin.o MP_DisableAutoFailbackLu.o \ + MP_DisableAutoFailbackPlugin.o MP_DisableAutoProbingLu.o \ + MP_DisableAutoProbingPlugin.o MP_DisablePath.o \ + MP_EnableAutoFailbackLu.o MP_EnableAutoFailbackPlugin.o \ + MP_EnableAutoProbingLu.o MP_EnableAutoProbingPlugin.o \ + MP_EnablePath.o MP_GetAssociatedPathOidList.o \ + MP_GetAssociatedTPGOidList.o \ + MP_GetDeviceProductOidListPlugin.o \ + MP_GetDeviceProductProperties.o \ + MP_GetInitiatorPortOidListPlugin.o \ + MP_GetInitiatorPortProperties.o \ + MP_GetMPLogicalUnitProperties.o \ + MP_GetMPLuOidListFromTPG.o MP_GetMultipathLusDevProd.o \ + MP_GetMultipathLusPlugin.o MP_GetPathLogicalUnitProperties.o \ + MP_GetPluginPropertiesPlugin.o \ + MP_GetProprietaryLBOidListPlugin.o MP_GetProprietaryLBProp.o \ + MP_GetTargetPortGroupProperties.o MP_GetTargetPortOidList.o \ + MP_GetTargetPortProperties.o MP_RegForObjPropChangesPlugin.o \ + MP_RegForObjVisChangesPlugin.o MP_SetFailbackPollingRateLu.o \ + MP_SetFailbackPollingRatePlugin.o \ + MP_SetLogicalUnitLoadBalanceType.o MP_SetOverridePath.o \ + MP_SetPathWeight.o MP_SetPluginLBTypePlugin.o \ + MP_SetProbingPollingRateLu.o MP_SetProbingPollingRatePlugin.o \ + MP_SetProprietaryProperties.o MP_SetTPGAccess.o \ + Sun_MP_SendScsiCmd.o Terminate.o debug_logging.o mp_utils.o + +include ../../../Makefile.lib +include ../../../Makefile.rootfs + +SRCDIR = ../common + +LIBS = $(DYNLIB) +LDLIBS += -lc -ldevinfo -lsysevent -lnvpair + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) -D_POSIX_PTHREAD_SEMANTICS +CPPFLAGS += -DBUILD_TIME='"Wed Sep 24 12:00:00 2008"' + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../../Makefile.targ diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/amd64/Makefile b/usr/src/lib/mpapi/libmpscsi_vhci/amd64/Makefile new file mode 100644 index 0000000000..bbc20fa470 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/amd64/Makefile @@ -0,0 +1,29 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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 ../Makefile.com +include ../../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/Initialize.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/Initialize.c new file mode 100644 index 0000000000..24750cdfab --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/Initialize.c @@ -0,0 +1,94 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <sys/stat.h> +#include <fcntl.h> +#include <errno.h> + +#include "mp_utils.h" + + +/* + * Global Variables + */ + +MP_UINT32 g_pluginOwnerID = 0; +int g_scsi_vhci_fd = -1; + +PROPERTY_CALLBACK_NODE g_Property_Callback_List[MP_OBJECT_TYPE_MAX + 1]; +VISIBILITY_CALLBACK_NODE g_Visibility_Callback_List[MP_OBJECT_TYPE_MAX + 1]; + +sysevent_handle_t *g_SysEventHandle = NULL; + +pthread_mutex_t g_visa_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t g_prop_mutex = PTHREAD_MUTEX_INITIALIZER; + +/* + * Called by the common layer to request the plugin to initialize + * itself. + */ + +MP_STATUS +Initialize(MP_UINT32 pluginOwnerID) +{ + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "Initialize()", " - enter"); + + + (void) memset(&g_Property_Callback_List, 0, + sizeof (PROPERTY_CALLBACK_NODE) * (MP_OBJECT_TYPE_MAX + 1)); + + (void) memset(&g_Visibility_Callback_List, 0, + sizeof (VISIBILITY_CALLBACK_NODE) * (MP_OBJECT_TYPE_MAX + 1)); + + /* Attempt to open the driver that this plugin will make request of. */ + g_scsi_vhci_fd = open("/devices/scsi_vhci:devctl", + O_NDELAY | O_RDONLY); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "Initialize()", + " - failed to open driver. error is : %s", + strerror(errno)); + log(LOG_INFO, "Initialize()", " - error exit"); + return (MP_STATUS_FAILED); + } + + g_pluginOwnerID = pluginOwnerID; + + /* Register to listen for visibility and property change events */ + mpStatus = init_sysevents(); + + log(LOG_INFO, "Initialize()", + " - init_sysevents() returned %d", + mpStatus); + + + log(LOG_INFO, "Initialize()", " - exit"); + + return (mpStatus); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_AssignLogicalUnitToTPG.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_AssignLogicalUnitToTPG.c new file mode 100644 index 0000000000..7a8863e21d --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_AssignLogicalUnitToTPG.c @@ -0,0 +1,125 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" + + +/* + * Called by the common layer to request the plugin to assign + * a logical unit to a TPG. luOid is the logical unit to assign + * to the TPG, tpgOid. + */ + +MP_STATUS +MP_AssignLogicalUnitToTPG(MP_OID tpgOid, MP_OID luOid) +{ + mp_lu_tpg_pair_t tpgPair; + mp_iocdata_t mp_ioctl; + + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + + log(LOG_INFO, "MP_AssignLogicalUnitToTPG()", " - enter"); + + + log(LOG_INFO, "MP_AssignLogicalUnitToTPG()", + "tpgOid.objectSequenceNumber = %llx", + tpgOid.objectSequenceNumber); + + log(LOG_INFO, "MP_AssignLogicalUnitToTPG()", + "luOid.objectSequenceNumber = %llx", + luOid.objectSequenceNumber); + + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_AssignLogicalUnitToTPG()", + "invalid driver file handle"); + log(LOG_INFO, "MP_AssignLogicalUnitToTPG()", + " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&tpgPair, 0, sizeof (mp_lu_tpg_pair_t)); + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + tpgPair.tpgId = tpgOid.objectSequenceNumber; + tpgPair.luId = luOid.objectSequenceNumber; + + mp_ioctl.mp_cmd = MP_ASSIGN_LU_TO_TPG; + mp_ioctl.mp_ibuf = (caddr_t)&tpgPair; + mp_ioctl.mp_ilen = sizeof (mp_lu_tpg_pair_t); + mp_ioctl.mp_xfer = MP_XFER_WRITE; + + log(LOG_INFO, "MP_AssignLogicalUnitToTPG()", + "mp_ioctl.mp_cmd (MP_ASSIGN_LU_TO_TPG) : %d", + mp_ioctl.mp_cmd); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_AssignLogicalUnitToTPG()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_AssignLogicalUnitToTPG()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_AssignLogicalUnitToTPG()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_AssignLogicalUnitToTPG()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_AssignLogicalUnitToTPG()", + " - error exit, returning %d to caller.", mpStatus); + + return (mpStatus); + } + + + log(LOG_INFO, "MP_AssignLogicalUnitToTPG()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_CancelOverridePath.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_CancelOverridePath.c new file mode 100644 index 0000000000..58efa0d3cb --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_CancelOverridePath.c @@ -0,0 +1,45 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_CancelOverridePath(MP_OID luOid) +{ + log(LOG_INFO, "MP_CancelOverridePath()", " - enter"); + + + log(LOG_INFO, "MP_CancelOverridePath()", + " - luOid.objectSequenceNumber: %llx", + luOid.objectSequenceNumber); + + + log(LOG_INFO, "MP_CancelOverridePath()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DeregForObjPropChangesPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DeregForObjPropChangesPlugin.c new file mode 100644 index 0000000000..260531406a --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DeregForObjPropChangesPlugin.c @@ -0,0 +1,88 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 "mp_utils.h" + + +/* + * Called by the common layer to request the plugin to no longer call + * a client application's callback (pClientFn) when a property change + * is detected for the given object type. + */ + +MP_STATUS +MP_DeregisterForObjectPropertyChangesPlugin(MP_OBJECT_PROPERTY_FN pClientFn, + MP_OBJECT_TYPE objectType) +{ + log(LOG_INFO, "MP_DeregisterForObjectPropertyChangesPlugin()", + " - enter"); + + + if (NULL == pClientFn) { + + log(LOG_INFO, "MP_DeregisterForObjectPropertyChangesPlugin()", + " - pClientFn is NULL"); + + log(LOG_INFO, "MP_DeregisterForObjectPropertyChangesPlugin()", + " - error exit"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + /* Validate the object type passes in within range */ + if (objectType > MP_OBJECT_TYPE_MAX) { + + log(LOG_INFO, "MP_DeregisterForObjectPropertyChangesPlugin()", + " - objectType is invalid"); + + log(LOG_INFO, "MP_DeregisterForObjectPropertyChangesPlugin()", + " - error exit"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + if (objectType < 1) { + + log(LOG_INFO, "MP_DeregisterForObjectPropertyChangesPlugin()", + " - objectType is invalid"); + + log(LOG_INFO, "MP_DeregisterForObjectPropertyChangesPlugin()", + " - error exit"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + /* Remove registration. */ + (void) pthread_mutex_lock(&g_prop_mutex); + g_Property_Callback_List[objectType].pClientFn = NULL; + g_Property_Callback_List[objectType].pCallerData = NULL; + (void) pthread_mutex_unlock(&g_prop_mutex); + + + log(LOG_INFO, "MP_DeregisterForObjectPropertyChangesPlugin()", + " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DeregForObjVisChangesPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DeregForObjVisChangesPlugin.c new file mode 100644 index 0000000000..9903d22820 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DeregForObjVisChangesPlugin.c @@ -0,0 +1,89 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 "mp_utils.h" + + +/* + * Called by the common layer to request the plugin to no longer call + * a client application's callback (pClientFn) when a visibility change + * is detected for the given object type. + */ + +MP_STATUS +MP_DeregisterForObjectVisibilityChangesPlugin(MP_OBJECT_VISIBILITY_FN pClientFn, + MP_OBJECT_TYPE objectType) +{ + log(LOG_INFO, "MP_DeregisterForObjectVisibilityChangesPlugin()", + " - enter"); + + + if (NULL == pClientFn) { + + log(LOG_INFO, "MP_DeregisterForObjectVisibilityChangesPlugin()", + " - pClientFn is NULL"); + + log(LOG_INFO, "MP_DeregisterForObjectVisibilityChangesPlugin()", + " - error exit"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + + /* Validate the object type passes in within range */ + if (objectType > MP_OBJECT_TYPE_MAX) { + + log(LOG_INFO, "MP_DeregisterForObjectVisibilityChangesPlugin()", + " - objectType is invalid"); + + log(LOG_INFO, "MP_DeregisterForObjectVisibilityChangesPlugin()", + " - error exit"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + if (objectType < 1) { + + log(LOG_INFO, "MP_DeregisterForObjectVisibilityChangesPlugin()", + " - objectType is invalid"); + + log(LOG_INFO, "MP_DeregisterForObjectVisibilityChangesPlugin()", + " - error exit"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + /* Remove registration. */ + (void) pthread_mutex_lock(&g_visa_mutex); + g_Visibility_Callback_List[objectType].pClientFn = NULL; + g_Visibility_Callback_List[objectType].pCallerData = NULL; + (void) pthread_mutex_unlock(&g_visa_mutex); + + + log(LOG_INFO, "MP_DeregisterForObjectVisibilityChangesPlugin()", + " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisableAutoFailbackLu.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisableAutoFailbackLu.c new file mode 100644 index 0000000000..ef71c84723 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisableAutoFailbackLu.c @@ -0,0 +1,45 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_DisableAutoFailbackLu(MP_OID oid) +{ + log(LOG_INFO, "MP_DisableAutoFailbackLu()", " - enter"); + + + log(LOG_INFO, "MP_DisableAutoFailbackLu()", + " - oid.objectSequenceNumber: %llx", + oid.objectSequenceNumber); + + + log(LOG_INFO, "MP_DisableAutoFailbackLu()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisableAutoFailbackPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisableAutoFailbackPlugin.c new file mode 100644 index 0000000000..50d1b3d90e --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisableAutoFailbackPlugin.c @@ -0,0 +1,113 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" + + +/* + * Called by the common layer to request the plugin to request + * to disable autofailback. + */ + +MP_STATUS +MP_DisableAutoFailbackPlugin(void) +{ + mp_iocdata_t mp_ioctl; + + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + char chBuffer[256]; + + + + log(LOG_INFO, "MP_DisableAutoFailbackPlugin()", " - enter"); + + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_DisableAutoFailbackPlugin()", + "invalid driver file handle"); + log(LOG_INFO, "MP_DisableAutoFailbackPlugin()", + " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&chBuffer, 0, 256); + + mp_ioctl.mp_cmd = MP_DISABLE_AUTO_FAILBACK; + mp_ioctl.mp_ibuf = (caddr_t)&chBuffer[0]; + mp_ioctl.mp_xfer = MP_XFER_WRITE; + + + log(LOG_INFO, "MP_DisableAutoFailbackPlugin()", + "mp_ioctl.mp_cmd (MP_DISABLE_AUTO_FAILBACK) : %d", + mp_ioctl.mp_cmd); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_DisableAutoFailbackPlugin()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_DisableAutoFailbackPlugin()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_DisableAutoFailbackPlugin()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_DisableAutoFailbackPlugin()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_DisableAutoFailbackPlugin()", + " - error exit"); + + return (mpStatus); + } + + + log(LOG_INFO, "MP_DisableAutoFailbackPlugin()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisableAutoProbingLu.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisableAutoProbingLu.c new file mode 100644 index 0000000000..7cfb2fe019 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisableAutoProbingLu.c @@ -0,0 +1,45 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_DisableAutoProbingLu(MP_OID oid) +{ + log(LOG_INFO, "MP_DisableAutoProbingLu()", " - enter"); + + + log(LOG_INFO, "MP_DisableAutoProbingLu()", + " - oid.objectSequenceNumber: %llx", + oid.objectSequenceNumber); + + + log(LOG_INFO, "MP_DisableAutoProbingLu()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisableAutoProbingPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisableAutoProbingPlugin.c new file mode 100644 index 0000000000..0ba0ea3bda --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisableAutoProbingPlugin.c @@ -0,0 +1,40 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_DisableAutoProbingPlugin(void) +{ + log(LOG_INFO, "MP_DisableAutoProbingPlugin()", " - enter"); + + + log(LOG_INFO, "MP_DisableAutoProbingPlugin()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisablePath.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisablePath.c new file mode 100644 index 0000000000..a46abda663 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_DisablePath.c @@ -0,0 +1,112 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" + + +/* + * Called by the common layer to request to disable a path + */ + +MP_STATUS +MP_DisablePath(MP_OID oid) +{ + mp_iocdata_t mp_ioctl; + + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + + log(LOG_INFO, "MP_DisablePath()", " - enter"); + + + log(LOG_INFO, "MP_DisablePath()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_DisablePath()", + "invalid driver file handle"); + log(LOG_INFO, "MP_DisablePath()", " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = MP_DISABLE_PATH; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_xfer = MP_XFER_WRITE; + + log(LOG_INFO, "MP_DisablePath()", + "mp_ioctl.mp_cmd (MP_DISABLE_PATH) : %d", + mp_ioctl.mp_cmd); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_DisablePath()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_DisablePath()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_DisablePath()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_DisablePath()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_DisablePath()", + " - error exit"); + + return (mpStatus); + } + + + log(LOG_INFO, "MP_DisablePath()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnableAutoFailbackLu.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnableAutoFailbackLu.c new file mode 100644 index 0000000000..18a272cf18 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnableAutoFailbackLu.c @@ -0,0 +1,45 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_EnableAutoFailbackLu(MP_OID oid) +{ + log(LOG_INFO, "MP_EnableAutoFailbackLu()", " - enter"); + + + log(LOG_INFO, "MP_EnableAutoFailbackLu()", + " - oid.objectSequenceNumber: %llx", + oid.objectSequenceNumber); + + + log(LOG_INFO, "MP_EnableAutoFailbackLu()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnableAutoFailbackPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnableAutoFailbackPlugin.c new file mode 100644 index 0000000000..90b33d1303 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnableAutoFailbackPlugin.c @@ -0,0 +1,105 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_EnableAutoFailbackPlugin(void) +{ + mp_iocdata_t mp_ioctl; + + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + char chBuffer[256]; + + + log(LOG_INFO, "MP_EnableAutoFailbackPlugin()", " - enter"); + + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_EnableAutoFailbackPlugin()", + "invalid driver file handle"); + log(LOG_INFO, "MP_EnableAutoFailbackPlugin()", " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&chBuffer, 0, 256); + + mp_ioctl.mp_cmd = MP_ENABLE_AUTO_FAILBACK; + mp_ioctl.mp_ibuf = (caddr_t)&chBuffer[0]; + mp_ioctl.mp_xfer = MP_XFER_WRITE; + + log(LOG_INFO, "MP_EnableAutoFailbackPlugin()", + "mp_ioctl.mp_cmd (MP_ENABLE_AUTO_FAILBACK) : %d", + mp_ioctl.mp_cmd); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_EnableAutoFailbackPlugin()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_EnableAutoFailbackPlugin()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_EnableAutoFailbackPlugin()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_EnableAutoFailbackPlugin()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_EnableAutoFailbackPlugin()", + " - error exit"); + + return (mpStatus); + } + + + log(LOG_INFO, "MP_EnableAutoFailbackPlugin()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnableAutoProbingLu.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnableAutoProbingLu.c new file mode 100644 index 0000000000..1c185010a8 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnableAutoProbingLu.c @@ -0,0 +1,45 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_EnableAutoProbingLu(MP_OID oid) +{ + log(LOG_INFO, "MP_EnableAutoProbingLu()", " - enter"); + + + log(LOG_INFO, "MP_EnableAutoProbingLu()", + " - oid.objectSequenceNumber: %llx", + oid.objectSequenceNumber); + + + log(LOG_INFO, "MP_EnableAutoProbingLu()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnableAutoProbingPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnableAutoProbingPlugin.c new file mode 100644 index 0000000000..c3f74c35c1 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnableAutoProbingPlugin.c @@ -0,0 +1,40 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_EnableAutoProbingPlugin(void) +{ + log(LOG_INFO, "MP_EnableAutoProbingPlugin()", " - enter"); + + + log(LOG_INFO, "MP_EnableAutoProbingPlugin()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnablePath.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnablePath.c new file mode 100644 index 0000000000..41e66a77ee --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_EnablePath.c @@ -0,0 +1,113 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" + + +/* + * Called by the common layer to request to enable a path + */ + +MP_STATUS +MP_EnablePath(MP_OID oid) +{ + mp_iocdata_t mp_ioctl; + + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + + log(LOG_INFO, "MP_EnablePath()", " - enter"); + + + log(LOG_INFO, "MP_EnablePath()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_EnablePath()", + "invalid driver file handle"); + log(LOG_INFO, "MP_EnablePath()", " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = MP_ENABLE_PATH; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_xfer = MP_XFER_WRITE; + + log(LOG_INFO, "MP_EnablePath()", + "mp_ioctl.mp_cmd (MP_ENABLE_PATH) : %d", + mp_ioctl.mp_cmd); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_EnablePath()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_EnablePath()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_EnablePath()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_EnablePath()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_EnablePath()", + " - error exit"); + + return (mpStatus); + } + + + log(LOG_INFO, "MP_EnablePath()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetAssociatedPathOidList.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetAssociatedPathOidList.c new file mode 100644 index 0000000000..cfc0842afa --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetAssociatedPathOidList.c @@ -0,0 +1,652 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" + +#include <libdevinfo.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/stat.h> + + +static MP_STATUS doDevInfoStuffForIntPort(MP_OID oid) +{ + di_node_t root_node = DI_NODE_NIL; + + di_node_t vh_node = DI_NODE_NIL; + di_node_t ph_node = DI_NODE_NIL; + di_node_t sv_node = DI_NODE_NIL; + + + di_path_t path = DI_PATH_NIL; + + struct stat buffer; + + int instNum = 0; + int majorNum = 0; + + int oidInstNum = 0; + int oidMajorNum = 0; + + int found = 0; + int status = -1; + + + char *pathName = NULL; + char *minorName = "c"; + + char fullName[512]; + + + + + log(LOG_INFO, "doDevInfoStuffForIntPort()", " - enter"); + + + oidInstNum = (int)MP_GET_INST_FROM_ID(oid.objectSequenceNumber); + oidMajorNum = (int)MP_GET_MAJOR_FROM_ID(oid.objectSequenceNumber); + + + root_node = di_init("/", DINFOCACHE); + if (DI_NODE_NIL == root_node) { + log(LOG_INFO, "doDevInfoStuffForIntPort()", + " - di_init() failed"); + + return (MP_STATUS_FAILED); + } + + vh_node = di_vhci_first_node(root_node); + + while (DI_NODE_NIL != vh_node) { + if ((di_driver_name(vh_node) != NULL) && + (strncmp(di_driver_name(vh_node), "scsi_vhci", 9) == 0)) { + ph_node = di_phci_first_node(vh_node); + while (DI_NODE_NIL != ph_node) { + + instNum = di_instance(ph_node); + majorNum = di_driver_major(ph_node); + + if ((majorNum == oidMajorNum) && + (instNum == oidInstNum)) { + + log(LOG_INFO, + "doDevInfoStuffForIntPort()", + "got a match"); + + found = 1; + + break; + } + + ph_node = di_phci_next_node(ph_node); + } + } + + if (found) { + + break; + } + + vh_node = di_vhci_next_node(vh_node); + } + + + if (!found) { + + di_fini(root_node); + + log(LOG_INFO, + "doDevInfoStuffForIntPort()", + " - no match found, error exit"); + + return (MP_STATUS_OBJECT_NOT_FOUND); + } + + + path = di_path_next(ph_node, DI_PATH_NIL); + + if (DI_PATH_NIL == path) { + + log(LOG_INFO, "doDevInfoStuffForIntPort()", + " - path is DI_PATH_NIL"); + } + + while (DI_PATH_NIL != path) { + + sv_node = di_path_client_node(path); + if (DI_NODE_NIL == sv_node) { + + log(LOG_INFO, "doDevInfoStuffForIntPort()", + " - sv_node is DI_NODE_NIL"); + + } else { + + pathName = di_devfs_path(sv_node); + (void) snprintf(fullName, 511, "/devices%s:%s", + pathName, minorName); + + (void) di_devfs_path_free(pathName); + + status = stat(fullName, &buffer); + if (status < 0) { + + log(LOG_INFO, + "doDevInfoStuffForIntPort()", + " - stat() call failed: %d", status); + + log(LOG_INFO, + "doDevInfoStuffForIntPort()", + " - errno: [%d].", errno); + + log(LOG_INFO, + "doDevInfoStuffForIntPort()", + " - strerror(errno): [%s].", + strerror(errno)); + + + di_fini(root_node); + + log(LOG_INFO, + "doDevInfoStuffForIntPort()", + " - error exit."); + + return (MP_STATUS_FAILED); + } + } + + path = di_path_next(ph_node, path); + } + + + di_fini(root_node); + + log(LOG_INFO, "doDevInfoStuffForIntPort()", " - exit"); + + return (MP_STATUS_SUCCESS); +} + + +static MP_STATUS doDevInfoStuffForTargetPort(MP_OID oid) +{ + di_node_t root_node = DI_NODE_NIL; + di_node_t sv_node = DI_NODE_NIL; + di_node_t child_node = DI_NODE_NIL; + + di_path_t path = DI_PATH_NIL; + + int match = 0; + int count = 0; + int ioctlStatus = 0; + int status = -1; + + struct stat buffer; + + char *pathName = NULL; + char *minorName = "c"; + + char fullName[512]; + + uchar_t *targetPort = NULL; + + mp_iocdata_t mp_ioctl; + + mp_target_port_prop_t tpInfo; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "doDevInfoStuffForTargetPort()", " - enter"); + + + log(LOG_INFO, "doDevInfoStuffForTargetPort()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&tpInfo, 0, sizeof (mp_target_port_prop_t)); + + mp_ioctl.mp_cmd = MP_GET_TARGET_PORT_PROP; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)&tpInfo; + mp_ioctl.mp_olen = sizeof (mp_target_port_prop_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, "doDevInfoStuffForTargetPort()", + "mp_ioctl.mp_cmd (MP_GET_TARGET_PORT_PROP) : %d", + mp_ioctl.mp_cmd); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "doDevInfoStuffForTargetPort()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "doDevInfoStuffForTargetPort()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "doDevInfoStuffForTargetPort()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "doDevInfoStuffForTargetPort()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = + getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "doDevInfoStuffForTargetPort()", + " - error exit"); + + return (mpStatus); + } + + root_node = di_init("/", DINFOCACHE); + + if (DI_NODE_NIL == root_node) { + log(LOG_INFO, "doDevInfoStuffForTargetPort()", + " - di_init() failed"); + + return (MP_STATUS_FAILED); + } + + + sv_node = di_drv_first_node("scsi_vhci", root_node); + if (DI_NODE_NIL == sv_node) { + log(LOG_INFO, "doDevInfoStuffForTargetPort()", + " - di_drv_first_node() failed"); + + di_fini(root_node); + + return (MP_STATUS_FAILED); + } + + child_node = di_child_node(sv_node); + + while (DI_NODE_NIL != child_node) { + + path = di_path_next(child_node, path); + + match = 0; + + while (DI_PATH_NIL != path) { + + count = di_path_prop_lookup_bytes(path, + "target-port", + &targetPort); + + if (NULL != targetPort) { + + if (0 == memcmp(targetPort, + tpInfo.portName, + count)) { + + match = 1; + + break; + } + } + + path = di_path_next(child_node, path); + } + + if (match) { + + log(LOG_INFO, "doDevInfoStuffForTargetPort()", + " - got a match"); + + pathName = di_devfs_path(child_node); + + (void) snprintf(fullName, 511, "/devices%s:%s", + pathName, minorName); + + (void) di_devfs_path_free(pathName); + + status = stat(fullName, &buffer); + if (status < 0) { + + log(LOG_INFO, + "doDevInfoStuffForTargetPort()", + " - stat() call failed: %d", status); + + log(LOG_INFO, + "doDevInfoStuffForTargetPort()", + " - errno: [%d].", errno); + + log(LOG_INFO, + "doDevInfoStuffForTargetPort()", + " - strerror(errno): [%s].", + strerror(errno)); + + + di_fini(root_node); + + log(LOG_INFO, + "doDevInfoStuffForTargetPort()", + " - error exit."); + + return (MP_STATUS_FAILED); + } + } + + child_node = di_sibling_node(child_node); + } + + + di_fini(root_node); + + log(LOG_INFO, "doDevInfoStuffForTargetPort()", " - exit"); + + return (MP_STATUS_SUCCESS); +} + + + +MP_STATUS +MP_GetAssociatedPathOidList(MP_OID oid, MP_OID_LIST **ppList) +{ + mp_iocdata_t mp_ioctl; + + uint64_t *objList = NULL; + + int numOBJ = 0; + int i = 0; + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + int request = MP_GET_PATH_LIST_FOR_MP_LU; + + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", " - enter"); + + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + " set default request to MP_GET_PATH_LIST_FOR_MP_LU"); + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "invalid driver file handle"); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", " - error exit"); + return (MP_STATUS_FAILED); + } + + if (MP_OBJECT_TYPE_INITIATOR_PORT == oid.objectType) { + request = MP_GET_PATH_LIST_FOR_INIT_PORT; + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + " set request to MP_GET_PATH_LIST_FOR_INIT_PORT"); + + mpStatus = doDevInfoStuffForIntPort(oid); + if (MP_STATUS_SUCCESS != mpStatus) { + + return (mpStatus); + } + } else if (MP_OBJECT_TYPE_TARGET_PORT == oid.objectType) { + request = MP_GET_PATH_LIST_FOR_TARGET_PORT; + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + " set request to MP_GET_PATH_LIST_FOR_TARGET_PORT"); + + mpStatus = doDevInfoStuffForTargetPort(oid); + if (MP_STATUS_SUCCESS != mpStatus) { + + return (mpStatus); + } + } + + objList = (uint64_t *)calloc(1, DEFAULT_BUFFER_SIZE_PATH_LIST); + if (NULL == objList) { + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "no memory for objList(1)"); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = request; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)objList; + mp_ioctl.mp_olen = DEFAULT_BUFFER_SIZE_PATH_LIST; + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "mp_ioctl.mp_cmd : %d", mp_ioctl.mp_cmd); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "mp_ioctl.mp_obuf: %x", mp_ioctl.mp_obuf); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "mp_ioctl.mp_olen: %d", mp_ioctl.mp_olen); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "mp_ioctl.mp_xfer: %d (MP_XFER_READ)", + mp_ioctl.mp_xfer); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "ioctl call returned ioctlStatus: %d", + ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if ((ioctlStatus != 0) && (MP_MORE_DATA != mp_ioctl.mp_errno)) { + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + + free(objList); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + " - error exit"); + + return (mpStatus); + } + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + " - mp_ioctl.mp_alen : %d", + mp_ioctl.mp_alen); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + " - sizeof (uint64_t): %d", + sizeof (uint64_t)); + + numOBJ = mp_ioctl.mp_alen / sizeof (uint64_t); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "Length of list: %d", numOBJ); + + if (numOBJ < 1) { + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "driver returned empty list."); + + free(objList); + + *ppList = createOidList(1); + if (NULL == *ppList) { + log(LOG_INFO, + "MP_GetAssociatedPathOidList()", + "no memory for MP_OID_LIST"); + log(LOG_INFO, + "MP_GetAssociatedPathOidList()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + return (MP_STATUS_SUCCESS); + } + + if (mp_ioctl.mp_alen > DEFAULT_BUFFER_SIZE_PATH_LIST) { + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "buffer size too small, need : %d", + mp_ioctl.mp_alen); + + free(objList); + + objList = (uint64_t *)calloc(1, numOBJ * sizeof (uint64_t)); + if (NULL == objList) { + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "no memory for objList(2)"); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = request; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)objList; + mp_ioctl.mp_olen = numOBJ * sizeof (uint64_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "mp_ioctl.mp_cmd : %d", mp_ioctl.mp_cmd); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "mp_ioctl.mp_obuf: %x", mp_ioctl.mp_obuf); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "mp_ioctl.mp_olen: %d", mp_ioctl.mp_olen); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "mp_ioctl.mp_xfer: %d (MP_XFER_READ)", + mp_ioctl.mp_xfer); + + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "ioctl call returned ioctlStatus: %d", + ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + + free(objList); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = + getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + " - error exit"); + + return (mpStatus); + } + } + + + *ppList = createOidList(numOBJ); + if (NULL == *ppList) { + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "no memory for *ppList"); + free(objList); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (*ppList)->oidCount = numOBJ; + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "(*ppList)->oidCount = %d", + (*ppList)->oidCount); + + for (i = 0; i < numOBJ; i++) { + (*ppList)->oids[i].objectType = MP_OBJECT_TYPE_PATH_LU; + (*ppList)->oids[i].ownerId = g_pluginOwnerID; + (*ppList)->oids[i].objectSequenceNumber = objList[i]; + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "(*ppList)->oids[%d].objectType = %d", + i, (*ppList)->oids[i].objectType); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "(*ppList)->oids[%d].ownerId = %d", + i, (*ppList)->oids[i].ownerId); + log(LOG_INFO, "MP_GetAssociatedPathOidList()", + "(*ppList)->oids[%d].objectSequenceNumber = %llx", + i, (*ppList)->oids[i].objectSequenceNumber); + } + + free(objList); + + + log(LOG_INFO, "MP_GetAssociatedPathOidList()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetAssociatedTPGOidList.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetAssociatedTPGOidList.c new file mode 100644 index 0000000000..9223803e10 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetAssociatedTPGOidList.c @@ -0,0 +1,295 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" +MP_STATUS +MP_GetAssociatedTPGOidList(MP_OID oid, MP_OID_LIST **ppList) +{ + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "MP_GetAssociatedTPGOidList()", " - enter"); + + + mpStatus = getAssociatedTPGOidList(oid, ppList); + + + log(LOG_INFO, "MP_GetAssociatedTPGOidList()", " - exit"); + + return (mpStatus); +} + + +MP_STATUS +getAssociatedTPGOidList(MP_OID oid, MP_OID_LIST **ppList) +{ + mp_iocdata_t mp_ioctl; + + uint64_t *objList = NULL; + + int numOBJ = 0; + int i = 0; + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "getAssociatedTPGOidList()", " - enter"); + + + log(LOG_INFO, "getAssociatedTPGOidList()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "getAssociatedTPGOidList()", + "invalid driver file handle"); + log(LOG_INFO, "getAssociatedTPGOidList()", " - error exit"); + return (MP_STATUS_FAILED); + } + + objList = (uint64_t *)calloc(1, DEFAULT_BUFFER_SIZE_TPG); + if (NULL == objList) { + log(LOG_INFO, "getAssociatedTPGOidList()", + "no memory for objList(1)"); + log(LOG_INFO, "getAssociatedTPGOidList()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = MP_GET_TPG_LIST; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)objList; + mp_ioctl.mp_olen = DEFAULT_BUFFER_SIZE_TPG; + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, "getAssociatedTPGOidList()", + "mp_ioctl.mp_cmd (MP_GET_TPG_LIST) : %d", + mp_ioctl.mp_cmd); + log(LOG_INFO, "getAssociatedTPGOidList()", + "mp_ioctl.mp_obuf: %x", mp_ioctl.mp_obuf); + log(LOG_INFO, "getAssociatedTPGOidList()", + "mp_ioctl.mp_olen: %d", mp_ioctl.mp_olen); + log(LOG_INFO, "getAssociatedTPGOidList()", + "mp_ioctl.mp_xfer: %d (MP_XFER_READ)", + mp_ioctl.mp_xfer); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + log(LOG_INFO, "getAssociatedTPGOidList()", + "ioctl call returned ioctlStatus: %d", + ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if ((ioctlStatus != 0) && (MP_MORE_DATA != mp_ioctl.mp_errno)) { + + log(LOG_INFO, "getAssociatedTPGOidList()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "getAssociatedTPGOidList()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "getAssociatedTPGOidList()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + + free(objList); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "getAssociatedTPGOidList()", + " - error exit, returning %d to caller.", mpStatus); + + return (mpStatus); + } + + log(LOG_INFO, "getAssociatedTPGOidList()", + " - mp_ioctl.mp_alen : %d", + mp_ioctl.mp_alen); + log(LOG_INFO, "getAssociatedTPGOidList()", + " - sizeof (uint64_t): %d", + sizeof (uint64_t)); + + numOBJ = mp_ioctl.mp_alen / sizeof (uint64_t); + log(LOG_INFO, "getAssociatedTPGOidList()", + "Length of list: %d", numOBJ); + + if (numOBJ < 1) { + log(LOG_INFO, "getAssociatedTPGOidList()", + "driver returned empty list."); + + free(objList); + + *ppList = createOidList(1); + if (NULL == *ppList) { + log(LOG_INFO, + "getAssociatedTPGOidList()", + "no memory for MP_OID_LIST"); + log(LOG_INFO, + "getAssociatedTPGOidList()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + return (MP_STATUS_SUCCESS); + } + + if (mp_ioctl.mp_alen > DEFAULT_BUFFER_SIZE_TPG) { + + log(LOG_INFO, "getAssociatedTPGOidList()", + "buffer size too small, need : %d", + mp_ioctl.mp_alen); + + free(objList); + + objList = (uint64_t *)calloc(1, numOBJ * sizeof (uint64_t)); + if (NULL == objList) { + log(LOG_INFO, "getAssociatedTPGOidList()", + "no memory for objList(2)"); + log(LOG_INFO, "getAssociatedTPGOidList()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = MP_GET_TPG_LIST; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)objList; + mp_ioctl.mp_olen = numOBJ * sizeof (uint64_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, "getAssociatedTPGOidList()", + "mp_ioctl.mp_cmd (MP_GET_TPG_LIST) : %d", + mp_ioctl.mp_cmd); + log(LOG_INFO, "getAssociatedTPGOidList()", + "mp_ioctl.mp_obuf: %x", mp_ioctl.mp_obuf); + log(LOG_INFO, "getAssociatedTPGOidList()", + "mp_ioctl.mp_olen: %d", mp_ioctl.mp_olen); + log(LOG_INFO, "getAssociatedTPGOidList()", + "mp_ioctl.mp_xfer: %d (MP_XFER_READ)", + mp_ioctl.mp_xfer); + + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + log(LOG_INFO, "getAssociatedTPGOidList()", + "ioctl call returned ioctlStatus: %d", + ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + + log(LOG_INFO, "getAssociatedTPGOidList()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "getAssociatedTPGOidList()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "getAssociatedTPGOidList()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + + free(objList); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = + getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "getAssociatedTPGOidList()", + " - error exit"); + + return (mpStatus); + } + } + + + *ppList = createOidList(numOBJ); + if (NULL == *ppList) { + log(LOG_INFO, "getAssociatedTPGOidList()", + "no memory for *ppList"); + free(objList); + log(LOG_INFO, "getAssociatedTPGOidList()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (*ppList)->oidCount = numOBJ; + + log(LOG_INFO, "getAssociatedTPGOidList()", + "(*ppList)->oidCount = %d", + (*ppList)->oidCount); + + for (i = 0; i < numOBJ; i++) { + (*ppList)->oids[i].objectType = + MP_OBJECT_TYPE_TARGET_PORT_GROUP; + (*ppList)->oids[i].ownerId = g_pluginOwnerID; + (*ppList)->oids[i].objectSequenceNumber = objList[i]; + + log(LOG_INFO, "getAssociatedTPGOidList()", + "(*ppList)->oids[%d].objectType = %d", + i, (*ppList)->oids[i].objectType); + log(LOG_INFO, "getAssociatedTPGOidList()", + "(*ppList)->oids[%d].ownerId = %d", + i, (*ppList)->oids[i].ownerId); + log(LOG_INFO, "getAssociatedTPGOidList()", + "(*ppList)->oids[%d].objectSequenceNumber = %llx", + i, (*ppList)->oids[i].objectSequenceNumber); + } + + free(objList); + + + log(LOG_INFO, "getAssociatedTPGOidList()", + " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetDeviceProductOidListPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetDeviceProductOidListPlugin.c new file mode 100644 index 0000000000..f01cda2535 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetDeviceProductOidListPlugin.c @@ -0,0 +1,278 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" + + +/* + * Called by the common layer to request a list of Device Products + */ + +MP_STATUS +MP_GetDeviceProductOidListPlugin(MP_OID_LIST **ppList) +{ + mp_iocdata_t mp_ioctl; + + uint64_t *objList = NULL; + + int numOBJ = 0; + int i = 0; + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", " - enter"); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "invalid driver file handle"); + return (MP_STATUS_FAILED); + } + + + objList = (uint64_t *)calloc(1, DEFAULT_BUFFER_SIZE_DEV_PROD); + if (NULL == objList) { + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "no memory for objList(1)"); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = MP_GET_DEV_PROD_LIST; + mp_ioctl.mp_obuf = (caddr_t)objList; + mp_ioctl.mp_olen = DEFAULT_BUFFER_SIZE_DEV_PROD; + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "mp_ioctl.mp_cmd : %d (MP_GET_DEV_PROD_LIST)", + mp_ioctl.mp_cmd); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "mp_ioctl.mp_obuf: %x", + mp_ioctl.mp_obuf); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "mp_ioctl.mp_olen: %d", + mp_ioctl.mp_olen); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "mp_ioctl.mp_xfer: %d (MP_XFER_READ)", + mp_ioctl.mp_xfer); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "ioctl call returned ioctlStatus: %d", + ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if ((ioctlStatus != 0) && (MP_MORE_DATA != mp_ioctl.mp_errno)) { + + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + + free(objList); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + " - error exit"); + + return (mpStatus); + } + + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + " - mp_ioctl.mp_alen : %d", + mp_ioctl.mp_alen); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + " - sizeof (uint64_t): %d", + sizeof (uint64_t)); + + numOBJ = mp_ioctl.mp_alen / sizeof (uint64_t); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "Length of list: %d", numOBJ); + + if (numOBJ < 1) { + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "driver returned empty list."); + + free(objList); + + *ppList = createOidList(1); + if (NULL == *ppList) { + log(LOG_INFO, + "MP_GetDeviceProductOidListPlugin()", + "no memory for MP_OID_LIST"); + log(LOG_INFO, + "MP_GetDeviceProductOidListPlugin()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + return (MP_STATUS_SUCCESS); + } + + + if (mp_ioctl.mp_alen > DEFAULT_BUFFER_SIZE_DEV_PROD) { + + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "buffer size too small, need : %d", + mp_ioctl.mp_alen); + + free(objList); + + objList = (uint64_t *)calloc(1, numOBJ * sizeof (uint64_t)); + if (NULL == objList) { + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "no memory for objList(2)"); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = MP_GET_DEV_PROD_LIST; + mp_ioctl.mp_obuf = (caddr_t)objList; + mp_ioctl.mp_olen = numOBJ * sizeof (uint64_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "mp_ioctl.mp_cmd : %d (MP_GET_DEV_PROD_LIST)", + mp_ioctl.mp_cmd); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "mp_ioctl.mp_obuf: %x", + mp_ioctl.mp_obuf); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "mp_ioctl.mp_olen: %d", + mp_ioctl.mp_olen); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "mp_ioctl.mp_xfer: %d (MP_XFER_READ)", + mp_ioctl.mp_xfer); + + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "ioctl call returned ioctlStatus: %d", + ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + + free(objList); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = + getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + " - error exit"); + + return (mpStatus); + } + } + + + *ppList = createOidList(numOBJ); + if (NULL == *ppList) { + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "no memory for *ppList"); + free(objList); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (*ppList)->oidCount = numOBJ; + + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "(*ppList)->oidCount = %d", + (*ppList)->oidCount); + + for (i = 0; i < numOBJ; i++) { + (*ppList)->oids[i].objectType = MP_OBJECT_TYPE_DEVICE_PRODUCT; + (*ppList)->oids[i].ownerId = g_pluginOwnerID; + (*ppList)->oids[i].objectSequenceNumber = objList[i]; + + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "(*ppList)->oids[%d].objectType = %d", + i, (*ppList)->oids[i].objectType); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "(*ppList)->oids[%d].ownerId = %d", + i, (*ppList)->oids[i].ownerId); + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + "(*ppList)->oids[%d].objectSequenceNumber = %llx", + i, (*ppList)->oids[i].objectSequenceNumber); + } + + free(objList); + + + log(LOG_INFO, "MP_GetDeviceProductOidListPlugin()", + " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetDeviceProductProperties.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetDeviceProductProperties.c new file mode 100644 index 0000000000..838d6f2360 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetDeviceProductProperties.c @@ -0,0 +1,140 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 "mp_utils.h" + +#include <string.h> +#include <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + + +/* + * Called by the common layer to request properties for a Device Product + */ + +MP_STATUS +MP_GetDeviceProductProperties(MP_OID oid, MP_DEVICE_PRODUCT_PROPERTIES *pProps) +{ + mp_iocdata_t mp_ioctl; + mp_dev_prod_prop_t devProdInfo; + + int ioctlStatus = 0; + + int vendorLength = 0; + int productLength = 0; + int revisionLength = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "MP_GetDeviceProductProperties()", " - enter"); + + log(LOG_INFO, "MP_GetDeviceProductProperties()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_GetDeviceProductProperties()", + "invalid driver file handle"); + log(LOG_INFO, "MP_GetDeviceProductProperties", + " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&devProdInfo, 0, sizeof (mp_dev_prod_prop_t)); + + mp_ioctl.mp_cmd = MP_GET_DEV_PROD_PROP; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)&devProdInfo; + mp_ioctl.mp_olen = sizeof (mp_dev_prod_prop_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_GetDeviceProductProperties()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_GetDeviceProductProperties()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetDeviceProductProperties()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetDeviceProductProperties()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetDeviceProductProperties()", + " - error exit"); + + return (mpStatus); + } + + (void) memset(pProps, 0, sizeof (MP_DEVICE_PRODUCT_PROPERTIES)); + + + vendorLength = sizeof (pProps->vendor); + productLength = sizeof (pProps->product); + revisionLength = sizeof (pProps->revision); + + + (void) strncpy(pProps->vendor, + devProdInfo.prodInfo.vendor, + vendorLength); + + (void) strncpy(pProps->product, + devProdInfo.prodInfo.product, + productLength); + + (void) strncpy(pProps->revision, + devProdInfo.prodInfo.revision, + revisionLength); + + pProps->supportedLoadBalanceTypes = + devProdInfo.supportedLoadBalanceTypes; + + + log(LOG_INFO, "MP_GetDeviceProductProperties()", + " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetInitiatorPortOidListPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetInitiatorPortOidListPlugin.c new file mode 100644 index 0000000000..310de4766c --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetInitiatorPortOidListPlugin.c @@ -0,0 +1,193 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" + +#include <libdevinfo.h> + + +static int getOidList(di_node_t root_node, MP_OID_LIST *pOidList) +{ + int numNodes = 0; + int instNum = 0; + int majorNum = 0; + + di_node_t vh_node = DI_NODE_NIL; + di_node_t ph_node = DI_NODE_NIL; + + MP_UINT64 osn = 0; + + int haveList = (NULL != pOidList); + + + log(LOG_INFO, "getOidList()", " - enter"); + + vh_node = di_vhci_first_node(root_node); + + while (DI_NODE_NIL != vh_node) { + if ((di_driver_name(vh_node) != NULL) && + (strncmp(di_driver_name(vh_node), "scsi_vhci", 9) == 0)) { + ph_node = di_phci_first_node(vh_node); + while (DI_NODE_NIL != ph_node) { + if (haveList) { + + instNum = di_instance(ph_node); + majorNum = di_driver_major(ph_node); + + log(LOG_INFO, "getOidList()", + "instNum = %d", + instNum); + + log(LOG_INFO, "getOidList()", + "majorNum = %d", + majorNum); + + if (numNodes < pOidList->oidCount) { + + osn = 0; + + osn = + MP_STORE_INST_TO_ID(instNum, + osn); + + osn = + MP_STORE_MAJOR_TO_ID(majorNum, + osn); + + pOidList->oids[numNodes] + .objectSequenceNumber = + osn; + + pOidList->oids[numNodes]. + objectType = + MP_OBJECT_TYPE_INITIATOR_PORT; + + pOidList->oids[numNodes]. + ownerId = + g_pluginOwnerID; + } + } + + ++numNodes; + ph_node = di_phci_next_node(ph_node); + } + + } + vh_node = di_vhci_next_node(vh_node); + } + + log(LOG_INFO, + "getOidList()", + " - numNodes: %d", + numNodes); + + + log(LOG_INFO, "getOidList()", " - exit"); + + return (numNodes); +} + + + +MP_STATUS +MP_GetInitiatorPortOidListPlugin(MP_OID_LIST **ppList) +{ + di_node_t root_node = DI_NODE_NIL; + + int i = 0; + int numNodes = 0; + + + + log(LOG_INFO, "MP_GetInitiatorPortOidListPlugin()", " - enter"); + + + root_node = di_init("/", DINFOCACHE); + if (DI_NODE_NIL == root_node) { + log(LOG_INFO, "MP_GetInitiatorPortOidListPlugin()", + " - di_init() failed"); + + return (MP_STATUS_FAILED); + } + + numNodes = getOidList(root_node, NULL); + + if (numNodes < 1) { + + *ppList = createOidList(1); + + if (NULL == *ppList) { + log(LOG_INFO, "MP_GetInitiatorPortOidListPlugin()", + "no memory for *ppList"); + log(LOG_INFO, "MP_GetInitiatorPortOidListPlugin()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + log(LOG_INFO, "MP_GetInitiatorPortOidListPlugin()", + " - returning empty list."); + + return (MP_STATUS_SUCCESS); + } + + *ppList = createOidList(numNodes); + if (NULL == *ppList) { + log(LOG_INFO, "MP_GetInitiatorPortOidListPlugin()", + "no memory for *ppList"); + log(LOG_INFO, "MP_GetInitiatorPortOidListPlugin()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (*ppList)->oidCount = numNodes; + + numNodes = getOidList(root_node, *ppList); + + for (i = 0; i < (*ppList)->oidCount; i++) { + + log(LOG_INFO, "MP_GetInitiatorPortOidListPlugin()", + "(*ppList)->oids[%d].objectType = %d", + i, (*ppList)->oids[i].objectType); + log(LOG_INFO, "MP_GetInitiatorPortOidListPlugin()", + "(*ppList)->oids[%d].ownerId = %d", + i, (*ppList)->oids[i].ownerId); + log(LOG_INFO, "MP_GetInitiatorPortOidListPlugin()", + "(*ppList)->oids[%d].objectSequenceNumber = %llx", + i, (*ppList)->oids[i].objectSequenceNumber); + } + + + di_fini(root_node); + + + log(LOG_INFO, "MP_GetInitiatorPortOidListPlugin()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetInitiatorPortProperties.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetInitiatorPortProperties.c new file mode 100644 index 0000000000..1a81b0a643 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetInitiatorPortProperties.c @@ -0,0 +1,124 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 "mp_utils.h" + +#include <string.h> +#include <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + + + +MP_STATUS +MP_GetInitiatorPortProperties(MP_OID oid, MP_INITIATOR_PORT_PROPERTIES *pProps) +{ + mp_iocdata_t mp_ioctl; + mp_init_port_prop_t initPortInfo; + + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "MP_GetInitiatorPortProperties()", " - enter"); + + + log(LOG_INFO, "MP_GetInitiatorPortProperties()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_GetInitiatorPortProperties()", + "invalid driver file handle"); + log(LOG_INFO, "MP_GetInitiatorPortProperties()", + " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&initPortInfo, 0, sizeof (mp_init_port_prop_t)); + + mp_ioctl.mp_cmd = MP_GET_INIT_PORT_PROP; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)&initPortInfo; + mp_ioctl.mp_olen = sizeof (mp_init_port_prop_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_GetInitiatorPortProperties()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_GetInitiatorPortProperties()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetInitiatorPortProperties()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetInitiatorPortProperties()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetInitiatorPortProperties()", + " - error exit"); + + return (mpStatus); + } + + (void) memset(pProps, 0, sizeof (MP_INITIATOR_PORT_PROPERTIES)); + + (void) strncpy(pProps->osDeviceFile, + initPortInfo.osDeviceFile, + sizeof (pProps->osDeviceFile)); + (void) strncpy(pProps->portID, + initPortInfo.portID, + sizeof (pProps->portID)); + pProps->portType = + initPortInfo.portType; + + + /* where does "pProps->osFriendlyName" (MP_WCHAR) come from ??? */ + + + log(LOG_INFO, "MP_GetInitiatorPortProperties()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMPLogicalUnitProperties.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMPLogicalUnitProperties.c new file mode 100644 index 0000000000..94fe7c9f72 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMPLogicalUnitProperties.c @@ -0,0 +1,351 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <string.h> +#include <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include <libdevinfo.h> + +#include "mp_utils.h" + + +typedef struct walk_devlink { + char *path; + size_t len; + char **linkpp; +} walk_devlink_t; + + + +static int +get_devlink(di_devlink_t devlink, void *arg) { + + walk_devlink_t *warg = (walk_devlink_t *)arg; + + + log(LOG_INFO, "get_devlink()", " - enter"); + + + *(warg->linkpp) = strdup(di_devlink_path(devlink)); + + + log(LOG_INFO, "get_devlink()", " - exit"); + + return (DI_WALK_TERMINATE); +} + + +char +*getDeviceFileName(MP_UINT64 instanceNum) +{ + char *deviceFileName = NULL; + + di_node_t root_node = DI_NODE_NIL; + di_node_t cur_node = DI_NODE_NIL; + + MP_UINT64 nodeInstance = 0; + + char *pathName = NULL; + char *minorName = "c,raw"; + char *devLink = NULL; + + char fullName[512]; + + walk_devlink_t warg; + di_devlink_handle_t dlHandle = NULL; + + int diStatus = 0; + + + log(LOG_INFO, "getDeviceFileName()", " - enter"); + + log(LOG_INFO, "getDeviceFileName()", + " - instanceNum: %llx", + instanceNum); + + root_node = di_init("/", DINFOCACHE); + if (DI_NODE_NIL == root_node) { + log(LOG_INFO, "MP_GetMultipathLusPlugin()", + " - $ERROR, di_init() failed"); + + return (NULL); + } + + + cur_node = di_drv_first_node("scsi_vhci", root_node); + if (DI_NODE_NIL == cur_node) { + log(LOG_INFO, "getDeviceFileName()", + " - $ERROR, di_drv_first_node() failed"); + + di_fini(root_node); + + return (NULL); + } + + + cur_node = di_child_node(cur_node); + + while (DI_NODE_NIL != cur_node) { + + nodeInstance = + (MP_UINT64)di_instance(cur_node); + + if (nodeInstance == instanceNum) { + + log(LOG_INFO, "getDeviceFileName()", + " - found node."); + + break; + } + + cur_node = di_sibling_node(cur_node); + } + + if (DI_NODE_NIL != cur_node) { + + dlHandle = di_devlink_init(NULL, 0); + if (NULL == dlHandle) { + log(LOG_INFO, "getDeviceFileName()", + " - $ERROR, di_devlink_init() failed."); + + di_fini(root_node); + + return (NULL); + } + + pathName = di_devfs_path(cur_node); + + (void) snprintf(fullName, 511, "%s:%s", pathName, minorName); + + log(LOG_INFO, "getDeviceFileName()", + " - fullName: {%s]", fullName); + + (void) memset(&warg, 0, sizeof (walk_devlink_t)); + + devLink = NULL; + warg.linkpp = &devLink; + + diStatus = di_devlink_walk(dlHandle, + NULL, + fullName, + DI_PRIMARY_LINK, + (void *)&warg, + get_devlink); + + if (diStatus != 0) { + + log(LOG_INFO, "getDeviceFileName()", + "diStatus: %d", diStatus); + + if (diStatus < 0) { + diStatus = errno; + } + + log(LOG_INFO, "getDeviceFileName()", + "diStatus: %d", diStatus); + + log(LOG_INFO, "getDeviceFileName()", + "strerror(diStatus): %s", strerror(diStatus)); + } + + if (NULL != devLink) { + + deviceFileName = + (char *)calloc(1, strlen(devLink) + 1); + + (void) strncpy(deviceFileName, devLink, + strlen(devLink)); + + } else { + + log(LOG_INFO, "getDeviceFileName()", + " - $ERROR, devLink is NULL."); + + deviceFileName = + (char *)calloc(1, 256); + + (void) strncpy(deviceFileName, pathName, 255); + } + + di_devfs_path_free(pathName); + + (void) di_devlink_fini(&dlHandle); + + } + + + di_fini(root_node); + + + log(LOG_INFO, "getDeviceFileName()", " - exit"); + + return (deviceFileName); +} + + + +MP_STATUS +MP_GetMPLogicalUnitProperties(MP_OID oid, + MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES *pProps) +{ + mp_iocdata_t mp_ioctl; + mp_logical_unit_prop_t luInfo; + + MP_OID overridePathOID; + + int ioctlStatus = 0; + + int vendorLength = 0; + int productLength = 0; + int revisionLength = 0; + + char *deviceFileName = NULL; + + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", " - enter"); + + + log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", + "invalid driver file handle"); + log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", + " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&luInfo, 0, sizeof (mp_logical_unit_prop_t)); + + mp_ioctl.mp_cmd = MP_GET_LU_PROP; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)&luInfo; + mp_ioctl.mp_olen = sizeof (mp_logical_unit_prop_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", + " - error exit"); + + return (mpStatus); + } + + (void) memset(pProps, 0, sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES)); + + pProps->asymmetric = luInfo.asymmetric; + pProps->autoFailbackEnabled = luInfo.autoFailbackEnabled; + pProps->autoProbingEnabled = luInfo.autoProbingEnabled; + pProps->currentFailbackPollingRate = luInfo.currentFailBackPollingRate; + pProps->currentLoadBalanceType = luInfo.currentLoadBalanceType; + pProps->currentProbingPollingRate = luInfo.currentProbingPollingRate; + + + deviceFileName = getDeviceFileName(oid.objectSequenceNumber); + + if (NULL != deviceFileName) { + + log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", + "deviceFileName: %s", + deviceFileName); + + (void) strncpy(pProps->deviceFileName, + deviceFileName, + sizeof (pProps->deviceFileName) - 1); + + free(deviceFileName); + } + + pProps->failbackPollingRateMax = luInfo.failbackPollingRateMax; + pProps->logicalUnitGroupID = luInfo.luGroupID; + + (void) strncpy(pProps->name, luInfo.name, sizeof (pProps->name) - 1); + + pProps->nameType = luInfo.nameType; + + overridePathOID.objectSequenceNumber = luInfo.overridePathID; + overridePathOID.objectType = MP_OBJECT_TYPE_PATH_LU; + overridePathOID.ownerId = g_pluginOwnerID; + (void) memcpy(&pProps->overridePath, &overridePathOID, sizeof (MP_OID)); + + pProps->probingPollingRateMax = luInfo.probingPollingRateMax; + + + vendorLength = sizeof (pProps->vendor); + productLength = sizeof (pProps->product); + revisionLength = sizeof (pProps->revision); + + (void) strncpy(pProps->vendor, + luInfo.prodInfo.vendor, + vendorLength); + + (void) strncpy(pProps->product, + luInfo.prodInfo.product, + productLength); + + (void) strncpy(pProps->revision, + luInfo.prodInfo.revision, + revisionLength); + + log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMPLuOidListFromTPG.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMPLuOidListFromTPG.c new file mode 100644 index 0000000000..bb05513cb3 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMPLuOidListFromTPG.c @@ -0,0 +1,508 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <errno.h> +#include <unistd.h> +#include <stropts.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <libdevinfo.h> +#include <sys/stat.h> + +#include "mp_utils.h" + + +/* + * The plugin library will call MP_CMD ioctl with + * MP_GET_TARGET_PORT_LIST_FOR_TPG subcommand. + * For each target port, the plugin will get the target port name property. + * + * A scsi_vhci device with pathinfo containing matching target port name + * may potentially be associated with the given TPG. + * The plugin library will check the TPG list for qualifying scsi_vhci + * devices and find a matching TPG id. + * + * An rfe was filed against MDI to + * refresh DINFOCACHE snapshot for pathinfo update. + */ + + + + + +/* + * Returns MP_TRUE if the ID found in the dev info snapshot matches the ID + * provided by the schi_vhci driver. + */ + +static int checkTPGList(MP_UINT32 tpgID, int inst_num) +{ + int tpg = 0; + int status = MP_FALSE; + + MP_OID luOID; + + MP_OID_LIST *ppList = NULL; + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + MP_TARGET_PORT_GROUP_PROPERTIES tpgProps; + + + + log(LOG_INFO, "checkTPGList()", " - enter"); + + + luOID.objectSequenceNumber = (MP_UINT64)inst_num; + luOID.objectType = MP_OBJECT_TYPE_MULTIPATH_LU; + luOID.ownerId = g_pluginOwnerID; + + mpStatus = getAssociatedTPGOidList(luOID, &ppList); + if (MP_STATUS_SUCCESS != mpStatus) { + + log(LOG_INFO, "checkTPGList()", + " - getAssociatedTPGOidList() failed: %d", + mpStatus); + + return (MP_FALSE); + } + + for (tpg = 0; tpg < ppList->oidCount; tpg++) { + + mpStatus = + getTargetPortGroupProperties(ppList->oids[tpg], + &tpgProps); + + if (MP_STATUS_SUCCESS != mpStatus) { + + log(LOG_INFO, "checkTPGList()", + " - getTargetPortGroupProperties()" + " failed: %d", + mpStatus); + + return (MP_FALSE); + } + + if (tpgProps.tpgID == tpgID) { + + status = MP_TRUE; + + log(LOG_INFO, + "checkTPGList()", + " - found a match"); + + break; + } + } + + free(ppList); + + + log(LOG_INFO, "checkTPGList()", " - exit"); + + return (status); +} + + + +/* + * Returns the number of matches found. If pOidList is not NULL, then + * populate it. A return values of -1 indicates and error, zerom menas + * no match is found. + */ + +static int getOidList(di_node_t root_node, int tpgID, + MP_OID_LIST *tpList, MP_OID_LIST *pOidList) +{ + di_node_t sv_node = DI_NODE_NIL; + di_node_t child_node = DI_NODE_NIL; + di_path_t path = DI_PATH_NIL; + + int numNodes = 0; + int tp = 0; + int ioctlStatus = 0; + int match = 0; + int status = -1; + int sv_child_inst = 0; + int hasTpgMatch = MP_FALSE; + + struct stat buffer; + + char *pathName = NULL; + char *minorName = "c"; + + char fullName[512]; + + char *portName = NULL; + + mp_iocdata_t mp_ioctl; + + mp_target_port_prop_t tpInfo; + + MP_UINT64 tpOSN = 0; + + int haveList = (NULL != pOidList); + + + log(LOG_INFO, "getOidList()", " - enter"); + + + /* Look through the list of target ports for a portName that matches */ + for (tp = 0; tp < tpList->oidCount; tp++) { + + tpOSN = tpList->oids[tp].objectSequenceNumber; + + log(LOG_INFO, "getOidList()", + "tpOSN = %llx", + tpOSN); + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&tpInfo, 0, sizeof (mp_target_port_prop_t)); + + mp_ioctl.mp_cmd = MP_GET_TARGET_PORT_PROP; + mp_ioctl.mp_ibuf = (caddr_t)&tpOSN; + mp_ioctl.mp_ilen = sizeof (tpOSN); + mp_ioctl.mp_obuf = (caddr_t)&tpInfo; + mp_ioctl.mp_olen = sizeof (mp_target_port_prop_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, "getOidList()", + "mp_ioctl.mp_cmd (MP_GET_TARGET_PORT_PROP) : %d", + mp_ioctl.mp_cmd); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "getOidList()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "getOidList()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "getOidList()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "getOidList()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + log(LOG_INFO, "getOidList()", + " - error exit"); + + return (-1); + } + + sv_node = di_drv_first_node("scsi_vhci", root_node); + if (DI_NODE_NIL == sv_node) { + log(LOG_INFO, "getOidList()", + " - di_drv_first_node() failed"); + + return (-1); + } + + child_node = di_child_node(sv_node); + + while (DI_NODE_NIL != child_node) { + + path = di_path_next(child_node, path); + + match = 0; + + while (DI_PATH_NIL != path) { + + + (void) di_path_prop_lookup_strings(path, + "target-port", + &portName); + + if (NULL != portName) { + + if (0 == strncmp(portName, + tpInfo.portName, + strlen(tpInfo.portName))) { + + match = 1; + + break; + } + } + + path = di_path_next(child_node, path); + } + + if (match) { + + log(LOG_INFO, "getOidList()", + " - got a match"); + + pathName = di_devfs_path(child_node); + + (void) snprintf(fullName, 511, "/devices%s:%s", + pathName, minorName); + + di_devfs_path_free(pathName); + + status = stat(fullName, &buffer); + if (status < 0) { + + log(LOG_INFO, + "getOidList()", + " - stat() call failed: %d", + status); + + log(LOG_INFO, + "getOidList()", + " - errno: [%d].", errno); + + log(LOG_INFO, + "getOidList()", + " - strerror(errno): [%s].", + strerror(errno)); + + log(LOG_INFO, + "getOidList()", + " - error exit."); + + return (-1); + } + + sv_child_inst = di_instance(child_node); + + /* + * OK, found an portName that matches, let's + * to see if the IDs match. + */ + hasTpgMatch = + checkTPGList(tpgID, + sv_child_inst); + + if (MP_TRUE != hasTpgMatch) { + + child_node = + di_sibling_node(child_node); + + continue; + } + + if (haveList && + (numNodes < pOidList->oidCount)) { + + pOidList->oids[numNodes]. + objectSequenceNumber = + sv_child_inst; + + pOidList->oids[numNodes].objectType = + MP_OBJECT_TYPE_MULTIPATH_LU; + + pOidList->oids[numNodes].ownerId = + g_pluginOwnerID; + } + + ++numNodes; + } + + child_node = di_sibling_node(child_node); + } + } + + log(LOG_INFO, + "getOidList()", + " - numNodes: %d", + numNodes); + + + log(LOG_INFO, "getOidList()", " - exit"); + + return (numNodes); +} + + + +/* + * Called by the common layer to request a list of multipath logical units + * associated with a given target port group. + */ + +MP_STATUS +MP_GetMPLuOidListFromTPG(MP_OID oid, MP_OID_LIST **ppList) +{ + + di_node_t root_node = DI_NODE_NIL; + + int i = 0; + int numNodes = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + MP_UINT32 sourceTpgID = 0; + + MP_OID_LIST *pOidList = NULL; + MP_OID_LIST *tpList = NULL; + + MP_TARGET_PORT_GROUP_PROPERTIES sourceTpgProps; + + + + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", " - enter"); + + + + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + mpStatus = getTargetPortGroupProperties(oid, &sourceTpgProps); + if (MP_STATUS_SUCCESS != mpStatus) { + + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", + " - getTargetPortGroupProperties() failed: %d", + mpStatus); + + return (mpStatus); + } + + /* The TPG ID we will use as a serch key */ + sourceTpgID = sourceTpgProps.tpgID; + + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", + "sourceTpgID = %d", + sourceTpgID); + + /* Get a list of target ports for the TPG */ + mpStatus = getTargetPortOidList(oid, &tpList); + if (MP_STATUS_SUCCESS != mpStatus) { + + log(LOG_INFO, "getOidList()", + " - getTargetPortOidList() failed: %d", + mpStatus); + + return (mpStatus); + } + + /* Take a snapshot */ + root_node = di_init("/", DINFOCACHE); + if (DI_NODE_NIL == root_node) { + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", + " - di_init() failed"); + + free(tpList); + + return (MP_STATUS_FAILED); + } + + /* search for the number of multipath logical units that match */ + numNodes = getOidList(root_node, sourceTpgID, tpList, NULL); + + if (numNodes < 0) { + + log(LOG_INFO, + "MP_GetMPLuOidListFromTPG()", + " - unable to get OID list."); + + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", + " - error exit"); + + free(tpList); + + di_fini(root_node); + + return (MP_STATUS_FAILED); + } + + if (0 == numNodes) { + + pOidList = createOidList(1); + if (NULL == pOidList) { + + log(LOG_INFO, + "MP_GetMPLuOidListFromTPG()", + " - unable to create OID list."); + + free(tpList); + + di_fini(root_node); + + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + pOidList->oids[0].objectType = + MP_OBJECT_TYPE_MULTIPATH_LU; + + pOidList->oids[0].ownerId = + g_pluginOwnerID; + + *ppList = pOidList; + + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", + " - returning empty list."); + + free(tpList); + + return (MP_STATUS_SUCCESS); + } + + *ppList = createOidList(numNodes); + if (NULL == *ppList) { + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", + "no memory for *ppList"); + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", + " - error exit"); + + free(tpList); + + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + /* now populate the list */ + + (*ppList)->oidCount = numNodes; + + numNodes = getOidList(root_node, sourceTpgID, tpList, *ppList); + + for (i = 0; i < (*ppList)->oidCount; i++) { + + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", + "(*ppList)->oids[%d].objectType = %d", + i, (*ppList)->oids[i].objectType); + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", + "(*ppList)->oids[%d].ownerId = %d", + i, (*ppList)->oids[i].ownerId); + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", + "(*ppList)->oids[%d].objectSequenceNumber = %llx", + i, (*ppList)->oids[i].objectSequenceNumber); + } + + free(tpList); + + di_fini(root_node); + + + log(LOG_INFO, "MP_GetMPLuOidListFromTPG()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMultipathLusDevProd.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMultipathLusDevProd.c new file mode 100644 index 0000000000..a7da4c2e07 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMultipathLusDevProd.c @@ -0,0 +1,320 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <string.h> +#include <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> +#include <libdevinfo.h> + +#include "mp_utils.h" + + +static int getOidList(di_node_t root_node, + MP_OID_LIST *pOidList, + char *pProductID, + char *pVendorID) +{ + int numNodes = 0; + int pidSize = 0; + int vidSize = 0; + + int haveList = (NULL != pOidList); + + char *pid = NULL; + char *vid = NULL; + + di_node_t sv_node = DI_NODE_NIL; + di_node_t sv_child_node = DI_NODE_NIL; + + MP_UINT64 nodeInstance = 0; + + + log(LOG_INFO, "getOidList()", " - enter"); + + + sv_node = di_drv_first_node("scsi_vhci", root_node); + if (DI_NODE_NIL == sv_node) { + log(LOG_INFO, "getOidList()", + " - di_drv_first_node() failed"); + + return (-1); + } + + + sv_child_node = di_child_node(sv_node); + + while (DI_NODE_NIL != sv_child_node) { + + (void) di_prop_lookup_strings(DDI_DEV_T_ANY, + sv_child_node, + "inquiry-product-id", + &pid); + + pidSize = strlen(pid); + + (void) di_prop_lookup_strings(DDI_DEV_T_ANY, + sv_child_node, + "inquiry-vendor-id", + &vid); + + vidSize = strlen(vid); + + if ((0 == strncmp(pProductID, pid, pidSize)) && + (0 == strncmp(pVendorID, vid, vidSize))) { + + if (haveList) { + + nodeInstance = + (MP_UINT64) + di_instance(sv_child_node); + + if (numNodes < pOidList->oidCount) { + + pOidList->oids[numNodes]. + objectType = + MP_OBJECT_TYPE_MULTIPATH_LU; + + pOidList->oids[numNodes]. + ownerId = + g_pluginOwnerID; + + pOidList->oids[numNodes]. + objectSequenceNumber = + nodeInstance; + } + } + + ++numNodes; + } + + sv_child_node = di_sibling_node(sv_child_node); + } + + + log(LOG_INFO, + "getOidList()", + " - numNodes: %d", + numNodes); + + + log(LOG_INFO, "getOidList()", " - exit"); + + return (numNodes); +} + + +MP_STATUS +MP_GetMultipathLusDevProd(MP_OID oid, MP_OID_LIST **ppList) +{ + di_node_t root_node = DI_NODE_NIL; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + int numNodes = 0; + int ioctlStatus = 0; + int i = 0; + + mp_iocdata_t mp_ioctl; + mp_dev_prod_prop_t devProdInfo; + + char inqProductID[256]; + char inqVendorID[256]; + + + + log(LOG_INFO, "MP_GetMultipathLusDevProd()", " - enter"); + + + + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + "invalid driver file handle"); + log(LOG_INFO, "MP_GetMultipathLusDevProd", + " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&devProdInfo, 0, sizeof (mp_dev_prod_prop_t)); + + mp_ioctl.mp_cmd = MP_GET_DEV_PROD_PROP; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)&devProdInfo; + mp_ioctl.mp_olen = sizeof (mp_dev_prod_prop_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + " - error exit"); + + return (mpStatus); + } + + (void) strncpy(inqProductID, + devProdInfo.prodInfo.product, + sizeof (devProdInfo.prodInfo.product)); + + (void) strncpy(inqVendorID, + devProdInfo.prodInfo.vendor, + sizeof (devProdInfo.prodInfo.vendor)); + + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + " - inqProductID: [%s]", inqProductID); + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + " - inqVendorID: [%s]", inqVendorID); + + + root_node = di_init("/", DINFOCACHE); + if (DI_NODE_NIL == root_node) { + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + " - di_init() failed"); + + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + " - error exit"); + + return (MP_STATUS_FAILED); + } + + numNodes = getOidList(root_node, + NULL, + inqProductID, + inqVendorID); + + if (numNodes < 0) { + + log(LOG_INFO, + "MP_GetMultipathLusDevProd()", + " - unable to get OID list."); + + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + " - error exit"); + + di_fini(root_node); + + return (MP_STATUS_FAILED); + } + + + if (0 == numNodes) { + + *ppList = createOidList(1); + if (NULL == *ppList) { + + log(LOG_INFO, + "MP_GetMultipathLusDevProd()", + " - unable to create OID list."); + + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + " - error exit"); + + di_fini(root_node); + + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (*ppList)->oids[0].objectType = + MP_OBJECT_TYPE_MULTIPATH_LU; + + (*ppList)->oids[0].ownerId = + g_pluginOwnerID; + + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + " - returning empty list."); + + return (MP_STATUS_SUCCESS); + } + + *ppList = createOidList(numNodes); + if (NULL == *ppList) { + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + "no memory for *ppList"); + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (*ppList)->oidCount = numNodes; + + numNodes = getOidList(root_node, + *ppList, + inqProductID, + inqVendorID); + + + for (i = 0; i < (*ppList)->oidCount; i++) { + + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + "(*ppList)->oids[%d].objectType = %d", + i, (*ppList)->oids[i].objectType); + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + "(*ppList)->oids[%d].ownerId = %d", + i, (*ppList)->oids[i].ownerId); + log(LOG_INFO, "MP_GetMultipathLusDevProd()", + "(*ppList)->oids[%d].objectSequenceNumber = %llx", + i, (*ppList)->oids[i].objectSequenceNumber); + } + + + di_fini(root_node); + + log(LOG_INFO, "MP_GetMultipathLusDevProd()", " - exit"); + + return (MP_STATUS_SUCCESS); + +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMultipathLusPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMultipathLusPlugin.c new file mode 100644 index 0000000000..91670ad4f0 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMultipathLusPlugin.c @@ -0,0 +1,198 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" + +#include <libdevinfo.h> + +static int getOidList(di_node_t root_node, MP_OID_LIST *pOidList) +{ + int numNodes = 0; + + MP_UINT64 instNum = 0; + + di_node_t sv_node = DI_NODE_NIL; + di_node_t sv_child_node = DI_NODE_NIL; + + int haveList = (NULL != pOidList); + + + log(LOG_INFO, "getOidList()", " - enter"); + + + sv_node = di_drv_first_node("scsi_vhci", root_node); + if (DI_NODE_NIL == sv_node) { + log(LOG_INFO, "getOidList()", + " - di_drv_first_node() failed"); + + return (-1); + } + + sv_child_node = di_child_node(sv_node); + + while (DI_NODE_NIL != sv_child_node) { + + if (haveList && (numNodes < pOidList->oidCount)) { + + instNum = + (MP_UINT64)di_instance(sv_child_node); + + log(LOG_INFO, "getOidList()", + " - instance number is: %llx", + instNum); + + pOidList->oids[numNodes].objectType = + MP_OBJECT_TYPE_MULTIPATH_LU; + + pOidList->oids[numNodes].ownerId = + g_pluginOwnerID; + + pOidList->oids[numNodes].objectSequenceNumber = + instNum; + } + + ++numNodes; + + sv_child_node = di_sibling_node(sv_child_node); + } + + log(LOG_INFO, + "getOidList()", + " - numNodes: %d", + numNodes); + + + + log(LOG_INFO, "getOidList()", " - exit"); + + return (numNodes); +} + + +MP_STATUS +MP_GetMultipathLusPlugin(MP_OID_LIST **ppList) +{ + di_node_t root_node = DI_NODE_NIL; + MP_OID_LIST *pOidList = NULL; + + int numNodes = 0; + int i = 0; + + log(LOG_INFO, "MP_GetMultipathLusPlugin()", " - enter"); + + + root_node = di_init("/", DINFOCACHE); + if (DI_NODE_NIL == root_node) { + log(LOG_INFO, "MP_GetMultipathLusPlugin()", + " - di_init() failed"); + + return (MP_STATUS_FAILED); + } + + numNodes = getOidList(root_node, NULL); + + if (numNodes < 0) { + + log(LOG_INFO, + "MP_GetMultipathLusPlugin()", + " - unable to get OID list."); + + log(LOG_INFO, "MP_GetMultipathLusPlugin()", + " - error exit"); + + di_fini(root_node); + + return (MP_STATUS_FAILED); + } + + if (0 == numNodes) { + + pOidList = createOidList(1); + if (NULL == pOidList) { + + log(LOG_INFO, + "MP_GetMultipathLusPlugin()", + " - unable to create OID list."); + + di_fini(root_node); + + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + pOidList->oids[0].objectType = + MP_OBJECT_TYPE_MULTIPATH_LU; + + pOidList->oids[0].ownerId = + g_pluginOwnerID; + + *ppList = pOidList; + + log(LOG_INFO, "MP_GetMultipathLusPlugin()", + " - returning empty list."); + + di_fini(root_node); + + return (MP_STATUS_SUCCESS); + } + + *ppList = createOidList(numNodes); + if (NULL == *ppList) { + log(LOG_INFO, "MP_GetMultipathLusPlugin()", + "no memory for *ppList"); + log(LOG_INFO, "MP_GetMultipathLusPlugin()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (*ppList)->oidCount = numNodes; + + numNodes = getOidList(root_node, *ppList); + + for (i = 0; i < (*ppList)->oidCount; i++) { + + log(LOG_INFO, "MP_GetMultipathLusPlugin()", + "(*ppList)->oids[%d].objectType = %d", + i, (*ppList)->oids[i].objectType); + log(LOG_INFO, "MP_GetMultipathLusPlugin()", + "(*ppList)->oids[%d].ownerId = %d", + i, (*ppList)->oids[i].ownerId); + log(LOG_INFO, "MP_GetMultipathLusPlugin()", + "(*ppList)->oids[%d].objectSequenceNumber = %llx", + i, (*ppList)->oids[i].objectSequenceNumber); + } + + + di_fini(root_node); + + log(LOG_INFO, "MP_GetMultipathLusPlugin()", " - exit"); + + return (MP_STATUS_SUCCESS); + +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetPathLogicalUnitProperties.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetPathLogicalUnitProperties.c new file mode 100644 index 0000000000..40f3caa2e6 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetPathLogicalUnitProperties.c @@ -0,0 +1,174 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <string.h> +#include <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_GetPathLogicalUnitProperties(MP_OID oid, + MP_PATH_LOGICAL_UNIT_PROPERTIES *pProps) +{ + mp_iocdata_t mp_ioctl; + mp_path_prop_t pathInfo; + + int ioctlStatus = 0; + + MP_OID initPortOID; + MP_OID targetPortOID; + MP_OID luOID; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + + log(LOG_INFO, "MP_GetPathLogicalUnitProperties()", " - enter"); + + + log(LOG_INFO, "MP_GetPathLogicalUnitProperties()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_GetPathLogicalUnitProperties()", + "invalid driver file handle"); + log(LOG_INFO, "MP_GetPathLogicalUnitProperties()", + " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&pathInfo, 0, sizeof (mp_path_prop_t)); + + mp_ioctl.mp_cmd = MP_GET_PATH_PROP; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)&pathInfo; + mp_ioctl.mp_olen = sizeof (mp_path_prop_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_GetPathLogicalUnitProperties()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_GetPathLogicalUnitProperties()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetPathLogicalUnitProperties()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetPathLogicalUnitProperties()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetPathLogicalUnitProperties()", + " - error exit"); + + return (mpStatus); + } + + (void) memset(pProps, 0, sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES)); + + pProps->disabled = pathInfo.disabled; + + initPortOID.objectSequenceNumber = pathInfo.initPort.id; + initPortOID.objectType = MP_OBJECT_TYPE_INITIATOR_PORT; + initPortOID.ownerId = g_pluginOwnerID; + + (void) memcpy(&pProps->initiatorPortOid, &initPortOID, sizeof (MP_OID)); + + targetPortOID.objectSequenceNumber = pathInfo.targetPort.id; + targetPortOID.objectType = MP_OBJECT_TYPE_TARGET_PORT; + targetPortOID.ownerId = g_pluginOwnerID; + + (void) memcpy(&pProps->targetPortOid, &targetPortOID, sizeof (MP_OID)); + + luOID.objectSequenceNumber = pathInfo.logicalUnit.id; + luOID.objectType = MP_OBJECT_TYPE_MULTIPATH_LU; + luOID.ownerId = g_pluginOwnerID; + + (void) memcpy(&pProps->logicalUnitOid, &luOID, sizeof (MP_OID)); + + pProps->logicalUnitNumber = pathInfo.logicalUnit.id; + + switch (pathInfo.pathState) { + + case MP_DRVR_PATH_STATE_ACTIVE: + case MP_DRVR_PATH_STATE_PASSIVE: + pProps->pathState = MP_PATH_STATE_OKAY; + break; + + case MP_DRVR_PATH_STATE_PATH_ERR: + pProps->pathState = MP_PATH_STATE_PATH_ERR; + break; + + case MP_DRVR_PATH_STATE_LU_ERR: + pProps->pathState = MP_PATH_STATE_LU_ERR; + break; + + case MP_DRVR_PATH_STATE_RESERVED: + pProps->pathState = MP_PATH_STATE_RESERVED; + break; + + case MP_DRVR_PATH_STATE_REMOVED: + pProps->pathState = MP_PATH_STATE_REMOVED; + break; + + case MP_DRVR_PATH_STATE_TRANSITIONING: + pProps->pathState = MP_PATH_STATE_TRANSITIONING; + break; + + default: + pProps->pathState = MP_PATH_STATE_UNKNOWN; + + } + + pProps->weight = pathInfo.weight; + + + log(LOG_INFO, "MP_GetPathLogicalUnitProperties()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetPluginPropertiesPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetPluginPropertiesPlugin.c new file mode 100644 index 0000000000..28addebcbe --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetPluginPropertiesPlugin.c @@ -0,0 +1,147 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 "mp_utils.h" + +#include <string.h> +#include <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + + + +MP_STATUS +MP_GetPluginPropertiesPlugin(MP_PLUGIN_PROPERTIES *pProps) +{ + mp_iocdata_t mp_ioctl; + mp_driver_prop_t driverInfo; + + int ioctlStatus = 0; + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + log(LOG_INFO, "MP_GetPluginPropertiesPlugin()", " - enter"); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_GetPluginPropertiesPlugin()", + "invalid driver file handle"); + return (MP_STATUS_FAILED); + } + + (void) memset(pProps, 0, sizeof (MP_PLUGIN_PROPERTIES)); + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&driverInfo, 0, sizeof (mp_driver_prop_t)); + + mp_ioctl.mp_cmd = MP_GET_DRIVER_PROP; + mp_ioctl.mp_obuf = (caddr_t)&driverInfo; + mp_ioctl.mp_olen = sizeof (mp_driver_prop_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_GetPluginPropertiesPlugin()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_GetPluginPropertiesPlugin()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetPluginPropertiesPlugin()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetPluginPropertiesPlugin()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetPluginPropertiesPlugin()", + " - error exit"); + + return (mpStatus); + } + + (void) wcsncpy(pProps->vendor, L"Sun Microsystems", 255); + + pProps->autoFailbackSupport = driverInfo.autoFailbackSupport; + pProps->autoProbingSupport = driverInfo.autoProbingSupport; + +#ifdef BUILD_TIME + (void) mbstowcs(pProps->buildTime, BUILD_TIME, 256); +#endif + + pProps->canOverridePaths = driverInfo.canOverridePaths; + pProps->canSetTPGAccess = driverInfo.canSetTPGAccess; + pProps->currentFailbackPollingRate = + driverInfo.currentFailbackPollingRate; + pProps->currentProbingPollingRate = + driverInfo.currentProbingPollingRate; + pProps->defaultloadBalanceType = + driverInfo.defaultLoadBalanceType; + + (void) strncpy(pProps->deviceFileNamespace, + driverInfo.deviceFileNamespace, 255); + + (void) strncpy(pProps->driverName, "scsi_vhci", 255); + + (void) wcsncpy(pProps->driverVendor, L"Sun Microsystems", 255); + + (void) mbstowcs(pProps->driverVersion, driverInfo.driverVersion, 256); + + pProps->exposesPathDeviceFiles = driverInfo.exposesPathDeviceFiles; + pProps->failbackPollingRateMax = driverInfo.failbackPollingRateMax; + + (void) strncpy(pProps->fileName, "libmpscsi_vhci.so", 255); + + (void) wcsncpy(pProps->implementationVersion, L"1.0.0.0", 255); + + pProps->maximumWeight = driverInfo.maximumWeight; + pProps->onlySupportsSpecifiedProducts = + driverInfo.onlySupportsSpecifiedProducts; + + pProps->pluginAutoFailbackEnabled = driverInfo.autoFailbackEnabled; + pProps->pluginAutoProbingEnabled = driverInfo.autoProbingEnabled; + + pProps->probingPollingRateMax = driverInfo.probingPollingRateMax; + + pProps->supportedLoadBalanceTypes = + driverInfo.supportedLoadBalanceTypes; + pProps->supportedMpVersion = MP_LIBVERSION; + + + log(LOG_INFO, "MP_GetPluginPropertiesPlugin()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetProprietaryLBOidListPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetProprietaryLBOidListPlugin.c new file mode 100644 index 0000000000..c06be96768 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetProprietaryLBOidListPlugin.c @@ -0,0 +1,287 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_GetProprietaryLoadBalanceOidListPlugin(MP_OID_LIST **ppList) +{ + mp_iocdata_t mp_ioctl; + + uint64_t *objList = NULL; + + int numOBJ = 0; + int i = 0; + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + " - enter"); + + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "invalid driver file handle"); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + " - error exit"); + return (MP_STATUS_FAILED); + } + + objList = (uint64_t *)calloc(1, DEFAULT_BUFFER_SIZE_LOADBALANCE); + if (NULL == objList) { + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "no memory for objList(1)"); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = MP_GET_PROPRIETARY_LOADBALANCE_LIST; + mp_ioctl.mp_obuf = (caddr_t)objList; + mp_ioctl.mp_olen = DEFAULT_BUFFER_SIZE_LOADBALANCE; + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "mp_ioctl.mp_cmd : %d", mp_ioctl.mp_cmd); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "mp_ioctl.mp_obuf: %x", mp_ioctl.mp_obuf); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "mp_ioctl.mp_olen: %d", mp_ioctl.mp_olen); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "mp_ioctl.mp_xfer: %d (MP_XFER_READ)", + mp_ioctl.mp_xfer); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + log(LOG_INFO, "MP_GetInitiatorPortOidListPlugin()", + "ioctl call returned ioctlStatus: %d", + ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if ((ioctlStatus != 0) && (MP_MORE_DATA != mp_ioctl.mp_errno)) { + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + + free(objList); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + " - error exit"); + + return (mpStatus); + } + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + " - mp_ioctl.mp_alen : %d", + mp_ioctl.mp_alen); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + " - sizeof (uint64_t): %d", + sizeof (uint64_t)); + + numOBJ = mp_ioctl.mp_alen / sizeof (uint64_t); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "Length of list: %d", numOBJ); + + if (numOBJ < 1) { + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "driver returned empty list."); + + free(objList); + + *ppList = createOidList(1); + if (NULL == *ppList) { + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + "no memory for MP_OID_LIST"); + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + return (MP_STATUS_SUCCESS); + } + + if (mp_ioctl.mp_alen > DEFAULT_BUFFER_SIZE_LOADBALANCE) { + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "buffer size too small, need : %d", + mp_ioctl.mp_alen); + + free(objList); + + objList = (uint64_t *)calloc(1, numOBJ * sizeof (uint64_t)); + if (NULL == objList) { + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + "no memory for objList(2)"); + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = MP_GET_PROPRIETARY_LOADBALANCE_LIST; + mp_ioctl.mp_obuf = (caddr_t)objList; + mp_ioctl.mp_olen = numOBJ * sizeof (uint64_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + "mp_ioctl.mp_cmd : %d", mp_ioctl.mp_cmd); + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + "mp_ioctl.mp_obuf: %x", mp_ioctl.mp_obuf); + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + "mp_ioctl.mp_olen: %d", mp_ioctl.mp_olen); + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + "mp_ioctl.mp_xfer: %d (MP_XFER_READ)", + mp_ioctl.mp_xfer); + + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "ioctl call returned ioctlStatus: %d", + ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + + free(objList); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = + getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + " - error exit"); + + return (mpStatus); + } + } + + + *ppList = createOidList(numOBJ); + if (NULL == *ppList) { + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + "no memory for *ppList"); + free(objList); + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (*ppList)->oidCount = numOBJ; + + log(LOG_INFO, + "MP_GetProprietaryLoadBalanceOidListPlugin()", + "(*ppList)->oidCount = %d", + (*ppList)->oidCount); + + for (i = 0; i < numOBJ; i++) { + + (*ppList)->oids[i].objectType = + MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE; + (*ppList)->oids[i].ownerId = + g_pluginOwnerID; + (*ppList)->oids[i].objectSequenceNumber = + objList[i]; + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "(*ppList)->oids[%d].objectType = %d", + i, (*ppList)->oids[i].objectType); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "(*ppList)->oids[%d].ownerId = %d", + i, (*ppList)->oids[i].ownerId); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + "(*ppList)->oids[%d].objectSequenceNumber = %llx", + i, (*ppList)->oids[i].objectSequenceNumber); + } + + free(objList); + + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceOidListPlugin()", + " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetProprietaryLBProp.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetProprietaryLBProp.c new file mode 100644 index 0000000000..cf61b19d2a --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetProprietaryLBProp.c @@ -0,0 +1,129 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + + +#include "mp_utils.h" + + +MP_STATUS +MP_GetProprietaryLoadBalanceProperties(MP_OID oid, + MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES *pProps) +{ + mp_iocdata_t mp_ioctl; + mp_proprietary_loadbalance_prop_t lbProps; + + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceProperties()", " - enter"); + + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceProperties()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_GetProprietaryLoadBalanceProperties()", + "invalid driver file handle"); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceProperties", + " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&lbProps, 0, sizeof (mp_proprietary_loadbalance_prop_t)); + + mp_ioctl.mp_cmd = MP_GET_PROPRIETARY_LOADBALANCE_PROP; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)&lbProps; + mp_ioctl.mp_olen = sizeof (mp_proprietary_loadbalance_prop_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceProperties()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_GetProprietaryLoadBalanceProperties()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceProperties()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetProprietaryLoadBalanceProperties()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceProperties()", + " - error exit"); + + return (mpStatus); + } + + (void) memset(pProps, 0, + sizeof (MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES)); + + (void) mbstowcs(pProps->name, lbProps.name, 256); + + /* + * + * Get: + * + * pProps->proprietaryPropertyCount & + * pProps->proprietaryProperties + * + * when they are available + * + */ + + pProps->typeIndex = lbProps.typeIndex; + (void) mbstowcs(pProps->vendorName, lbProps.vendorName, 256); + + + log(LOG_INFO, "MP_GetProprietaryLoadBalanceProperties()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetTargetPortGroupProperties.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetTargetPortGroupProperties.c new file mode 100644 index 0000000000..0e2b510c1f --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetTargetPortGroupProperties.c @@ -0,0 +1,137 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <string.h> +#include <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + + +#include "mp_utils.h" + + + +MP_STATUS +MP_GetTargetPortGroupProperties(MP_OID oid, + MP_TARGET_PORT_GROUP_PROPERTIES *pProps) +{ + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "MP_GetTargetPortGroupProperties()", " - enter"); + + + mpStatus = getTargetPortGroupProperties(oid, pProps); + + + log(LOG_INFO, "MP_GetTargetPortGroupProperties()", " - exit"); + + return (mpStatus); +} + + +MP_STATUS +getTargetPortGroupProperties(MP_OID oid, + MP_TARGET_PORT_GROUP_PROPERTIES *pProps) +{ + mp_iocdata_t mp_ioctl; + mp_tpg_prop_t tpgProps; + + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "getTargetPortGroupProperties()", " - enter"); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "getTargetPortGroupProperties()", + "invalid driver file handle"); + log(LOG_INFO, "getTargetPortGroupProperties", + " - error exit"); + return (MP_STATUS_FAILED); + } + + log(LOG_INFO, "getTargetPortGroupProperties()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + (void) memset(pProps, 0, sizeof (MP_TARGET_PORT_GROUP_PROPERTIES)); + (void) memset(&tpgProps, 0, sizeof (mp_tpg_prop_t)); + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = MP_GET_TPG_PROP; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)&tpgProps; + mp_ioctl.mp_olen = sizeof (mp_tpg_prop_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "getTargetPortGroupProperties()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "getTargetPortGroupProperties()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "getTargetPortGroupProperties()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "getTargetPortGroupProperties()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "getTargetPortGroupProperties()", + " - error exit"); + + return (mpStatus); + } + + pProps->accessState = tpgProps.accessState; + pProps->explicitFailover = tpgProps.explicitFailover; + pProps->preferredLuPath = tpgProps.preferredLuPath; + pProps->supportsLuAssignment = tpgProps.supportsLuAssignment; + pProps->tpgID = tpgProps.tpgId; + + + log(LOG_INFO, "getTargetPortGroupProperties()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetTargetPortOidList.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetTargetPortOidList.c new file mode 100644 index 0000000000..9b823bea18 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetTargetPortOidList.c @@ -0,0 +1,297 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <string.h> +#include <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + + +#include "mp_utils.h" + + +MP_STATUS +MP_GetTargetPortOidList(MP_OID oid, MP_OID_LIST **ppList) +{ + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "MP_GetTargetPortOidList()", " - enter"); + + + mpStatus = getTargetPortOidList(oid, ppList); + + + log(LOG_INFO, "MP_GetTargetPortOidList()", " - exit"); + + return (mpStatus); +} + + + +MP_STATUS +getTargetPortOidList(MP_OID oid, MP_OID_LIST **ppList) +{ + mp_iocdata_t mp_ioctl; + + uint64_t *objList = NULL; + + int numOBJ = 0; + int i = 0; + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + log(LOG_INFO, "getTargetPortOidList()", " - enter"); + + + log(LOG_INFO, "getTargetPortOidList()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "getTargetPortOidList()", + "invalid driver file handle"); + log(LOG_INFO, "getTargetPortOidList()", " - error exit"); + return (MP_STATUS_FAILED); + } + + objList = (uint64_t *)calloc(1, DEFAULT_BUFFER_SIZE_TPG); + if (NULL == objList) { + log(LOG_INFO, "getTargetPortOidList()", + "no memory for objList(1)"); + log(LOG_INFO, "getTargetPortOidList()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = MP_GET_TARGET_PORT_LIST_FOR_TPG; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)objList; + mp_ioctl.mp_olen = DEFAULT_BUFFER_SIZE_TPG; + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, "getTargetPortOidList()", + "mp_ioctl.mp_cmd (MP_GET_TARGET_PORT_LIST_FOR_TPG): %d", + mp_ioctl.mp_cmd); + log(LOG_INFO, "getTargetPortOidList()", + "mp_ioctl.mp_obuf: %x", mp_ioctl.mp_obuf); + log(LOG_INFO, "getTargetPortOidList()", + "mp_ioctl.mp_olen: %d", mp_ioctl.mp_olen); + log(LOG_INFO, "getTargetPortOidList()", + "mp_ioctl.mp_xfer: %d (MP_XFER_READ)", + mp_ioctl.mp_xfer); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + log(LOG_INFO, "getTargetPortOidList()", + "ioctl call returned ioctlStatus: %d", + ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if ((ioctlStatus != 0) && (MP_MORE_DATA != mp_ioctl.mp_errno)) { + + log(LOG_INFO, "getTargetPortOidList()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "getTargetPortOidList()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "getTargetPortOidList()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + + free(objList); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "getTargetPortOidList()", + " - error exit"); + + return (mpStatus); + } + + log(LOG_INFO, "getTargetPortOidList()", + " - mp_ioctl.mp_alen : %d", + mp_ioctl.mp_alen); + log(LOG_INFO, "getTargetPortOidList()", + " - sizeof (uint64_t): %d", + sizeof (uint64_t)); + + numOBJ = mp_ioctl.mp_alen / sizeof (uint64_t); + log(LOG_INFO, "getTargetPortOidList()", + "Length of list: %d", numOBJ); + + if (numOBJ < 1) { + log(LOG_INFO, "getTargetPortOidList()", + "driver returned empty list."); + + free(objList); + + *ppList = createOidList(1); + if (NULL == *ppList) { + log(LOG_INFO, + "getTargetPortOidList()", + "no memory for MP_OID_LIST"); + log(LOG_INFO, + "getTargetPortOidList()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + return (MP_STATUS_SUCCESS); + } + + if (mp_ioctl.mp_alen > DEFAULT_BUFFER_SIZE_TPG) { + + log(LOG_INFO, "getTargetPortOidList()", + "buffer size too small, need : %d", + mp_ioctl.mp_alen); + + free(objList); + + objList = (uint64_t *)calloc(1, numOBJ * sizeof (uint64_t)); + if (NULL == objList) { + log(LOG_INFO, "getTargetPortOidList()", + "no memory for objList(2)"); + log(LOG_INFO, "getTargetPortOidList()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = MP_GET_TARGET_PORT_LIST_FOR_TPG; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)objList; + mp_ioctl.mp_olen = numOBJ * sizeof (uint64_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, "getTargetPortOidList()", + "mp_ioctl.mp_cmd (MP_GET_TARGET_PORT_LIST_FOR_TPG): %d", + mp_ioctl.mp_cmd); + log(LOG_INFO, "getTargetPortOidList()", + "mp_ioctl.mp_obuf: %x", mp_ioctl.mp_obuf); + log(LOG_INFO, "getTargetPortOidList()", + "mp_ioctl.mp_olen: %d", mp_ioctl.mp_olen); + log(LOG_INFO, "getTargetPortOidList()", + "mp_ioctl.mp_xfer: %d (MP_XFER_READ)", + mp_ioctl.mp_xfer); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + log(LOG_INFO, "getTargetPortOidList()", + "ioctl call returned ioctlStatus: %d", + ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + + log(LOG_INFO, "getTargetPortOidList()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "getTargetPortOidList()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "getTargetPortOidList()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + + free(objList); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = + getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "getTargetPortOidList()", + " - error exit"); + + return (mpStatus); + } + } + + + *ppList = createOidList(numOBJ); + if (NULL == *ppList) { + log(LOG_INFO, "getTargetPortOidList()", + "no memory for *ppList"); + free(objList); + log(LOG_INFO, "getTargetPortOidList()", + " - error exit"); + return (MP_STATUS_INSUFFICIENT_MEMORY); + } + + (*ppList)->oidCount = numOBJ; + + log(LOG_INFO, "getTargetPortOidList()", + "(*ppList)->oidCount = %d", + (*ppList)->oidCount); + + for (i = 0; i < numOBJ; i++) { + (*ppList)->oids[i].objectType = MP_OBJECT_TYPE_TARGET_PORT; + (*ppList)->oids[i].ownerId = g_pluginOwnerID; + (*ppList)->oids[i].objectSequenceNumber = objList[i]; + + log(LOG_INFO, "getTargetPortOidList()", + "(*ppList)->oids[%d].objectType = %d", + i, (*ppList)->oids[i].objectType); + log(LOG_INFO, "getTargetPortOidList()", + "(*ppList)->oids[%d].ownerId = %d", + i, (*ppList)->oids[i].ownerId); + log(LOG_INFO, "getTargetPortOidList()", + "(*ppList)->oids[%d].objectSequenceNumber = %llx", + i, (*ppList)->oids[i].objectSequenceNumber); + } + + free(objList); + + + log(LOG_INFO, "getTargetPortOidList()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetTargetPortProperties.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetTargetPortProperties.c new file mode 100644 index 0000000000..64422605ff --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetTargetPortProperties.c @@ -0,0 +1,121 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <string.h> +#include <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + +#include "mp_utils.h" + + + +MP_STATUS +MP_GetTargetPortProperties(MP_OID oid, + MP_TARGET_PORT_PROPERTIES *pProps) +{ + mp_iocdata_t mp_ioctl; + mp_target_port_prop_t tpInfo; + + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + + log(LOG_INFO, "MP_GetTargetPortProperties()", " - enter"); + + + log(LOG_INFO, "MP_GetTargetPortProperties()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_GetTargetPortProperties()", + "invalid driver file handle"); + log(LOG_INFO, "MP_GetTargetPortProperties()", " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&tpInfo, 0, sizeof (mp_target_port_prop_t)); + + mp_ioctl.mp_cmd = MP_GET_TARGET_PORT_PROP; + mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber); + mp_ioctl.mp_obuf = (caddr_t)&tpInfo; + mp_ioctl.mp_olen = sizeof (mp_target_port_prop_t); + mp_ioctl.mp_xfer = MP_XFER_READ; + + log(LOG_INFO, "MP_GetTargetPortProperties()", + "mp_ioctl.mp_cmd (MP_GET_TARGET_PORT_PROP) : %d", + mp_ioctl.mp_cmd); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_GetTargetPortProperties()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_GetTargetPortProperties()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_GetTargetPortProperties()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_GetTargetPortProperties()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_GetTargetPortProperties()", + " - error exit"); + + return (mpStatus); + } + + (void) memset(pProps, 0, sizeof (MP_TARGET_PORT_PROPERTIES)); + + (void) strncpy(pProps->portID, tpInfo.portName, + sizeof (pProps->portID)); + pProps->relativePortID = tpInfo.relativePortID; + + + log(LOG_INFO, "MP_GetTargetPortProperties()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_RegForObjPropChangesPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_RegForObjPropChangesPlugin.c new file mode 100644 index 0000000000..2fa2e58e44 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_RegForObjPropChangesPlugin.c @@ -0,0 +1,95 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 "mp_utils.h" + + +/* + * Called by the common layer to request the plugin to call + * a client application's callback (pClientFn) when a property change + * is detected for the given object type. + */ + +MP_STATUS +MP_RegisterForObjectPropertyChangesPlugin(MP_OBJECT_PROPERTY_FN pClientFn, + MP_OBJECT_TYPE objectType, + void *pCallerData) +{ + MP_BOOL hasFunc = MP_FALSE; + + + log(LOG_INFO, "MP_RegisterForObjectPropertyChangesPlugin()", + " - enter"); + + + /* Validate the object type passes in within range */ + if (objectType > MP_OBJECT_TYPE_MAX) { + + log(LOG_INFO, "MP_RegisterForObjectPropertyChangesPlugin()", + " - objectType is invalid"); + + log(LOG_INFO, "MP_RegisterForObjectPropertyChangesPlugin()", + " - error exit"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + if (objectType < 1) { + + log(LOG_INFO, "MP_RegisterForObjectPropertyChangesPlugin()", + " - objectType is invalid"); + + log(LOG_INFO, "MP_RegisterForObjectPropertyChangesPlugin()", + " - error exit"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + /* Check to see if we are going to be replacing */ + (void) pthread_mutex_lock(&g_prop_mutex); + if (g_Property_Callback_List[objectType].pClientFn != NULL) { + + hasFunc = MP_TRUE; + } + + /* Add the registration. */ + g_Property_Callback_List[objectType].pClientFn = pClientFn; + g_Property_Callback_List[objectType].pCallerData = pCallerData; + (void) pthread_mutex_unlock(&g_prop_mutex); + + if (hasFunc) { + + log(LOG_INFO, "MP_RegisterForObjectPropertyChangesPlugin()", + " - returning MP_STATUS_FN_REPLACED"); + + return (MP_STATUS_FN_REPLACED); + } + + + log(LOG_INFO, "MP_RegisterForObjectPropertyChangesPlugin()", + " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_RegForObjVisChangesPlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_RegForObjVisChangesPlugin.c new file mode 100644 index 0000000000..59585d3311 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_RegForObjVisChangesPlugin.c @@ -0,0 +1,94 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 "mp_utils.h" + + +/* + * Called by the common layer to request the plugin to call + * a client application's callback (pClientFn) when a visibility change + * is detected for the given object type. + */ + +MP_STATUS +MP_RegisterForObjectVisibilityChangesPlugin(MP_OBJECT_VISIBILITY_FN pClientFn, + MP_OBJECT_TYPE objectType, + void *pCallerData) +{ + MP_BOOL hasFunc = MP_FALSE; + + + log(LOG_INFO, "MP_RegisterForObjectVisibilityChangesPlugin()", + " - enter"); + + + /* Validate the object type passes in within range */ + if (objectType > MP_OBJECT_TYPE_MAX) { + + log(LOG_INFO, "MP_RegisterForObjectVisibilityChangesPlugin()", + " - objectType is invalid"); + + log(LOG_INFO, "MP_RegisterForObjectVisibilityChangesPlugin()", + " - error exit"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + if (objectType < 1) { + + log(LOG_INFO, "MP_RegisterForObjectVisibilityChangesPlugin()", + " - objectType is invalid"); + + log(LOG_INFO, "MP_RegisterForObjectVisibilityChangesPlugin()", + " - error exit"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + /* Check to see if we are going to be replacing */ + (void) pthread_mutex_lock(&g_visa_mutex); + if (g_Visibility_Callback_List[objectType].pClientFn != NULL) { + + hasFunc = MP_TRUE; + } + + g_Visibility_Callback_List[objectType].pClientFn = pClientFn; + g_Visibility_Callback_List[objectType].pCallerData = pCallerData; + (void) pthread_mutex_unlock(&g_visa_mutex); + + if (hasFunc) { + + log(LOG_INFO, "MP_RegisterForObjectVisibilityChangesPlugin()", + " - returning MP_STATUS_FN_REPLACED"); + + return (MP_STATUS_FN_REPLACED); + } + + + log(LOG_INFO, "MP_RegisterForObjectVisibilityChangesPlugin()", + " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetFailbackPollingRateLu.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetFailbackPollingRateLu.c new file mode 100644 index 0000000000..22c1f21a94 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetFailbackPollingRateLu.c @@ -0,0 +1,49 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_SetFailbackPollingRateLu(MP_OID oid, MP_UINT32 pollingRate) +{ + log(LOG_INFO, "MP_SetFailbackPollingRateLu()", " - enter"); + + + log(LOG_INFO, "MP_SetFailbackPollingRateLu()", + " - oid.objectSequenceNumber: %llx", + oid.objectSequenceNumber); + + log(LOG_INFO, "MP_SetFailbackPollingRateLu()", + " - pollingRate: %d", + pollingRate); + + + log(LOG_INFO, "MP_SetFailbackPollingRateLu()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetFailbackPollingRatePlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetFailbackPollingRatePlugin.c new file mode 100644 index 0000000000..e27a28fb83 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetFailbackPollingRatePlugin.c @@ -0,0 +1,45 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_SetFailbackPollingRatePlugin(MP_UINT32 pollingRate) +{ + log(LOG_INFO, "MP_SetFailbackPollingRatePlugin()", " - enter"); + + + log(LOG_INFO, "MP_SetFailbackPollingRatePlugin()", + " - pollingRate: %d", + pollingRate); + + + log(LOG_INFO, "MP_SetFailbackPollingRatePlugin()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetLogicalUnitLoadBalanceType.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetLogicalUnitLoadBalanceType.c new file mode 100644 index 0000000000..13006dcaee --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetLogicalUnitLoadBalanceType.c @@ -0,0 +1,50 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_SetLogicalUnitLoadBalanceType(MP_OID logicalUnitOid, + MP_LOAD_BALANCE_TYPE loadBalance) +{ + log(LOG_INFO, "MP_SetLogicalUnitLoadBalanceType()", " - enter"); + + + log(LOG_INFO, "MP_SetLogicalUnitLoadBalanceType()", + " - logicalUnitOid.objectSequenceNumber: %llx", + logicalUnitOid.objectSequenceNumber); + + log(LOG_INFO, "MP_SetLogicalUnitLoadBalanceType()", + " - loadBalance: %d", + loadBalance); + + + log(LOG_INFO, "MP_SetLogicalUnitLoadBalanceType()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetOverridePath.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetOverridePath.c new file mode 100644 index 0000000000..0ca5387efc --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetOverridePath.c @@ -0,0 +1,49 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_SetOverridePath(MP_OID logicalUnitOid, MP_OID pathOid) +{ + log(LOG_INFO, "MP_SetOverridePath()", " - enter"); + + + log(LOG_INFO, "MP_SetOverridePath()", + " - logicalUnitOid.objectSequenceNumber: %llx", + logicalUnitOid.objectSequenceNumber); + + log(LOG_INFO, "MP_SetOverridePath()", + " - pathOid.objectSequenceNumber: %llx", + pathOid.objectSequenceNumber); + + + log(LOG_INFO, "MP_SetOverridePath()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetPathWeight.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetPathWeight.c new file mode 100644 index 0000000000..2d22a8085b --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetPathWeight.c @@ -0,0 +1,49 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_SetPathWeight(MP_OID pathOid, MP_UINT32 weight) +{ + log(LOG_INFO, "MP_SetPathWeight()", " - enter"); + + + log(LOG_INFO, "MP_SetPathWeight()", + " - pathOid.objectSequenceNumber: %llx", + pathOid.objectSequenceNumber); + + log(LOG_INFO, "MP_SetPathWeight()", + " - weight: %d", + weight); + + + log(LOG_INFO, "MP_SetPathWeight()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetPluginLBTypePlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetPluginLBTypePlugin.c new file mode 100644 index 0000000000..846d94113a --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetPluginLBTypePlugin.c @@ -0,0 +1,45 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_SetPluginLoadBalanceTypePlugin(MP_LOAD_BALANCE_TYPE loadBalance) +{ + log(LOG_INFO, "MP_SetPluginLoadBalanceTypePlugin()", " - enter"); + + + log(LOG_INFO, "MP_SetPluginLoadBalanceTypePlugin()", + " - loadBalance: %d", + loadBalance); + + + log(LOG_INFO, "MP_SetPluginLoadBalanceTypePlugin()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetProbingPollingRateLu.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetProbingPollingRateLu.c new file mode 100644 index 0000000000..5688005b5f --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetProbingPollingRateLu.c @@ -0,0 +1,49 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_SetProbingPollingRateLu(MP_OID oid, MP_UINT32 pollingRate) +{ + log(LOG_INFO, "MP_SetProbingPollingRateLu()", " - enter"); + + + log(LOG_INFO, "MP_SetProbingPollingRateLu()", + " - oid.objectSequenceNumber: %llx", + oid.objectSequenceNumber); + + log(LOG_INFO, "MP_SetProbingPollingRateLu()", + " - pollingRate: %d", + pollingRate); + + + log(LOG_INFO, "MP_SetProbingPollingRateLu()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetProbingPollingRatePlugin.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetProbingPollingRatePlugin.c new file mode 100644 index 0000000000..a2fba5c93d --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetProbingPollingRatePlugin.c @@ -0,0 +1,45 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_SetProbingPollingRatePlugin(MP_UINT32 pollingRate) +{ + log(LOG_INFO, "MP_SetProbingPollingRatePlugin()", " - enter"); + + + log(LOG_INFO, "MP_SetProbingPollingRatePlugin()", + " - pollingRate: %d", + pollingRate); + + + log(LOG_INFO, "MP_SetProbingPollingRatePlugin()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetProprietaryProperties.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetProprietaryProperties.c new file mode 100644 index 0000000000..9ff74ad24c --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetProprietaryProperties.c @@ -0,0 +1,54 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> + +#include "mp_utils.h" + + +MP_STATUS +MP_SetProprietaryProperties(MP_OID oid, MP_UINT32 count, + MP_PROPRIETARY_PROPERTY *pPropertyList) +{ + log(LOG_INFO, "MP_SetProprietaryProperties()", " - enter"); + + + log(LOG_INFO, "MP_SetProprietaryProperties()", + " - oid.objectSequenceNumber: %llx", + oid.objectSequenceNumber); + + log(LOG_INFO, "MP_SetProprietaryProperties()", + " - count: %d", + count); + + log(LOG_INFO, "MP_SetProprietaryProperties()", + " - pPropertyList: %llx", + pPropertyList); + + + log(LOG_INFO, "MP_SetProprietaryProperties()", " - exit"); + + return (MP_STATUS_UNSUPPORTED); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetTPGAccess.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetTPGAccess.c new file mode 100644 index 0000000000..1a8cdf9164 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_SetTPGAccess.c @@ -0,0 +1,207 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <string.h> +#include <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> + + +#include "mp_utils.h" + + +/* + * Called by the common layer to request the plugin to set the + * access state for a list of target port groups. + */ + +MP_STATUS +MP_SetTPGAccess(MP_OID oid, MP_UINT32 count, + MP_TPG_STATE_PAIR *pTpgStateList) +{ + + MP_TPG_STATE_PAIR *head = pTpgStateList; + + mp_iocdata_t mp_ioctl; + mp_set_tpg_state_req_t setTpgStateRequest; + + int r = 0; + + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + + + log(LOG_INFO, "MP_SetTPGAccess()", " - enter"); + + + if (NULL == pTpgStateList) { + + log(LOG_INFO, "MP_SetTPGAccess()", + "pTpgStateList is NULL"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "MP_SetTPGAccess()", + "invalid driver file handle"); + log(LOG_INFO, "MP_SetTPGAccess()", " - error exit"); + return (MP_STATUS_FAILED); + } + + + log(LOG_INFO, "MP_SetTPGAccess()", + "oid.ownerId = %d", + oid.ownerId); + + log(LOG_INFO, "MP_SetTPGAccess()", + "oid.objectType = %d", + oid.objectType); + + log(LOG_INFO, "MP_SetTPGAccess()", + "oid.objectSequenceNumber = %llx", + oid.objectSequenceNumber); + + + log(LOG_INFO, "MP_SetTPGAccess()", + "count = %d", + count); + + + for (r = 0; r < count; r++) { + + if (head->tpgOid.ownerId != g_pluginOwnerID) { + + log(LOG_INFO, "MP_SetTPGAccess()", + "pTpgStateList->tpgOid.ownerId is not for" + " this plugin"); + + log(LOG_INFO, "MP_SetTPGAccess()", + "error exit"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + if (head->tpgOid.objectType != + MP_OBJECT_TYPE_TARGET_PORT_GROUP) { + + log(LOG_INFO, "MP_SetTPGAccess()", + "pTpgStateList->tpgOid.objectType is not" + " MP_OBJECT_TYPE_TARGET_PORT_GROUP"); + + log(LOG_INFO, "MP_SetTPGAccess()", + "error exit"); + + return (MP_STATUS_INVALID_PARAMETER); + } + + + head++; + } + + + head = pTpgStateList; + + for (r = 0; r < count; r++) { + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + (void) memset(&setTpgStateRequest, 0, + sizeof (mp_set_tpg_state_req_t)); + + setTpgStateRequest.desiredState + = head->desiredState; + setTpgStateRequest.luTpgPair.luId + = oid.objectSequenceNumber; + setTpgStateRequest.luTpgPair.tpgId + = head->tpgOid.objectSequenceNumber; + + mp_ioctl.mp_cmd = MP_SET_TPG_ACCESS_STATE; + mp_ioctl.mp_ibuf = (caddr_t)&setTpgStateRequest; + mp_ioctl.mp_ilen = sizeof (mp_set_tpg_state_req_t); + mp_ioctl.mp_xfer = MP_XFER_WRITE; + + log(LOG_INFO, "MP_SetTPGAccess()", + "mp_ioctl.mp_cmd (MP_SET_TPG_ACCESS_STATE) : %d", + mp_ioctl.mp_cmd); + + log(LOG_INFO, "MP_SetTPGAccess()", + "setTpgStateRequest.luTpgPair.luId = %llx", + setTpgStateRequest.luTpgPair.luId); + + log(LOG_INFO, "MP_SetTPGAccess()", + "setTpgStateRequest.luTpgPair.tpgId = %llx", + setTpgStateRequest.luTpgPair.tpgId); + + log(LOG_INFO, "MP_SetTPGAccess()", + "setTpgStateRequest.desiredState = %d", + setTpgStateRequest.desiredState); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "MP_SetTPGAccess()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "MP_SetTPGAccess()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "MP_SetTPGAccess()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "MP_SetTPGAccess()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = + getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "MP_SetTPGAccess()", + " - error exit"); + + return (mpStatus); + } + + head++; + } + + + log(LOG_INFO, "MP_SetTPGAccess()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/Sun_MP_SendScsiCmd.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/Sun_MP_SendScsiCmd.c new file mode 100644 index 0000000000..b78705784e --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/Sun_MP_SendScsiCmd.c @@ -0,0 +1,115 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <stropts.h> +#include <sys/scsi/impl/uscsi.h> + +#include "mp_utils.h" + + +/* + * Called by the common layer to request to steer a path + */ + +MP_STATUS +Sun_MP_SendScsiCmd(MP_OID pathOid, struct uscsi_cmd *cmd) +{ + mp_iocdata_t mp_ioctl; + + int ioctlStatus = 0; + + MP_STATUS mpStatus = MP_STATUS_SUCCESS; + + log(LOG_INFO, "Sun_MP_SendScsiCmd()", " - enter"); + + log(LOG_INFO, "Sun_MP_SendScsiCmd()", + "pathOid.objectSequenceNumber = %llx", + pathOid.objectSequenceNumber); + + if (g_scsi_vhci_fd < 0) { + log(LOG_INFO, "Sun_MP_SendScsiCmd()", + "invalid driver file handle"); + log(LOG_INFO, "Sun_MP_SendScsiCmd()", " - error exit"); + return (MP_STATUS_FAILED); + } + + (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t)); + + mp_ioctl.mp_cmd = MP_SEND_SCSI_CMD; + mp_ioctl.mp_ibuf = (caddr_t)&pathOid.objectSequenceNumber; + mp_ioctl.mp_ilen = sizeof (pathOid.objectSequenceNumber); + mp_ioctl.mp_xfer = + ((cmd->uscsi_flags & USCSI_READ) ? MP_XFER_READ : MP_XFER_WRITE); + mp_ioctl.mp_obuf = (char *)cmd; + mp_ioctl.mp_olen = sizeof (*cmd); + + log(LOG_INFO, "Sun_MP_SendScsiCmd()", + "mp_ioctl.mp_cmd (MP_SEND_SCSI_CMD) : %d", + mp_ioctl.mp_cmd); + + ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl); + + log(LOG_INFO, "Sun_MP_SendScsiCmd()", + " IOCTL call returned: %d", ioctlStatus); + + if (ioctlStatus < 0) { + ioctlStatus = errno; + } + + if (ioctlStatus != 0) { + log(LOG_INFO, "Sun_MP_SendScsiCmd()", + "IOCTL call failed. IOCTL error is: %d", + ioctlStatus); + log(LOG_INFO, "Sun_MP_SendScsiCmd()", + "IOCTL call failed. IOCTL error is: %s", + strerror(ioctlStatus)); + log(LOG_INFO, "Sun_MP_SendScsiCmd()", + "IOCTL call failed. mp_ioctl.mp_errno: %x", + mp_ioctl.mp_errno); + + if (ENOTSUP == ioctlStatus) { + mpStatus = MP_STATUS_UNSUPPORTED; + } else if (EPERM == ioctlStatus) { + mpStatus = MP_STATUS_NOT_PERMITTED; + } else if (0 == mp_ioctl.mp_errno) { + mpStatus = MP_STATUS_FAILED; + } else { + mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno); + } + + log(LOG_INFO, "Sun_MP_SendScsiCmd()", + " - error exit"); + + return (mpStatus); + } + + + log(LOG_INFO, "Sun_MP_SendScsiCmd()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/Terminate.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/Terminate.c new file mode 100644 index 0000000000..fc1e72713a --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/Terminate.c @@ -0,0 +1,53 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <syslog.h> +#include <unistd.h> + +#include "mp_utils.h" + + +MP_STATUS +Terminate(void) +{ + log(LOG_INFO, "Terminate()", " - enter"); + + + if (g_scsi_vhci_fd > -1) { + (void) close(g_scsi_vhci_fd); + } + + if (NULL != g_SysEventHandle) { + + sysevent_unbind_handle(g_SysEventHandle); + } + + (void) pthread_mutex_destroy(&g_visa_mutex); + (void) pthread_mutex_destroy(&g_prop_mutex); + + log(LOG_INFO, "Terminate()", " - exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/debug_logging.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/debug_logging.c new file mode 100644 index 0000000000..7f0703ac30 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/debug_logging.c @@ -0,0 +1,67 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 <stdio.h> +#include <sys/varargs.h> +#include <syslog.h> +#include <time.h> +#include <string.h> +#include <errno.h> + +#define MAX_LOG_LEN 2048 + + +void +log(int priority, const char *routine, char *msg, ...) +{ + char header[MAX_LOG_LEN+1]; + char message[MAX_LOG_LEN+1]; + int oldErrno = 0; + va_list ap; + + + oldErrno = errno; + + (void) memset(&header, 0, MAX_LOG_LEN+1); + (void) memset(&message, 0, MAX_LOG_LEN+1); + + (void) va_start(ap, msg); + + (void) snprintf(header, MAX_LOG_LEN, "%s: %s: %s", + "MP-API (SUN) Plugin", + routine, + msg); + + /* LINTED E_SEC_PRINTF_VAR_FMT */ + (void) vsnprintf(message, MAX_LOG_LEN, header, ap); + /* LINTED E_SEC_PRINTF_VAR_FMT */ + (void) syslog(LOG_USER|LOG_DEBUG, message); + + (void) va_end(ap); + + errno = oldErrno; + + oldErrno = priority; +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/mapfile-vers b/usr/src/lib/mpapi/libmpscsi_vhci/common/mapfile-vers new file mode 100644 index 0000000000..07d617465c --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/mapfile-vers @@ -0,0 +1,87 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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. +# + +SUNW_1.1 { + global: + Initialize; + Terminate; + MP_GetPluginPropertiesPlugin; + MP_GetDeviceProductOidListPlugin; + MP_GetDeviceProductProperties; + MP_GetInitiatorPortOidListPlugin; + MP_GetInitiatorPortProperties; + MP_GetMultipathLusPlugin; + MP_GetMultipathLusDevProd; + MP_GetMPLogicalUnitProperties; + MP_GetAssociatedPathOidList; + MP_GetPathLogicalUnitProperties; + MP_GetAssociatedTPGOidList; + MP_GetTargetPortGroupProperties; + MP_GetMPLuOidListFromTPG; + MP_GetProprietaryLoadBalanceOidListPlugin; + MP_GetProprietaryLoadBalanceProperties; + MP_GetTargetPortOidList; + MP_GetTargetPortProperties; + MP_GetTargetPortGroupProperties; + MP_AssignLogicalUnitToTPG; + MP_SetOverridePath; + MP_CancelOverridePath; + MP_EnableAutoFailbackPlugin; + MP_EnableAutoFailbackLu; + MP_DisableAutoFailbackPlugin; + MP_DisableAutoFailbackLu; + MP_EnableAutoProbingPlugin; + MP_EnableAutoProbingLu; + MP_DisableAutoProbingPlugin; + MP_DisableAutoProbingLu; + MP_EnablePath; + MP_DisablePath; + MP_SetLogicalUnitLoadBalanceType; + MP_SetPluginLoadBalanceTypePlugin; + MP_SetPathWeight; + MP_SetFailbackPollingRatePlugin; + MP_SetFailbackPollingRateLu; + MP_SetProbingPollingRatePlugin; + MP_SetProbingPollingRateLu; + MP_SetProprietaryProperties; + MP_SetTPGAccess; + MP_RegisterForObjectPropertyChangesPlugin; + MP_DeregisterForObjectPropertyChangesPlugin; + MP_RegisterForObjectVisibilityChangesPlugin; + MP_DeregisterForObjectVisibilityChangesPlugin; + Sun_MP_SendScsiCmd; + local: + *; +}; + +SUNWprivate_1.1 { + global: + init_sysevents; + log; + getStatus4ErrorCode; + createOidList; + local: + *; +}; diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/mp_utils.c b/usr/src/lib/mpapi/libmpscsi_vhci/common/mp_utils.c new file mode 100644 index 0000000000..37ba6b2d2f --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/mp_utils.c @@ -0,0 +1,675 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 "mp_utils.h" +#include <sys/sunddi.h> + +#ifndef OIDLIST +#define OIDLIST "oid" +#endif + + +/* Remove these 5 when this source can compile with sunddi.h */ +#ifndef EC_DDI +#define EC_DDI "EC_ddi" +#endif + +#ifndef ESC_DDI_INITIATOR_REGISTER +#define ESC_DDI_INITIATOR_REGISTER "ESC_ddi_initiator_register" +#endif + +#ifndef ESC_DDI_INITIATOR_UNREGISTER +#define ESC_DDI_INITIATOR_UNREGISTER "ESC_ddi_initiator_unregister" +#endif + +#ifndef DDI_DRIVER_MAJOR +#define DDI_DRIVER_MAJOR "ddi.major" +#endif + +#ifndef DDI_INSTANCE +#define DDI_INSTANCE "ddi.instance" +#endif + + +#define VISA_CHANGE 1 +#define PROP_CHANGE 2 + + + +MP_STATUS +getStatus4ErrorCode(int driverError) +{ + MP_STATUS mpStatus = MP_STATUS_FAILED; + + log(LOG_INFO, "getStatus4ErrorCode()", "- enter"); + + switch (driverError) { + + case MP_DRVR_INVALID_ID: + log(LOG_INFO, "getStatus4ErrorCode()", + " received mp_errno=MP_DRVR_INVALID_ID" + " from driver call."); + log(LOG_INFO, "getStatus4ErrorCode()", + " returning MP_STATUS_OBJECT_NOT_FOUND" + " to caller."); + mpStatus = MP_STATUS_OBJECT_NOT_FOUND; + break; + + + case MP_DRVR_ID_OBSOLETE: + log(LOG_INFO, "getStatus4ErrorCode()", + " received mp_errno=MP_DRVR_ID_OBSOLETE" + " from driver call."); + log(LOG_INFO, "getStatus4ErrorCode()", + " returning MP_STATUS_OBJECT_NOT_FOUND" + " to caller."); + mpStatus = MP_STATUS_OBJECT_NOT_FOUND; + break; + + + case MP_DRVR_ACCESS_SYMMETRIC: + log(LOG_INFO, "getStatus4ErrorCode()", + " received mp_errno=MP_DRVR_ACCESS_SYMMETRIC" + " from driver call."); + log(LOG_INFO, "getStatus4ErrorCode()", + " returning MP_STATUS_INVALID_PARAMETER" + " to caller."); + mpStatus = MP_STATUS_INVALID_PARAMETER; + break; + + + case MP_DRVR_PATH_UNAVAILABLE: + log(LOG_INFO, "getStatus4ErrorCode()", + " received mp_errno=MP_DRVR_PATH_UNAVAILABLE" + " from driver call."); + log(LOG_INFO, "getStatus4ErrorCode()", + " returning MP_STATUS_PATH_NONOPERATIONAL" + " to caller."); + mpStatus = MP_STATUS_PATH_NONOPERATIONAL; + break; + + + case MP_DRVR_IDS_NOT_ASSOCIATED: + log(LOG_INFO, "getStatus4ErrorCode()", + " received mp_errno=MP_DRVR_IDS_NOT_ASSOCIATED" + " from driver call."); + log(LOG_INFO, "getStatus4ErrorCode()", + " returning MP_STATUS_INVALID_PARAMETER" + " to caller."); + mpStatus = MP_STATUS_INVALID_PARAMETER; + break; + + + case MP_DRVR_ILLEGAL_ACCESS_STATE_REQUEST: + log(LOG_INFO, "getStatus4ErrorCode()", + " received mp_errno=" + "MP_DRVR_ILLEGAL_ACCESS_STATE_REQUEST" + " from driver call."); + log(LOG_INFO, "getStatus4ErrorCode()", + " returning MP_STATUS_INVALID_PARAMETER" + " to caller."); + mpStatus = MP_STATUS_ACCESS_STATE_INVALID; + break; + + + default: + log(LOG_INFO, "getStatus4ErrorCode()", + " - received (unsupported) mp_errno=%d from" + " driver call.", driverError); + log(LOG_INFO, "getStatus4ErrorCode()", + " - returning MP_STATUS_FAILED to caller."); + mpStatus = MP_STATUS_FAILED; + } + + log(LOG_INFO, "getStatus4ErrorCode()", "- exit"); + + return (mpStatus); +} + + + +MP_OID_LIST +*createOidList(int size) { + + MP_OID_LIST *pOidList = NULL; + + + log(LOG_INFO, "createOidList()", "- enter"); + + + if (size < 1) { + + log(LOG_INFO, "createOidList()", + "requested size is less than 1"); + log(LOG_INFO, "createOidList()", + " - error exit"); + return (NULL); + + } else { + + pOidList = (MP_OID_LIST*)calloc(1, + sizeof (MP_OID_LIST) + + ((size - 1) * + sizeof (MP_OID))); + + if (NULL == pOidList) { + log(LOG_INFO, "createOidList()", + "no memory for pOidList"); + log(LOG_INFO, "createOidList()", + " - error exit"); + return (NULL); + } + + log(LOG_INFO, + "createOidList()", + "- exit(%d)", + size); + + return (pOidList); + } +} + +/* Calls the client callback function, if one is registered */ +static void +notifyClient(sysevent_t *ev) +{ + nvlist_t *attr_list = NULL; + + uint64_t *val = NULL; + int32_t *instance = NULL; + int32_t *major = NULL; + + int valAllocated = 0; + + uint_t nelem = 0; + + int i = 0; + int eventType = 0; + int index = -1; + + void *pCallerData = NULL; + + char subClassName[256]; + + MP_BOOL becomingVisible = MP_FALSE; + + MP_OID_LIST *oidList = NULL; + + + log(LOG_INFO, "notifyClient()", "- enter"); + + + (void) strncpy(subClassName, sysevent_get_subclass_name(ev), 256); + + if (strstr(subClassName, "change")) { + + eventType = PROP_CHANGE; + + log(LOG_INFO, "notifyClient()", "- got a change event"); + log(LOG_INFO, "notifyClient()", ": [%s]", + subClassName); + + if (strncmp(subClassName, ESC_SUN_MP_LU_CHANGE, 255) == 0) { + + index = MP_OBJECT_TYPE_MULTIPATH_LU; + + } else if (strncmp(subClassName, ESC_SUN_MP_PATH_CHANGE, 255) + == 0) { + + index = MP_OBJECT_TYPE_PATH_LU; + + } else if (strncmp(subClassName, ESC_SUN_MP_INIT_PORT_CHANGE, + 255) == 0) { + + index = MP_OBJECT_TYPE_INITIATOR_PORT; + + } else if (strncmp(subClassName, ESC_SUN_MP_TPG_CHANGE, 255) + == 0) { + + index = MP_OBJECT_TYPE_TARGET_PORT_GROUP; + + } else if (strncmp(subClassName, ESC_SUN_MP_TARGET_PORT_CHANGE, + 255) == 0) { + + index = MP_OBJECT_TYPE_TARGET_PORT; + + } else if (strncmp(subClassName, ESC_SUN_MP_DEV_PROD_CHANGE, + 255) == 0) { + + index = MP_OBJECT_TYPE_DEVICE_PRODUCT; + } + + } else if ((strstr(subClassName, "add")) || + (strstr(subClassName, "initiator_register"))) { + + eventType = VISA_CHANGE; + becomingVisible = MP_TRUE; + + log(LOG_INFO, "notifyClient()", "- got a visibility" + " add event"); + log(LOG_INFO, "notifyClient()", ": [%s]", + subClassName); + + if (strncmp(subClassName, ESC_DEVFS_DEVI_ADD, 255) == 0) { + + index = MP_OBJECT_TYPE_MULTIPATH_LU; + + } else if (strncmp(subClassName, ESC_SUN_MP_PATH_ADD, 255) + == 0) { + + index = MP_OBJECT_TYPE_PATH_LU; + + } else if (strncmp(subClassName, ESC_DDI_INITIATOR_REGISTER, + 244) == 0) { + + index = MP_OBJECT_TYPE_INITIATOR_PORT; + + } else if (strncmp(subClassName, ESC_SUN_MP_TPG_ADD, + 255) == 0) { + + index = MP_OBJECT_TYPE_TARGET_PORT_GROUP; + + } else if (strncmp(subClassName, ESC_SUN_MP_TARGET_PORT_ADD, + 255) == 0) { + + index = MP_OBJECT_TYPE_TARGET_PORT; + + } else if (strncmp(subClassName, ESC_SUN_MP_DEV_PROD_ADD, 255) + == 0) { + + index = MP_OBJECT_TYPE_DEVICE_PRODUCT; + } + + + } else if ((strstr(subClassName, "remove")) || + (strstr(subClassName, "initiator_unregister"))) { + + eventType = VISA_CHANGE; + becomingVisible = MP_FALSE; + + log(LOG_INFO, "notifyClient()", "- got a visibility" + " remove event"); + log(LOG_INFO, "notifyClient()", ": [%s]", + subClassName); + + if (strncmp(subClassName, ESC_DEVFS_DEVI_REMOVE, 255) == 0) { + + index = MP_OBJECT_TYPE_MULTIPATH_LU; + + } else if (strncmp(subClassName, ESC_SUN_MP_PATH_REMOVE, 255) + == 0) { + + index = MP_OBJECT_TYPE_PATH_LU; + + } else if (strncmp(subClassName, ESC_DDI_INITIATOR_UNREGISTER, + 255) == 0) { + + index = MP_OBJECT_TYPE_INITIATOR_PORT; + + } else if (strncmp(subClassName, ESC_SUN_MP_TPG_REMOVE, 255) + == 0) { + + index = MP_OBJECT_TYPE_TARGET_PORT_GROUP; + + } else if (strncmp(subClassName, ESC_SUN_MP_TARGET_PORT_REMOVE, + 255) == 0) { + + index = MP_OBJECT_TYPE_TARGET_PORT; + + } else if (strncmp(subClassName, ESC_SUN_MP_DEV_PROD_REMOVE, + 255) == 0) { + + index = MP_OBJECT_TYPE_DEVICE_PRODUCT; + } + + + } else { + log(LOG_INFO, "notifyClient()", "- got an unsupported event"); + return; + } + + if (index < 0) { + + log(LOG_INFO, "notifyClient()", "- index is less than zero"); + return; + } + + if (eventType == VISA_CHANGE) { + + (void) pthread_mutex_lock(&g_visa_mutex); + + if (NULL == g_Visibility_Callback_List[index].pClientFn) { + + log(LOG_INFO, "notifyClient()", + "- no visibility change callback to notify"); + + (void) pthread_mutex_unlock(&g_visa_mutex); + + return; + } + + (void) pthread_mutex_unlock(&g_visa_mutex); + } + + if (eventType == PROP_CHANGE) { + + (void) pthread_mutex_lock(&g_prop_mutex); + + if (NULL == g_Property_Callback_List[index].pClientFn) { + + log(LOG_INFO, "notifyClient()", + "- no property change callback to notify"); + + (void) pthread_mutex_unlock(&g_prop_mutex); + + return; + } + + (void) pthread_mutex_unlock(&g_prop_mutex); + } + + (void) sysevent_get_attr_list(ev, &attr_list); + if (NULL != attr_list) { + + if ((VISA_CHANGE == eventType) && + (MP_OBJECT_TYPE_MULTIPATH_LU == index)) { + + (void) nvlist_lookup_int32_array(attr_list, + DEVFS_INSTANCE, &instance, &nelem); + + log(LOG_INFO, "notifyClient()", + "- event has [%d] elements", + nelem); + + if (NULL != instance) { + + val = (uint64_t *)malloc(sizeof (uint64_t)); + + valAllocated = 1; + + *val = *instance; + nelem = 1; + + } else { + + nelem = 0; + } + + } else if ((VISA_CHANGE == eventType) && + (MP_OBJECT_TYPE_INITIATOR_PORT == index)) { + + (void) nvlist_lookup_int32_array(attr_list, + DDI_INSTANCE, &instance, &nelem); + + log(LOG_INFO, "notifyClient()", + "- event (PHCI_INSTANCE) has [%d] elements", + nelem); + + (void) nvlist_lookup_int32_array(attr_list, + DDI_DRIVER_MAJOR, &major, &nelem); + + log(LOG_INFO, "notifyClient()", + "- event (PHCI_DRIVER_MAJOR) has [%d] elements", + nelem); + + if ((NULL != instance) & (NULL != major)) { + + val = (uint64_t *)malloc(sizeof (uint64_t)); + + valAllocated = 1; + + *val = MP_STORE_INST_TO_ID(*instance, *val); + *val = MP_STORE_MAJOR_TO_ID(*major, *val); + + nelem = 1; + + } else { + + nelem = 0; + } + + } else { + + (void) nvlist_lookup_uint64_array(attr_list, OIDLIST, + &val, &nelem); + + log(LOG_INFO, "notifyClient()", + "- event has [%d] elements", + nelem); + } + + if (nelem > 0) { + + for (i = 0; i < nelem; i++) { + + log(LOG_INFO, "notifyClient()", + "- event [%d] = %llx", + i, val[i]); + } + + oidList = createOidList(nelem); + if (NULL == oidList) { + + log(LOG_INFO, "notifyClient()", + "- unable to create MP_OID_LIST"); + + log(LOG_INFO, "notifyClient()", + "- error exit"); + + nvlist_free(attr_list); + + return; + } + + oidList->oidCount = nelem; + + for (i = 0; i < nelem; i++) { + + oidList->oids[i].objectType = index; + oidList->oids[i].ownerId = g_pluginOwnerID; + oidList->oids[i].objectSequenceNumber = val[i]; + } + + if (valAllocated) { + + free(val); + } + + for (i = 0; i < oidList->oidCount; i++) { + + log(LOG_INFO, "notifyClient()", + "oidList->oids[%d].objectType" + " = %d", + i, oidList->oids[i].objectType); + log(LOG_INFO, "notifyClient()", + "oidList->oids[%d].ownerId" + " = %d", + i, oidList->oids[i].ownerId); + log(LOG_INFO, "notifyClient()", + "oidList->oids[%d].objectSequenceNumber" + " = %llx", + i, + oidList->oids[i].objectSequenceNumber); + } + + if (eventType == PROP_CHANGE) { + + (void) pthread_mutex_lock(&g_prop_mutex); + + pCallerData = g_Property_Callback_List[index]. + pCallerData; + + (g_Property_Callback_List[index].pClientFn) + (oidList, pCallerData); + + (void) pthread_mutex_unlock(&g_prop_mutex); + + } else if (eventType == VISA_CHANGE) { + + (void) pthread_mutex_lock(&g_visa_mutex); + + pCallerData = g_Visibility_Callback_List[index]. + pCallerData; + + (g_Visibility_Callback_List[index].pClientFn) + (becomingVisible, oidList, pCallerData); + + (void) pthread_mutex_unlock(&g_visa_mutex); + + } + } + + nvlist_free(attr_list); + } + + + log(LOG_INFO, "notifyClient()", "- exit"); +} + +/* Event handler called by system */ +static void +sysevent_handler(sysevent_t *ev) +{ + log(LOG_INFO, "sysevent_handler()", "- enter"); + + /* Is the event one of ours? */ + if ((strncmp(EC_SUN_MP, sysevent_get_class_name(ev), 9) != 0) && + (strncmp(EC_DEVFS, sysevent_get_class_name(ev), 8) != 0) && + (strncmp(EC_DDI, sysevent_get_class_name(ev), 6) != 0)) { + + return; + } + + /* Notify client if it cares */ + notifyClient(ev); + + + log(LOG_INFO, "sysevent_handler()", "- exit"); +} + +/* Registers the plugin to the sysevent framework */ +MP_STATUS init_sysevents() { + + const char *subclass_list[] = { + + ESC_SUN_MP_LU_CHANGE, + + ESC_SUN_MP_PATH_CHANGE, + ESC_SUN_MP_PATH_ADD, + ESC_SUN_MP_PATH_REMOVE, + + ESC_SUN_MP_INIT_PORT_CHANGE, + + ESC_SUN_MP_TPG_CHANGE, + ESC_SUN_MP_TPG_ADD, + ESC_SUN_MP_TPG_REMOVE, + + ESC_SUN_MP_TARGET_PORT_CHANGE, + ESC_SUN_MP_TARGET_PORT_ADD, + ESC_SUN_MP_TARGET_PORT_REMOVE, + + ESC_SUN_MP_DEV_PROD_CHANGE, + ESC_SUN_MP_DEV_PROD_ADD, + ESC_SUN_MP_DEV_PROD_REMOVE + + }; + + const char *lu_subclass_list[] = { + + ESC_DEVFS_DEVI_ADD, + ESC_DEVFS_DEVI_REMOVE + + }; + + const char *init_port_subclass_list[] = { + + ESC_DDI_INITIATOR_REGISTER, + ESC_DDI_INITIATOR_UNREGISTER + }; + + + + log(LOG_INFO, "init_sysevents()", "- enter"); + + + g_SysEventHandle = sysevent_bind_handle(sysevent_handler); + if (g_SysEventHandle == NULL) { + + log(LOG_INFO, "init_sysevents()", + "- sysevent_bind_handle() failed"); + + log(LOG_INFO, "init_sysevents()", "- error exit"); + + return (MP_STATUS_FAILED); + } + + if (sysevent_subscribe_event(g_SysEventHandle, EC_SUN_MP, + subclass_list, 14) != 0) { + + + log(LOG_INFO, "init_sysevents()", + "- sysevent_subscribe_event() failed for subclass_list"); + + log(LOG_INFO, "init_sysevents()", "- error exit"); + + sysevent_unbind_handle(g_SysEventHandle); + + return (MP_STATUS_FAILED); + } + + if (sysevent_subscribe_event(g_SysEventHandle, EC_DEVFS, + lu_subclass_list, 2) != 0) { + + + log(LOG_INFO, "init_sysevents()", + "- sysevent_subscribe_event() failed for lu_subclass_list"); + + log(LOG_INFO, "init_sysevents()", "- error exit"); + + sysevent_unbind_handle(g_SysEventHandle); + + return (MP_STATUS_FAILED); + } + + if (sysevent_subscribe_event(g_SysEventHandle, EC_DDI, + init_port_subclass_list, 2) != 0) { + + + log(LOG_INFO, "init_sysevents()", + "- sysevent_subscribe_event() failed " + "for init_port_subclass_list"); + + log(LOG_INFO, "init_sysevents()", "- error exit"); + + sysevent_unbind_handle(g_SysEventHandle); + + return (MP_STATUS_FAILED); + } + + + log(LOG_INFO, "init_sysevents()", "- exit"); + + return (MP_STATUS_SUCCESS); +} diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/common/mp_utils.h b/usr/src/lib/mpapi/libmpscsi_vhci/common/mp_utils.h new file mode 100644 index 0000000000..411043098c --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/common/mp_utils.h @@ -0,0 +1,117 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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. + */ +#ifndef _MP_UTILS_H +#define _MP_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <mpapi.h> +#include <sys/scsi/adapters/mpapi_impl.h> + +#include <sys/types.h> +#include <libsysevent.h> +#include <syslog.h> +#include <pthread.h> + +/* Default bytes */ +#define DEFAULT_BUFFER_SIZE_LU_LIST 4096 +#define DEFAULT_BUFFER_SIZE_INIT_PORT_LIST 1024 +#define DEFAULT_BUFFER_SIZE_PATH_LIST 1024 +#define DEFAULT_BUFFER_SIZE_DEV_PROD 1024 +#define DEFAULT_BUFFER_SIZE_TPG 1024 +#define DEFAULT_BUFFER_SIZE_LOADBALANCE 1024 + + +/* Node to hold pointer to client callback */ +typedef struct _property_node +{ + MP_OBJECT_PROPERTY_FN pClientFn; + void *pCallerData; + +} PROPERTY_CALLBACK_NODE; + + +/* Node to hold pointer to client callback */ +typedef struct _visibility_node +{ + MP_OBJECT_VISIBILITY_FN pClientFn; + void *pCallerData; + +} VISIBILITY_CALLBACK_NODE; + + +/* Global array to hold client callbacks */ +extern +PROPERTY_CALLBACK_NODE g_Property_Callback_List[MP_OBJECT_TYPE_MAX + 1]; + +/* Global array to hold client callbacks */ +extern +VISIBILITY_CALLBACK_NODE g_Visibility_Callback_List[MP_OBJECT_TYPE_MAX + 1]; + + +/* Global variable to hold this pligin's ID */ +extern MP_UINT32 g_pluginOwnerID; + +/* Global variable to hold scsi_vhci file descriptor */ +extern int g_scsi_vhci_fd; + +/* Global variable to hold sysevent handle */ +extern sysevent_handle_t *g_SysEventHandle; + +/* Mutexes to make array modify/read thread safe */ +extern pthread_mutex_t g_visa_mutex; +extern pthread_mutex_t g_prop_mutex; + + + +/* Used to add debug (log) info */ +void log(int priority, const char *routine, char *msg, ...); + +/* Returns an MP_STATUS code for an mp_iocdata_t.mp_errno code */ +MP_STATUS getStatus4ErrorCode(int driverError); + +/* Returns an MP_OID_LIST that will hold "size" MP_OID elements */ +MP_OID_LIST *createOidList(int size); + +/* Initializes the sysevent framework */ +MP_STATUS init_sysevents(); + +/* Implementation function for MP_GetAssociatedTPGOidList() */ +MP_STATUS getAssociatedTPGOidList(MP_OID oid, MP_OID_LIST **ppList); + +/* Implementation function for MP_GetTargetPortGroupProperties() */ +MP_STATUS getTargetPortGroupProperties(MP_OID oid, + MP_TARGET_PORT_GROUP_PROPERTIES *pProps); + +/* Implementation function for MP_GetTargetPortOidList() */ +MP_STATUS getTargetPortOidList(MP_OID oid, MP_OID_LIST **ppList); + +#ifdef __cplusplus +} +#endif + +#endif /* _MP_UTILS_H */ diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/i386/Makefile b/usr/src/lib/mpapi/libmpscsi_vhci/i386/Makefile new file mode 100644 index 0000000000..4acb0bde30 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/i386/Makefile @@ -0,0 +1,28 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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 ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/sparc/Makefile b/usr/src/lib/mpapi/libmpscsi_vhci/sparc/Makefile new file mode 100644 index 0000000000..4acb0bde30 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/sparc/Makefile @@ -0,0 +1,28 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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 ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) diff --git a/usr/src/lib/mpapi/libmpscsi_vhci/sparcv9/Makefile b/usr/src/lib/mpapi/libmpscsi_vhci/sparcv9/Makefile new file mode 100644 index 0000000000..bbc20fa470 --- /dev/null +++ b/usr/src/lib/mpapi/libmpscsi_vhci/sparcv9/Makefile @@ -0,0 +1,29 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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 ../Makefile.com +include ../../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) |