/******************************************************************************
*
* 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);
}
}
}