1 /******************************************************************************
4 * mpapi.c - Implements Multipath Management API Version 1.0
7 * The contents of this file are subject to the SNIA Public License
8 * Version 1.1 (the "License"); you may not use this file except in
9 * compliance with the License. You may obtain a copy of the License at
11 * http://mp-mgmt-api.sourceforge.net
13 * Software distributed under the License is distributed on an "AS IS"
14 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
15 * the License for the specific language governing rights and limitations
18 * The Original Code is SNIA iSCSI Management API and Multipath Management
21 * The Initial Developer of the Original Code is:
22 * Benjamin F. Kuo Troika Networks, Inc. (benk@troikanetworks.com)
23 * David Dillard VERITAS Software(david.dillard@veritas.com)
24 * Jeff Ding Adaptec, Inc. (jding@corp.adaptec.com)
25 * Hyon Kim Sun Microsystems(hyon.kim@sun.com)
28 * Paul von Behren Sun Microsystems(paul.vonbehren@sun.com)
30 ******************************************************************************
33 * 1/15/2005 Implemented SNIA MP API specification 1.0
35 * - License location was specified in the header comment.
36 * - validate_object() routine was updated per the latest
38 * - is_zero_oid() routine was added.
39 * - MP_GetObjectType() was updated with validate_object().
40 * - pplist argument checking added in MP_GetMultipathLus().
41 * - Corrected typo in MP_GetTaregetPortGroupProperties()
42 * - MP_RegisterForObjectPropertyChanges() was updated with
43 * is_zero_oid() routine.
44 * - MP_DeregisterForObjectPropertyChanges() was updated with
45 * is_zero_oid() routine.
46 * - MP_RegisterForObjectVisibilityChanges() was updated with
47 * is_zero_oid() routine.
48 * - MP_DeregisterForObjectVisibilityChanges() was updated with
49 * is_zero_oid() routine.
50 * - Added stat() check in MP_RegisterPlugin() to validate the
51 * the given plugin file name.
52 * - Made MP_DeregisterPlugin() return MP_STATUS_UNKNOWN_FN
53 * to mach the specification description.
54 ******************************************************************************
62 #include <sys/types.h>
70 #include "mpapi-sun.h"
71 #include "mpapi-plugin.h"
73 #define LIBRARY_SUPPORTED_MP_VERSION 1
74 #define LIBRARY_IMPLEMENTATION_VERSION L"1.0.0"
75 #define LIBRARY_VENDOR L"Sun Microsystems Inc."
77 #define LIBRARY_FILE_NAME "libMPAPI.so"
80 MPPLUGININFO_T plugintable
[MP_MAX_NUM_PLUGINS
];
81 pthread_mutex_t mp_lib_mutex
= PTHREAD_MUTEX_INITIALIZER
;
83 static int number_of_plugins
= -1;
88 static int lock_register(int fd
, int cmd
, int type
, off_t offset
, int whence
,
90 static int search_line(MP_CHAR
*buf
, size_t buflen
, MP_CHAR
*srch_id
,
91 size_t id_len
, int *write_offset
, int *bytes_left
);
92 static int is_zero_oid(MP_OID
);
95 ******************************************************************************
99 * - Return MP_STATUS_OBJECT_NOT_FOUND when no plugin is found or the ownerId
100 * of input OID is not found.
101 * - Return MP_STATUS_INVALID_OBJECT_TYPE when no plugin is found or
102 * the type of input OID is not one of legitimate types defined SNIA
103 * Multipath Management spec.
104 * - Return MP_STATUS_INVALID_PARAMETER when the type of input OID is
105 * legitimate but its object type doesn't match with the object type
107 * - Otherwise return MP_STATUS_SUCCESS.
109 ******************************************************************************
111 MP_STATUS
validate_object(MP_OID obj
, MP_OBJECT_TYPE objType
,
115 if ((number_of_plugins
== 0) ||
116 (obj
.ownerId
> number_of_plugins
|| obj
.ownerId
<= 0)) {
117 return (MP_STATUS_OBJECT_NOT_FOUND
);
118 } else if (obj
.objectType
< 0 || obj
.objectType
> MP_OBJECT_TYPE_MAX
) {
119 return (MP_STATUS_INVALID_OBJECT_TYPE
);
120 } else if (obj
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
121 if (obj
.objectSequenceNumber
!= 0) {
122 return (MP_STATUS_OBJECT_NOT_FOUND
);
126 if (flag
== MP_OBJECT_TYPE_MATCH
) {
127 if (obj
.objectType
!= objType
) {
128 return (MP_STATUS_INVALID_PARAMETER
);
131 return (MP_STATUS_SUCCESS
);
135 ******************************************************************************
137 * Check if an oid is ZERO_OID or not.
139 * - Return 1 if the input OID is ZERO_OID
143 ******************************************************************************
145 static int is_zero_oid(MP_OID oid
)
148 if ((oid
.objectType
!= MP_OBJECT_TYPE_UNKNOWN
) || (oid
.ownerId
!= 0) ||
149 (oid
.objectSequenceNumber
!= 0)) {
157 ******************************************************************************
159 * Initialize by loading plugin libraries and calling Initialize routine.
160 * Note: The build of libMPAPI.so should include a linker option to make this
161 * routine executed when it is loaded.
163 * - This routine bypasses a plugin library if it is not found.
164 * - The implementation of this routine is based on configuration file
165 * /etc/mpapi.conf that contains a list of plugin libraries.
167 ******************************************************************************
173 MP_WCHAR fullline
[MAX_LINE_SIZE
]; /* line read in from mpapi.conf */
174 MP_WCHAR name
[MAX_NAME_SIZE
]; /* Read in from file mpapi.conf */
175 char path
[MAX_NAME_SIZE
]; /* Read in from file mpapi.conf */
176 char systemPath
[MAX_NAME_SIZE
], mpConfFilePath
[MAX_NAME_SIZE
];
179 struct stat stat_buf
;
181 MP_UINT32 i
= 0; /* index for plugin table */
183 if(number_of_plugins
!= -1) {
187 (void) pthread_mutex_lock(&mp_lib_mutex
);
189 number_of_plugins
= 0;
191 /* Open configuration file from known location */
192 strncpy(mpConfFilePath
, "/etc/mpapi.conf", MAX_NAME_SIZE
);
194 if ((fd_mpconf
= open(mpConfFilePath
, O_RDONLY
)) < 0) {
195 (void) pthread_mutex_unlock(&mp_lib_mutex
);
199 if (lock_register(fd_mpconf
, F_SETLKW
, F_RDLCK
, 0, SEEK_SET
, 0) < 0) {
201 (void) pthread_mutex_unlock(&mp_lib_mutex
);
205 if ((mpconf
= fdopen(fd_mpconf
, "r")) == NULL
) {
206 lock_register(fd_mpconf
, F_SETLK
, F_UNLCK
, 0, SEEK_SET
, 0);
208 (void) pthread_mutex_unlock(&mp_lib_mutex
);
212 /* Read in each line and load library */
213 while ((mpconf
!= NULL
) &&
214 (charPtr
= fgetws(fullline
, MAX_LINE_SIZE
, mpconf
))) {
215 if ((*charPtr
!= L
'#') && (*charPtr
!= L
'\n')) {
216 /* Take out the '\n' */
217 if ((charPtr
= wcschr(fullline
, L
'\n')) != NULL
)
221 /* remove leading blank or taps. */
222 while ((fullline
[0] == L
' ') || (fullline
[0] == L
'\t'))
228 * look for first tab or space.
230 if ((charPtr
= wcschr(fullline
, L
'\t')) == NULL
)
231 charPtr
= wcschr(fullline
, L
' ');
233 /* Set Null termination for library name if found */
234 if (charPtr
!= NULL
) {
236 wcsncpy(name
, sol
, MAX_NAME_SIZE
);
237 /* Skip space and tab until the next character found */
238 while ((*charPtr
== L
' ') || (*charPtr
== L
'\t'))
241 continue; /* May be invalid entry */
244 /* Copy library name and path */
245 wcstombs(path
, charPtr
, MAX_NAME_SIZE
);
248 * Continue to the next line if library name or path is
251 if ((wcslen(name
) == 0) ||
255 /* Load the plugin now */
256 if (stat(path
, &stat_buf
) != -1) {
257 plugintable
[i
].hdlPlugin
= dlopen(path
, RTLD_LAZY
);
262 if (plugintable
[i
].hdlPlugin
!= NULL
) {
263 InitializeFn PassFunc
;
265 wcsncpy(plugintable
[i
].pluginName
,
266 name
, MAX_NAME_SIZE
);
267 strncpy(plugintable
[i
].pluginPath
,
268 path
, MAX_NAME_SIZE
);
270 plugintable
[i
].ownerId
= i
+ 1;
272 PassFunc
= (InitializeFn
)
273 dlsym(plugintable
[i
].hdlPlugin
, "Initialize");
274 if (PassFunc
!= NULL
) {
275 (void) PassFunc(plugintable
[i
].ownerId
);
283 if (lock_register(fd_mpconf
, F_SETLK
, F_UNLCK
, 0, SEEK_SET
, 0) < 0) {
286 (void) pthread_mutex_unlock(&mp_lib_mutex
);
292 number_of_plugins
= i
;
293 (void) pthread_mutex_unlock(&mp_lib_mutex
);
297 ******************************************************************************
299 * Exit by calling Terminate routine of plugin libraries.
301 * Note: The build of libMPAPI.so should include a linker option to make this
302 * routine executed when it is unloaded.
304 ******************************************************************************
310 if(number_of_plugins
== -1)
313 (void) pthread_mutex_lock(&mp_lib_mutex
);
314 for (i
= 0; i
< number_of_plugins
; i
++) {
315 if (plugintable
[i
].hdlPlugin
!= NULL
) {
316 TerminateFn ExitPassFunc
;
318 ExitPassFunc
= (TerminateFn
)
319 dlsym(plugintable
[i
].hdlPlugin
, "Terminate");
321 if (ExitPassFunc
!= NULL
) {
325 /* Unload plugin from memory */
326 dlclose(plugintable
[i
].hdlPlugin
);
330 number_of_plugins
= -1;
332 (void) pthread_mutex_unlock(&mp_lib_mutex
);
333 (void) pthread_mutex_destroy(&mp_lib_mutex
);
337 ******************************************************************************
339 * Gets the properties of the MP API library that is being used.
342 * A pointer to an @ref MP_LIBRARY_PROPERTIES structure allocated by
343 * the caller. On successful return this structure will contain the
344 * properties of the MP library.
346 * @return An MP_STATUS indicating if the operation was successful or
347 * if an error occurred.
349 * @retval MP_STATUS_SUCCESS
350 * Returned if the library properties were successfully returned.
352 * @retval MP_STATUS_INVALID_PARAMETER Returned if @a pProps is NULL or
353 * specifies a memory area to which data cannot be written.
355 ******************************************************************************
357 MP_STATUS
MP_GetLibraryProperties(
358 MP_LIBRARY_PROPERTIES
*pProps
)
360 char mpPath
[MAX_NAME_SIZE
];
363 return MP_STATUS_INVALID_PARAMETER
;
366 /* Fill in properties */
367 if (mbstowcs(pProps
->buildTime
, BUILD_TIME
, 256) !=
368 strlen(BUILD_TIME
)) {
369 return (MP_STATUS_INVALID_PARAMETER
);
371 pProps
->supportedMpVersion
= LIBRARY_SUPPORTED_MP_VERSION
;
373 wcsncpy(pProps
->implementationVersion
,
374 LIBRARY_IMPLEMENTATION_VERSION
, MAX_NAME_SIZE
);
375 wcsncpy(pProps
->vendor
, LIBRARY_VENDOR
, MAX_NAME_SIZE
);
377 snprintf(pProps
->fileName
, MAX_NAME_SIZE
, "%s",
380 return MP_STATUS_SUCCESS
;
385 ******************************************************************************
387 * Gets a list of the object IDs of all currently loaded plugins.
389 * @param ppList A pointer to a pointer to an @ref MP_OID_LIST. On successful
390 * return this will contain a pointer to an @ref MP_OID_LIST
391 * which contains the object IDs of all of the plugins currently loaded
393 * @return An MP_STATUS indicating if the operation was successful or if
396 * @retval MP_SUCCESS Returned if the plugin ID list was successfully returned.
397 * @retval MP_STATUS_INVALID_PARAMETER Returned if @a ppList is NULL or
398 * specifies a memory area to which data cannot be written.
400 ******************************************************************************
402 MP_STATUS
MP_GetPluginOidList(
403 MP_OID_LIST
**ppList
)
408 return (MP_STATUS_INVALID_PARAMETER
);
410 (void) pthread_mutex_lock(&mp_lib_mutex
);
412 if (number_of_plugins
== 0) {
413 *ppList
= (MP_OID_LIST
*)calloc(1, sizeof(MP_OID_LIST
));
415 *ppList
= (MP_OID_LIST
*)calloc(1,
416 sizeof(MP_OID_LIST
) + (number_of_plugins
- 1)* sizeof(MP_OID
) );
419 if ((*ppList
) == NULL
) {
420 (void) pthread_mutex_unlock(&mp_lib_mutex
);
421 return (MP_STATUS_INSUFFICIENT_MEMORY
);
424 (*ppList
)->oidCount
= number_of_plugins
;
426 if (number_of_plugins
!= 0) {
427 for (i
= 0; i
< number_of_plugins
; i
++) {
428 (*ppList
)->oids
[i
].objectType
= MP_OBJECT_TYPE_PLUGIN
;
429 (*ppList
)->oids
[i
].ownerId
= plugintable
[i
].ownerId
;
430 (*ppList
)->oids
[i
].objectSequenceNumber
= 0;
434 (void) pthread_mutex_unlock(&mp_lib_mutex
);
435 return MP_STATUS_SUCCESS
;
439 *******************************************************************************
441 * Gets the properties of the specified vendor plugin.
444 * The ID of the plugin whose properties are being retrieved.
447 * A pointer to an @ref MP_PLUGIN_PROPERTIES structure allocated by
448 * the caller. On successful return this will contain the properties
449 * of the plugin specified by pluginOid.
451 * @return An MP_STATUS indicating if the operation was successful or if an
454 * @retval MP_STATUS_SUCCESS
455 * Returned if the plugin properties were successfully returned.
457 * @retval MP_STATUS_INVALID_OBJECT_TYPE
458 * Returned if oid does not specify any valid object type.
460 * @retval MP_STATUS_OBJECT_NOT_FOUND
461 * Returned if oid has an owner that is not currently known to
464 * @retval MP_STATUS_INVALID_PARAMETER
465 * Returned if 'pProps' is NULL or specifies a memory area to
466 * which data cannot be written.
468 *******************************************************************************
470 MP_STATUS
MP_GetPluginProperties(
472 MP_PLUGIN_PROPERTIES
*pProps
)
474 MP_GetPluginPropertiesPluginFn PassFunc
;
479 return (MP_STATUS_INVALID_PARAMETER
);
481 if ((status
= validate_object(pluginOid
, MP_OBJECT_TYPE_PLUGIN
,
482 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
486 (void) pthread_mutex_lock(&mp_lib_mutex
);
488 index
= pluginOid
.ownerId
- 1;
489 if (plugintable
[index
].hdlPlugin
!= NULL
) {
490 PassFunc
= (MP_GetPluginPropertiesPluginFn
)
491 dlsym(plugintable
[index
].hdlPlugin
, "MP_GetPluginPropertiesPlugin");
493 if (PassFunc
!= NULL
) {
494 status
= PassFunc(pProps
);
496 status
= MP_STATUS_UNSUPPORTED
;
499 status
= MP_STATUS_FAILED
;
502 (void) pthread_mutex_unlock(&mp_lib_mutex
);
507 *******************************************************************************
509 * Gets the object ID for the plugin associated with the specified object ID.
512 * The object ID of an object that has been received from a previous
516 * A pointer to an MP_OID structure allocated by the caller. On
517 * successful return this will contain the object ID of the plugin
518 * associated with the object specified by @a objectId.
520 * @return An MP_STATUS indicating if the operation was successful or if
523 * @retval MP_STATUS_SUCCESS
524 * Returned if the associated plugin ID was successfully returned.
526 * @retval MP_STATUS_OBJECT_NOT_FOUND
527 * Returned if oid does not specify a plugin that is currently known to
530 * @retval MP_STATUS_INVALID_PARAMETER
531 * Returned if 'oid' specifies an object not owned by a plugin or
532 * if pPluginOid is NULL or specifies a memory area to which data
535 * @retval MP_STATUS_INVALID_OBJECT_TYPE
536 * Returned if 'oid' specifies an object with an invalid type.
538 *******************************************************************************
540 MP_STATUS
MP_GetAssociatedPluginOid(
547 if (pPluginId
== NULL
)
548 return (MP_STATUS_INVALID_PARAMETER
);
550 if ((status
= validate_object(objectId
, 0, MP_OBJECT_TYPE_ANY
)) !=
555 pPluginId
->objectType
= MP_OBJECT_TYPE_PLUGIN
;
556 pPluginId
->ownerId
= objectId
.ownerId
;
557 pPluginId
->objectSequenceNumber
= 0;
559 return (MP_STATUS_SUCCESS
);
563 *******************************************************************************
565 * Gets the object type of an initialized object ID.
568 * The object ID of an object that has been received from a previous
572 * A pointer to an MP_OBJECT_TYPE variable allocated by the caller.
573 * On successful return this will contain the object type of oid.
575 * @return An MP_STATUS indicating if the operation was successful or
576 * if an error occurred.
578 * @retval MP_STATUS_OBJECT_NOT_FOUND
579 * Returned if oid has an owner that is not currently known to
582 * @retval MP_STATUS_INVALID_PARAMETER
583 * Returned if oid does not specify any valid object type.
585 * @retval MP_STATUS_SUCCESS
586 * Returned when the operation is successful.
588 *******************************************************************************
590 MP_STATUS
MP_GetObjectType(
592 MP_OBJECT_TYPE
*pObjectType
)
596 if (pObjectType
== NULL
)
597 return MP_STATUS_INVALID_PARAMETER
;
599 if ((status
= validate_object(oid
, 0, MP_OBJECT_TYPE_ANY
))
600 != MP_STATUS_SUCCESS
) {
604 *pObjectType
= oid
.objectType
;
605 return MP_STATUS_SUCCESS
;
609 *******************************************************************************
611 * Gets a list of the object IDs of all the device product properties
612 * associated with this plugin.
615 * The object ID of plugin.
618 * A pointer to a pointer to an MP_OID_LIST structure.
619 * On a successful return, this will contain a pointer to
620 * an MP_OID_LIST that contains the object IDs of all the device
621 * product descriptors associated with the specified plugin.
623 * @return An MP_STATUS indicating if the operation was successful or if
626 * @retval MP_STATUS_SUCCESS
627 * Returned when the operation is successful.
629 * @retval MP_STATUS_INVALID_PARAMETER
630 * Returned if ppList pointer passed as placeholder for holding
631 * the device product list is found to be invalid.
633 * @retval MP_STATUS_INVALID_OBJECT_TYPE
634 * Returned if oid does not specify any valid object type.
636 * @retval MP_STATUS_FAILED
637 * Returned when the plugin for the specified oid is not found.
639 * @retval MP_STATUS_INSUFFICIENT_MEMORY
640 * Returned when memory allocation failure occurs
642 * @retval MP_STATUS_UNSUPPORTED
643 * Returned when the API is not supported.
645 *******************************************************************************
647 MP_STATUS
MP_GetDeviceProductOidList(
649 MP_OID_LIST
**ppList
)
651 MP_GetDeviceProductOidListPluginFn PassFunc
;
656 return MP_STATUS_INVALID_PARAMETER
;
658 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
659 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
663 (void) pthread_mutex_lock(&mp_lib_mutex
);
665 index
= oid
.ownerId
- 1;
666 if (plugintable
[index
].hdlPlugin
!= NULL
) {
667 PassFunc
= (MP_GetDeviceProductOidListPluginFn
)
668 dlsym(plugintable
[index
].hdlPlugin
,
669 "MP_GetDeviceProductOidListPlugin");
670 if (PassFunc
!= NULL
) {
671 status
= PassFunc(ppList
);
673 status
= MP_STATUS_UNSUPPORTED
;
676 status
= MP_STATUS_FAILED
;
679 (void) pthread_mutex_unlock(&mp_lib_mutex
);
684 *******************************************************************************
686 * Gets the device product properties of the specified plugin oid.
689 * The object ID of the plugin.
692 * A pointer to a pointer to an MP_DEVICE_PRODUCT_PROPERTIES structure
693 * allocated by the caller. On successful return it will contain
694 * a pointer to an MP_DEVICE_PRODUCT_PROPERTIES structure allocated
697 * @return An MP_STATUS indicating if the operation was successful or if
700 * @retval MP_STATUS_SUCCESS
701 * Returned when the operation is successful.
703 * @retval MP_STATUS_INVALID_PARAMETER
704 * Returned if ppProps pointer passed as placeholder for holding
705 * the device product properties is found to be invalid.
707 * @retval MP_STATUS_INVALID_OBJECT_TYPE
708 * Returned if oid does not specify any valid object type.
710 * @retval MP_STATUS_FAILED
711 * Returned when the plugin for the specified oid is not found.
713 * @retval MP_STATUS_INSUFFICIENT_MEMORY
714 * Returned when memory allocation failure occurs
716 * @retval MP_STATUS_UNSUPPORTED
717 * Returned when the API is not supported.
719 *******************************************************************************
721 MP_STATUS
MP_GetDeviceProductProperties(
723 MP_DEVICE_PRODUCT_PROPERTIES
*pProps
)
725 MP_GetDeviceProductPropertiesFn PassFunc
;
730 return MP_STATUS_INVALID_PARAMETER
;
732 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_DEVICE_PRODUCT
,
733 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
737 (void) pthread_mutex_lock(&mp_lib_mutex
);
739 index
= oid
.ownerId
- 1;
740 if (plugintable
[index
].hdlPlugin
!= NULL
) {
741 PassFunc
= (MP_GetDeviceProductPropertiesFn
)
742 dlsym(plugintable
[index
].hdlPlugin
,
743 "MP_GetDeviceProductProperties");
745 if (PassFunc
!= NULL
) {
746 status
= PassFunc(oid
, pProps
);
748 status
= MP_STATUS_UNSUPPORTED
;
751 status
= MP_STATUS_FAILED
;
754 (void) pthread_mutex_unlock(&mp_lib_mutex
);
759 *******************************************************************************
761 * Gets a list of the object IDs of all the initiator ports associated
765 * The object ID of plugin.
768 * A pointer to a pointer to an MP_OID_LIST structure.
769 * On a successful return, this will contain a pointer to
770 * an MP_OID_LIST that contains the object IDs of all the initiator
771 * ports associated with the specified plugin.
773 * @return An MP_STATUS indicating if the operation was successful or if
776 * @retval MP_STATUS_SUCCESS
777 * Returned when the operation is successful.
779 * @retval MP_STATUS_INVALID_PARAMETER
780 * Returned if ppList pointer passed as placeholder for holding
781 * the initiator port list is found to be invalid.
783 * @retval MP_STATUS_INVALID_OBJECT_TYPE
784 * Returned if oid does not specify any valid object type.
786 * @retval MP_STATUS_FAILED
787 * Returned when the plugin for the specified oid is not found.
789 * @retval MP_STATUS_INSUFFICIENT_MEMORY
790 * Returned when memory allocation failure occurs
792 * @retval MP_STATUS_UNSUPPORTED
793 * Returned when the API is not supported.
795 *******************************************************************************
797 MP_STATUS
MP_GetInitiatorPortOidList(
799 MP_OID_LIST
**ppList
)
801 MP_GetInitiatorPortOidListPluginFn PassFunc
;
806 return MP_STATUS_INVALID_PARAMETER
;
808 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
809 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
813 (void) pthread_mutex_lock(&mp_lib_mutex
);
815 index
= oid
.ownerId
- 1;
816 if (plugintable
[index
].hdlPlugin
!= NULL
) {
817 PassFunc
= (MP_GetDeviceProductOidListPluginFn
)
818 dlsym(plugintable
[index
].hdlPlugin
, "MP_GetInitiatorPortOidListPlugin");
820 if (PassFunc
!= NULL
) {
821 status
= PassFunc(ppList
);
823 status
= MP_STATUS_UNSUPPORTED
;
826 status
= MP_STATUS_FAILED
;
829 (void) pthread_mutex_unlock(&mp_lib_mutex
);
834 *******************************************************************************
836 * Gets the properties of the specified initiator port.
839 * The object ID of the initiator port.
842 * A pointer to an MP_INITIATOR_PORT_PROPERTIES structure
843 * allocated by the caller. On successful return, this structure
844 * will contain the properties of the port specified by oid.
846 * @return An MP_STATUS indicating if the operation was successful or if
849 * @retval MP_STATUS_SUCCESS
850 * Returned when the operation is successful.
852 * @retval MP_STATUS_INVALID_PARAMETER
853 * Returned if pProps is NULL or specifies a memory area to
854 * which data cannot be written.
856 * @retval MP_STATUS_INVALID_OBJECT_TYPE
857 * Returned if oid does not specify any valid object type.
859 * @retval MP_STATUS_OBJECT_NOT_FOUND
860 * Returned if oid has an owner that is not currently known to
863 *******************************************************************************
865 MP_STATUS
MP_GetInitiatorPortProperties(
867 MP_INITIATOR_PORT_PROPERTIES
*pProps
)
869 MP_GetInitiatorPortPropertiesFn PassFunc
;
874 return MP_STATUS_INVALID_PARAMETER
;
876 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_INITIATOR_PORT
,
877 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
881 (void) pthread_mutex_lock(&mp_lib_mutex
);
883 index
= oid
.ownerId
- 1;
884 if (plugintable
[index
].hdlPlugin
!= NULL
) {
885 PassFunc
= (MP_GetInitiatorPortPropertiesFn
)
886 dlsym(plugintable
[index
].hdlPlugin
,
887 "MP_GetInitiatorPortProperties");
889 if (PassFunc
!= NULL
) {
890 status
= PassFunc(oid
, pProps
);
892 status
= MP_STATUS_UNSUPPORTED
;
895 status
= MP_STATUS_FAILED
;
898 (void) pthread_mutex_unlock(&mp_lib_mutex
);
903 *******************************************************************************
905 * Gets a list of multipath logical units associated to a plugin.
908 * The object ID of plugin.
911 * A pointer to a pointer to an MP_OID_LIST structure.
912 * On a successful return, this will contain a pointer to
913 * an MP_OID_LIST that contains the object IDs of all the multipath
914 * logical units associated with the specified plugin.
916 * @return An MP_STATUS indicating if the operation was successful or if
919 * @retval MP_STATUS_SUCCESS
920 * Returned when the operation is successful.
922 * @retval MP_STATUS_INVALID_PARAMETER
923 * Returned if ppList pointer passed as placeholder for holding
924 * the multipath logical unit list is found to be invalid.
926 * @retval MP_STATUS_INVALID_OBJECT_TYPE
927 * Returned if oid does not specify any valid object type.
929 * @retval MP_STATUS_FAILED
930 * Returned when the plugin for the specified oid is not found.
932 * @retval MP_STATUS_INSUFFICIENT_MEMORY
933 * Returned when memory allocation failure occurs
935 * @retval MP_STATUS_UNSUPPORTED
936 * Returned when the API is not supported.
938 *******************************************************************************
940 MP_STATUS
MP_GetMultipathLus(
942 MP_OID_LIST
**ppList
)
948 return MP_STATUS_INVALID_PARAMETER
;
950 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
951 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
952 ((status
= validate_object(oid
, MP_OBJECT_TYPE_DEVICE_PRODUCT
,
953 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
957 (void) pthread_mutex_lock(&mp_lib_mutex
);
959 index
= oid
.ownerId
- 1;
960 if (plugintable
[index
].hdlPlugin
!= NULL
) {
961 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
962 MP_GetMultipathLusPluginFn PassFunc
;
963 PassFunc
= (MP_GetMultipathLusPluginFn
)
964 dlsym(plugintable
[index
].hdlPlugin
,
965 "MP_GetMultipathLusPlugin");
967 if (PassFunc
!= NULL
) {
968 status
= PassFunc(ppList
);
970 status
= MP_STATUS_UNSUPPORTED
;
972 } else if (oid
.objectType
== MP_OBJECT_TYPE_DEVICE_PRODUCT
) {
973 MP_GetMultipathLusDevProdFn PassFunc
;
974 PassFunc
= (MP_GetMultipathLusDevProdFn
)
975 dlsym(plugintable
[index
].hdlPlugin
,
976 "MP_GetMultipathLusDevProd");
978 if (PassFunc
!= NULL
) {
979 status
= PassFunc(oid
, ppList
);
981 status
= MP_STATUS_UNSUPPORTED
;
984 status
= MP_STATUS_INVALID_PARAMETER
;
988 (void) pthread_mutex_unlock(&mp_lib_mutex
);
994 *******************************************************************************
996 * Gets the properties of the specified logical unit.
999 * The object ID of the multipath logical unit.
1002 * A pointer to an MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES structure
1003 * allocated by the caller. On successful return, this structure
1004 * will contain the properties of the port specified by oid.
1006 * @return An MP_STATUS indicating if the operation was successful or if
1007 * an error occurred.
1009 * @retval MP_STATUS_SUCCESS
1010 * Returned when the operation is successful.
1012 * @retval MP_STATUS_INVALID_PARAMETER
1013 * Returned if pProps is NULL or specifies a memory area to
1014 * which data cannot be written.
1016 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1017 * Returned if oid does not specify any valid object type.
1019 * @retval MP_STATUS_OBJECT_NOT_FOUND
1020 * Returned if oid has an owner that is not currently known to
1023 *******************************************************************************
1025 MP_STATUS
MP_GetMPLogicalUnitProperties(
1027 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
*pProps
)
1029 MP_GetMPLogicalUnitPropertiesFn PassFunc
;
1034 return MP_STATUS_INVALID_PARAMETER
;
1036 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1037 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1041 (void) pthread_mutex_lock(&mp_lib_mutex
);
1043 index
= oid
.ownerId
- 1;
1044 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1045 PassFunc
= (MP_GetMPLogicalUnitPropertiesFn
)
1046 dlsym(plugintable
[index
].hdlPlugin
,
1047 "MP_GetMPLogicalUnitProperties");
1049 if (PassFunc
!= NULL
) {
1050 status
= PassFunc(oid
, pProps
);
1052 status
= MP_STATUS_UNSUPPORTED
;
1055 status
= MP_STATUS_FAILED
;
1058 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1063 *******************************************************************************
1065 * Gets a list of the object IDs of all the path logical units associated
1066 * with the specified multipath logical unit, initiator port, or target port.
1069 * The object ID of multipath logical unit, initiator port, or
1073 * A pointer to a pointer to an MP_OID_LIST structure.
1074 * On a successful return, this will contain a pointer to
1075 * an MP_OID_LIST that contains the object IDs of all the mp path
1076 * logical units associated with the specified OID.
1078 * @return An MP_STATUS indicating if the operation was successful or if
1079 * an error occurred.
1081 * @retval MP_STATUS_SUCCESS
1082 * Returned when the operation is successful.
1084 * @retval MP_STATUS_INVALID_PARAMETER
1085 * Returned if ppList pointer passed as placeholder for holding
1086 * the device product list is found to be invalid.
1088 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1089 * Returned if oid does not specify any valid object type.
1091 * @retval MP_STATUS_FAILED
1092 * Returned when the plugin for the specified oid is not found.
1094 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1095 * Returned when memory allocation failure occurs
1097 * @retval MP_STATUS_OBJECT_NOT_FOUND
1098 * Returned if oid has an owner that is not currently known to
1101 *******************************************************************************
1103 MP_STATUS
MP_GetAssociatedPathOidList(
1105 MP_OID_LIST
**ppList
)
1107 MP_GetAssociatedPathOidListFn PassFunc
;
1112 return MP_STATUS_INVALID_PARAMETER
;
1114 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_INITIATOR_PORT
,
1115 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
1116 ((status
= validate_object(oid
, MP_OBJECT_TYPE_TARGET_PORT
,
1117 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
1118 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1119 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
1123 (void) pthread_mutex_lock(&mp_lib_mutex
);
1125 index
= oid
.ownerId
- 1;
1126 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1127 PassFunc
= (MP_GetAssociatedPathOidListFn
)
1128 dlsym(plugintable
[index
].hdlPlugin
,
1129 "MP_GetAssociatedPathOidList");
1131 if (PassFunc
!= NULL
) {
1132 status
= PassFunc(oid
, ppList
);
1134 status
= MP_STATUS_UNSUPPORTED
;
1137 status
= MP_STATUS_FAILED
;
1140 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1145 *******************************************************************************
1147 * Gets the properties of the specified path logical unit.
1150 * The object ID of the path logical unit.
1153 * A pointer to an MP_PATH_LOGICAL_UNIT_PROPERTIES structure
1154 * allocated by the caller. On successful return, this structure
1155 * will contain the properties of the port specified by oid.
1157 * @return An MP_STATUS indicating if the operation was successful or if
1158 * an error occurred.
1160 * @retval MP_STATUS_SUCCESS
1161 * Returned when the operation is successful.
1163 * @retval MP_STATUS_INVALID_PARAMETER
1164 * Returned if pProps is NULL or specifies a memory area to
1165 * which data cannot be written.
1167 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1168 * Returned if oid does not specify any valid object type.
1170 * @retval MP_STATUS_OBJECT_NOT_FOUND
1171 * Returned if oid has an owner that is not currently known to
1174 *******************************************************************************
1176 MP_STATUS
MP_GetPathLogicalUnitProperties(
1178 MP_PATH_LOGICAL_UNIT_PROPERTIES
*pProps
)
1180 MP_GetPathLogicalUnitPropertiesFn PassFunc
;
1185 return MP_STATUS_INVALID_PARAMETER
;
1187 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PATH_LU
,
1188 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1192 (void) pthread_mutex_lock(&mp_lib_mutex
);
1194 index
= oid
.ownerId
- 1;
1195 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1196 PassFunc
= (MP_GetPathLogicalUnitPropertiesFn
)
1197 dlsym(plugintable
[index
].hdlPlugin
,
1198 "MP_GetPathLogicalUnitProperties");
1200 if (PassFunc
!= NULL
) {
1201 status
= PassFunc(oid
, pProps
);
1203 status
= MP_STATUS_UNSUPPORTED
;
1206 status
= MP_STATUS_FAILED
;
1209 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1214 *******************************************************************************
1216 * Gets a list of the object IDs of all the target port group associated
1217 * with the specified multipath logical unit.
1220 * The object ID of the multiple logical unit.
1223 * A pointer to a pointer to an MP_OID_LIST structure.
1224 * On a successful return, this will contain a pointer to
1225 * an MP_OID_LIST that contains the object IDs of all the target
1226 * port group associated with the specified multipath logical unit.
1228 * @return An MP_STATUS indicating if the operation was successful or if
1229 * an error occurred.
1231 * @retval MP_STATUS_SUCCESS
1232 * Returned when the operation is successful.
1234 * @retval MP_STATUS_INVALID_PARAMETER
1235 * Returned if ppList pointer passed as placeholder for holding
1236 * the target port group list is found to be invalid.
1238 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1239 * Returned if oid does not specify any valid object type.
1241 * @retval MP_STATUS_FAILED
1242 * Returned when the plugin for the specified oid is not found.
1244 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1245 * Returned when memory allocation failure occurs
1248 *******************************************************************************
1250 MP_STATUS
MP_GetAssociatedTPGOidList(
1252 MP_OID_LIST
**ppList
)
1254 MP_GetAssociatedTPGOidListFn PassFunc
;
1259 return MP_STATUS_INVALID_PARAMETER
;
1261 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1262 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1266 (void) pthread_mutex_lock(&mp_lib_mutex
);
1268 index
= oid
.ownerId
- 1;
1269 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1270 PassFunc
= (MP_GetAssociatedTPGOidListFn
)
1271 dlsym(plugintable
[index
].hdlPlugin
,
1272 "MP_GetAssociatedTPGOidList");
1274 if (PassFunc
!= NULL
) {
1275 status
= PassFunc(oid
, ppList
);
1277 status
= MP_STATUS_UNSUPPORTED
;
1280 status
= MP_STATUS_FAILED
;
1283 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1288 *******************************************************************************
1290 * Gets the properties of the specified target port group.
1293 * The object ID of the target port group.
1296 * A pointer to an MP_TARGET_PORT_GROUP_PROPERTIES structure
1297 * allocated by the caller. On successful return, this structure
1298 * will contain the properties of the port specified by oid.
1300 * @return An MP_STATUS indicating if the operation was successful or if
1301 * an error occurred.
1303 * @retval MP_STATUS_SUCCESS
1304 * Returned when the operation is successful.
1306 * @retval MP_STATUS_INVALID_PARAMETER
1307 * Returned if pProps is NULL or specifies a memory area to
1308 * which data cannot be written.
1310 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1311 * Returned if oid does not specify any valid object type.
1313 * @retval MP_STATUS_OBJECT_NOT_FOUND
1314 * Returned if oid has an owner that is not currently known to
1317 *******************************************************************************
1319 MP_STATUS
MP_GetTargetPortGroupProperties(
1321 MP_TARGET_PORT_GROUP_PROPERTIES
*pProps
)
1323 MP_GetTargetPortGroupPropertiesFn PassFunc
;
1328 return MP_STATUS_INVALID_PARAMETER
;
1330 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_TARGET_PORT_GROUP
,
1331 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1335 (void) pthread_mutex_lock(&mp_lib_mutex
);
1337 index
= oid
.ownerId
- 1;
1338 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1339 PassFunc
= (MP_GetTargetPortGroupPropertiesFn
)
1340 dlsym(plugintable
[index
].hdlPlugin
,
1341 "MP_GetTargetPortGroupProperties");
1343 if (PassFunc
!= NULL
) {
1344 status
= PassFunc(oid
, pProps
);
1346 status
= MP_STATUS_UNSUPPORTED
;
1349 status
= MP_STATUS_FAILED
;
1352 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1357 *******************************************************************************
1359 * Gets a list of multipath logical units associated with the specific target
1363 * The object ID of the target port group.
1366 * A pointer to a pointer to an MP_OID_LIST structure.
1367 * On a successful return, this will contain a pointer to
1368 * an MP_OID_LIST that contains the object IDs of all the multipath
1369 * logical units associated with the specified target port group.
1371 * @return An MP_STATUS indicating if the operation was successful or if
1372 * an error occurred.
1374 * @retval MP_STATUS_SUCCESS
1375 * Returned when the operation is successful.
1377 * @retval MP_STATUS_INVALID_PARAMETER
1378 * Returned if ppList pointer passed as placeholder for holding
1379 * the multipath logical unit list is found to be invalid.
1381 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1382 * Returned if oid does not specify any valid object type.
1384 * @retval MP_STATUS_FAILED
1385 * Returned when the plugin for the specified oid is not found.
1387 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1388 * Returned when memory allocation failure occurs
1390 *******************************************************************************
1392 MP_STATUS
MP_GetMPLuOidListFromTPG(
1394 MP_OID_LIST
**ppList
)
1396 MP_GetMPLuOidListFromTPGFn PassFunc
;
1401 return MP_STATUS_INVALID_PARAMETER
;
1403 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_TARGET_PORT_GROUP
,
1404 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1408 (void) pthread_mutex_lock(&mp_lib_mutex
);
1410 index
= oid
.ownerId
- 1;
1411 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1412 PassFunc
= (MP_GetMPLuOidListFromTPGFn
)
1413 dlsym(plugintable
[index
].hdlPlugin
,
1414 "MP_GetMPLuOidListFromTPG");
1416 if (PassFunc
!= NULL
) {
1417 status
= PassFunc(oid
, ppList
);
1419 status
= MP_STATUS_UNSUPPORTED
;
1422 status
= MP_STATUS_FAILED
;
1425 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1430 *******************************************************************************
1432 * Gets a list of the object IDs of all the proprietary load balance
1433 * algorithms associated with this plugin.
1436 * The object ID of the plugin.
1439 * A pointer to a pointer to an MP_OID_LIST structure.
1440 * On a successful return, this will contain a pointer to
1441 * an MP_OID_LIST that contains the object IDs of all the proprietary
1442 * load balance algorithms associated with the specified plugin.
1444 * @return An MP_STATUS indicating if the operation was successful or if
1445 * an error occurred.
1447 * @retval MP_STATUS_SUCCESS
1448 * Returned when the operation is successful.
1450 * @retval MP_STATUS_INVALID_PARAMETER
1451 * Returned if ppList pointer passed as placeholder for holding
1452 * the proprietary load balance oid list is found to be invalid.
1454 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1455 * Returned if oid does not specify any valid object type.
1457 * @retval MP_STATUS_FAILED
1458 * Returned when the plugin for the specified oid is not found.
1460 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1461 * Returned when memory allocation failure occurs
1463 * @retval MP_STATUS_UNSUPPORTED
1464 * Returned when the API is not supported.
1466 *******************************************************************************
1468 MP_STATUS
MP_GetProprietaryLoadBalanceOidList(
1470 MP_OID_LIST
**ppList
)
1472 MP_GetProprietaryLoadBalanceOidListPluginFn PassFunc
;
1477 return MP_STATUS_INVALID_PARAMETER
;
1479 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
1480 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1484 (void) pthread_mutex_lock(&mp_lib_mutex
);
1486 index
= oid
.ownerId
- 1;
1487 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1488 PassFunc
= (MP_GetProprietaryLoadBalanceOidListPluginFn
)
1489 dlsym(plugintable
[index
].hdlPlugin
,
1490 "MP_GetProprietaryLoadBalanceOidListPlugin");
1492 if (PassFunc
!= NULL
) {
1493 status
= PassFunc(ppList
);
1495 status
= MP_STATUS_UNSUPPORTED
;
1498 status
= MP_STATUS_FAILED
;
1501 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1506 *******************************************************************************
1508 * Gets the properties of the specified load balance properties structure.
1511 * The object ID of the load balance properties structure.
1514 * A pointer to an MP_LOAD_BALANCE_PROPRIETARY_TYPE structure
1515 * allocated by the caller. On successful return, this structure
1516 * will contain the properties of the proprietary load balance algorithm
1519 * @return An MP_STATUS indicating if the operation was successful or if
1520 * an error occurred.
1522 * @retval MP_STATUS_SUCCESS
1523 * Returned when the operation is successful.
1525 * @retval MP_STATUS_INVALID_PARAMETER
1526 * Returned if pProps is NULL or specifies a memory area to
1527 * which data cannot be written.
1529 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1530 * Returned if oid does not specify any valid object type.
1532 * @retval MP_STATUS_OBJECT_NOT_FOUND
1533 * Returned if oid has an owner that is not currently known to
1536 *******************************************************************************
1538 MP_STATUS
MP_GetProprietaryLoadBalanceProperties (
1540 MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES
*pProps
)
1542 MP_GetProprietaryLoadBalancePropertiesFn PassFunc
;
1547 return MP_STATUS_INVALID_PARAMETER
;
1549 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE
,
1550 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1554 (void) pthread_mutex_lock(&mp_lib_mutex
);
1556 index
= oid
.ownerId
- 1;
1557 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1558 PassFunc
= (MP_GetProprietaryLoadBalancePropertiesFn
)
1559 dlsym(plugintable
[index
].hdlPlugin
,
1560 "MP_GetProprietaryLoadBalanceProperties");
1562 if (PassFunc
!= NULL
) {
1563 status
= PassFunc(oid
, pProps
);
1565 status
= MP_STATUS_UNSUPPORTED
;
1568 status
= MP_STATUS_FAILED
;
1571 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1576 *******************************************************************************
1578 * Gets a list of the object IDs of the target ports in the specified target
1582 * The object ID of the target port group.
1585 * A pointer to a pointer to an MP_OID_LIST structure.
1586 * On a successful return, this will contain a pointer to
1587 * an MP_OID_LIST that contains the object IDs of all the target ports
1588 * associated with the specified target port group.
1590 * @return An MP_STATUS indicating if the operation was successful or if
1591 * an error occurred.
1593 * @retval MP_STATUS_SUCCESS
1594 * Returned when the operation is successful.
1596 * @retval MP_STATUS_INVALID_PARAMETER
1597 * Returned if ppList pointer passed as placeholder for holding
1598 * the multipath logical unit list is found to be invalid.
1600 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1601 * Returned if oid does not specify any valid object type.
1603 * @retval MP_STATUS_FAILED
1604 * Returned when the plugin for the specified oid is not found.
1606 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1607 * Returned when memory allocation failure occurs
1609 *******************************************************************************
1611 MP_STATUS
MP_GetTargetPortOidList(
1613 MP_OID_LIST
**ppList
)
1615 MP_GetTargetPortOidListFn PassFunc
;
1620 return MP_STATUS_INVALID_PARAMETER
;
1622 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_TARGET_PORT_GROUP
,
1623 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1627 (void) pthread_mutex_lock(&mp_lib_mutex
);
1629 index
= oid
.ownerId
- 1;
1630 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1631 PassFunc
= (MP_GetTargetPortOidListFn
)
1632 dlsym(plugintable
[index
].hdlPlugin
,
1633 "MP_GetTargetPortOidList");
1635 if (PassFunc
!= NULL
) {
1636 status
= PassFunc(oid
, ppList
);
1638 status
= MP_STATUS_UNSUPPORTED
;
1641 status
= MP_STATUS_FAILED
;
1644 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1649 *******************************************************************************
1651 * Gets the properties of the specified target port.
1654 * The object ID of the target port.
1657 * A pointer to an MP_TARGET_PORT_PROPERTIES structure
1658 * allocated by the caller. On successful return, this structure
1659 * will contain the properties of the port specified by oid.
1661 * @return An MP_STATUS indicating if the operation was successful or if
1662 * an error occurred.
1664 * @retval MP_STATUS_SUCCESS
1665 * Returned when the operation is successful.
1667 * @retval MP_STATUS_INVALID_PARAMETER
1668 * Returned if pProps is NULL or specifies a memory area to
1669 * which data cannot be written.
1671 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1672 * Returned if oid does not specify any valid object type.
1674 * @retval MP_STATUS_OBJECT_NOT_FOUND
1675 * Returned if oid has an owner that is not currently known to
1678 *******************************************************************************
1680 MP_STATUS
MP_GetTargetPortProperties(
1682 MP_TARGET_PORT_PROPERTIES
*pProps
)
1684 MP_GetTargetPortPropertiesFn PassFunc
;
1689 return MP_STATUS_INVALID_PARAMETER
;
1691 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_TARGET_PORT
,
1692 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1696 (void) pthread_mutex_lock(&mp_lib_mutex
);
1698 index
= oid
.ownerId
- 1;
1699 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1700 PassFunc
= (MP_GetTargetPortPropertiesFn
)
1701 dlsym(plugintable
[index
].hdlPlugin
,
1702 "MP_GetTargetPortProperties");
1704 if (PassFunc
!= NULL
) {
1705 status
= PassFunc(oid
, pProps
);
1707 status
= MP_STATUS_UNSUPPORTED
;
1710 status
= MP_STATUS_FAILED
;
1713 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1719 *******************************************************************************
1721 * Assign a multipath logical unit to a target port group.
1724 * An MP_TARGET_PORT_GROUP oid. The target port group currently in
1725 * active access state that the administrator would like the LU
1729 * An MP_MULTIPATH_LOGICAL_UNIT oid.
1731 * @return An MP_STATUS indicating if the operation was successful or if
1732 * an error occurred.
1734 * @retval MP_STATUS_SUCCESS
1735 * Returned when the operation is successful.
1737 * @retval MP_STATUS_INVALID_PARAMETER
1738 * Returned when luOid is not associated with tpgOid.
1740 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1741 * Returned if oid does not specify any valid object type.
1743 * @retval MP_STATUS_OBJECT_NOT_FOUND
1744 * Returned if oid has an owner that is not currently known to
1747 *******************************************************************************
1749 MP_STATUS
MP_AssignLogicalUnitToTPG(
1753 MP_AssignLogicalUnitToTPGFn PassFunc
;
1757 if (luOid
.ownerId
!= tpgOid
.ownerId
) {
1758 return (MP_STATUS_INVALID_PARAMETER
);
1761 if ((status
= validate_object(tpgOid
, MP_OBJECT_TYPE_TARGET_PORT_GROUP
,
1762 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1766 if ((status
= validate_object(luOid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1767 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1771 (void) pthread_mutex_lock(&mp_lib_mutex
);
1773 index
= tpgOid
.ownerId
- 1;
1774 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1775 PassFunc
= (MP_AssignLogicalUnitToTPGFn
)
1776 dlsym(plugintable
[index
].hdlPlugin
,
1777 "MP_AssignLogicalUnitToTPG");
1779 if (PassFunc
!= NULL
) {
1780 status
= PassFunc(tpgOid
, luOid
);
1782 status
= MP_STATUS_UNSUPPORTED
;
1785 status
= MP_STATUS_FAILED
;
1788 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1793 *******************************************************************************
1795 * Manually override the path for a logical unit. The path exclusively used to
1796 * access the logical unit until cleared.
1798 * @param logicalUnitOid
1799 * The object ID of the multipath logical unit.
1802 * The object ID of the path logical unit.
1804 * @return An MP_STATUS indicating if the operation was successful or if
1805 * an error occurred.
1807 * @retval MP_STATUS_SUCCESS
1808 * Returned when the operation is successful.
1810 * @retval MP_STATUS_INVALID_PARAMETER
1811 * Returned if the oid of the object is not valid
1813 * @retval MP_STATUS_UNSUPPORTED
1814 * Returned when the implementation does not support the API
1816 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1817 * Returned if oid does not specify any valid object type.
1819 * @retval MP_STATUS_PATH_NONOPERATIONAL
1820 * Returned when the driver cannot communicate through selected path.
1822 *******************************************************************************
1824 MP_STATUS
MP_SetOverridePath(
1825 MP_OID logicalUnitOid
,
1828 MP_SetOverridePathFn PassFunc
;
1832 if ((status
= validate_object(logicalUnitOid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1833 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1836 if ((status
= validate_object(pathOid
, MP_OBJECT_TYPE_PATH_LU
,
1837 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1841 (void) pthread_mutex_lock(&mp_lib_mutex
);
1843 index
= pathOid
.ownerId
- 1;
1844 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1845 PassFunc
= (MP_SetOverridePathFn
)
1846 dlsym(plugintable
[index
].hdlPlugin
,
1847 "MP_SetOverridePath");
1849 if (PassFunc
!= NULL
) {
1850 status
= PassFunc(logicalUnitOid
, pathOid
);
1852 status
= MP_STATUS_UNSUPPORTED
;
1855 status
= MP_STATUS_FAILED
;
1858 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1863 *******************************************************************************
1865 * Cancel a path override and re-enable load balancing.
1868 * An MP_MULTIPATH_LOGICAL_UNIT oid.
1870 * @return An MP_STATUS indicating if the operation was successful or if
1871 * an error occurred.
1873 * @retval MP_STATUS_SUCCESS
1874 * Returned when the operation is successful.
1876 * @retval MP_STATUS_INVALID_PARAMETER
1877 * Returned if MP_MULTIPATH_LOGICAL_UNIT with the luOid is not found.
1879 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1880 * Returned if oid does not specify any valid object type.
1882 * @retval MP_STATUS_OBJECT_NOT_FOUND
1883 * Returned if oid has an owner that is not currently known to
1886 *******************************************************************************
1888 MP_STATUS
MP_CancelOverridePath(
1891 MP_CancelOverridePathFn PassFunc
;
1895 if ((status
= validate_object(luOid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1896 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1900 (void) pthread_mutex_lock(&mp_lib_mutex
);
1902 index
= luOid
.ownerId
- 1;
1903 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1904 PassFunc
= (MP_CancelOverridePathFn
)
1905 dlsym(plugintable
[index
].hdlPlugin
,
1906 "MP_CancelOverridePath");
1908 if (PassFunc
!= NULL
) {
1909 status
= PassFunc(luOid
);
1911 status
= MP_STATUS_UNSUPPORTED
;
1914 status
= MP_STATUS_FAILED
;
1917 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1922 *******************************************************************************
1924 * Enables Auto-failback.
1927 * The oid of the plugin.
1929 * @return An MP_STATUS indicating if the operation was successful or if
1930 * an error occurred.
1932 * @retval MP_STATUS_SUCCESS
1933 * Returned when the operation is successful.
1935 * @retval MP_STATUS_INVALID_PARAMETER
1936 * Returned if oid is NULL or specifies a memory area that is not
1937 * a valid plugin oid.
1939 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1940 * Returned if oid does not specify any valid object type.
1942 *******************************************************************************
1944 MP_STATUS
MP_EnableAutoFailback(
1950 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
1951 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
1952 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1953 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
1957 (void) pthread_mutex_lock(&mp_lib_mutex
);
1959 index
= oid
.ownerId
- 1;
1960 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1961 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
1962 MP_EnableAutoFailbackPluginFn PassFunc
;
1963 PassFunc
= (MP_EnableAutoFailbackPluginFn
)
1964 dlsym(plugintable
[index
].hdlPlugin
,
1965 "MP_EnableAutoFailbackPlugin");
1967 if (PassFunc
!= NULL
) {
1968 status
= PassFunc();
1970 status
= MP_STATUS_UNSUPPORTED
;
1972 } else if (oid
.objectType
== MP_OBJECT_TYPE_MULTIPATH_LU
) {
1973 MP_EnableAutoFailbackLuFn PassFunc
;
1974 PassFunc
= (MP_EnableAutoFailbackLuFn
)
1975 dlsym(plugintable
[index
].hdlPlugin
,
1976 "MP_EnableAutoFailbackLu");
1978 if (PassFunc
!= NULL
) {
1979 status
= PassFunc(oid
);
1981 status
= MP_STATUS_UNSUPPORTED
;
1984 status
= MP_STATUS_INVALID_PARAMETER
;
1988 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1993 *******************************************************************************
1995 * Enables Auto-probing.
1998 * The oid of the plugin or the multipath logical unit.
2000 * @return An MP_STATUS indicating if the operation was successful or if
2001 * an error occurred.
2003 * @retval MP_STATUS_SUCCESS
2004 * Returned when the operation is successful.
2006 * @retval MP_STATUS_INVALID_PARAMETER
2007 * Returned if oid is NULL or specifies a memory area that is not
2008 * a valid plugin oid.
2010 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2011 * Returned if oid does not specify any valid object type.
2013 *******************************************************************************
2015 MP_STATUS
MP_EnableAutoProbing(
2021 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2022 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2023 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2024 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
2028 (void) pthread_mutex_lock(&mp_lib_mutex
);
2030 index
= oid
.ownerId
- 1;
2031 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2032 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
2033 MP_EnableAutoProbingPluginFn PassFunc
;
2034 PassFunc
= (MP_EnableAutoProbingPluginFn
)
2035 dlsym(plugintable
[index
].hdlPlugin
,
2036 "MP_EnableAutoProbingPlugin");
2038 if (PassFunc
!= NULL
) {
2039 status
= PassFunc();
2041 status
= MP_STATUS_UNSUPPORTED
;
2043 } else if (oid
.objectType
== MP_OBJECT_TYPE_MULTIPATH_LU
) {
2044 MP_EnableAutoProbingLuFn PassFunc
;
2045 PassFunc
= (MP_EnableAutoProbingLuFn
)
2046 dlsym(plugintable
[index
].hdlPlugin
,
2047 "MP_EnableAutoProbingLu");
2049 if (PassFunc
!= NULL
) {
2050 status
= PassFunc(oid
);
2052 status
= MP_STATUS_UNSUPPORTED
;
2055 status
= MP_STATUS_INVALID_PARAMETER
;
2059 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2064 *******************************************************************************
2066 * Disables Auto-failback.
2069 * The oid of the plugin.
2071 * @return An MP_STATUS indicating if the operation was successful or if
2072 * an error occurred.
2074 * @retval MP_STATUS_SUCCESS
2075 * Returned when the operation is successful.
2077 * @retval MP_STATUS_INVALID_PARAMETER
2078 * Returned if oid is NULL or specifies a memory area that is not
2079 * a valid plugin oid.
2081 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2082 * Returned if oid does not specify any valid object type.
2084 *******************************************************************************
2086 MP_STATUS
MP_DisableAutoFailback(
2092 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2093 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2094 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2095 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
2099 (void) pthread_mutex_lock(&mp_lib_mutex
);
2101 index
= oid
.ownerId
- 1;
2102 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2103 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
2104 MP_DisableAutoFailbackPluginFn PassFunc
;
2105 PassFunc
= (MP_DisableAutoFailbackPluginFn
)
2106 dlsym(plugintable
[index
].hdlPlugin
,
2107 "MP_DisableAutoFailbackPlugin");
2109 if (PassFunc
!= NULL
) {
2110 status
= PassFunc();
2112 status
= MP_STATUS_UNSUPPORTED
;
2114 } else if (oid
.objectType
== MP_OBJECT_TYPE_MULTIPATH_LU
) {
2115 MP_DisableAutoFailbackLuFn PassFunc
;
2116 PassFunc
= (MP_DisableAutoFailbackLuFn
)
2117 dlsym(plugintable
[index
].hdlPlugin
,
2118 "MP_DisableAutoFailbackLu");
2120 if (PassFunc
!= NULL
) {
2121 status
= PassFunc(oid
);
2123 status
= MP_STATUS_UNSUPPORTED
;
2126 status
= MP_STATUS_INVALID_PARAMETER
;
2130 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2135 *******************************************************************************
2137 * Disables Auto-probing.
2140 * The oid of the plugin or the multipath logical unit.
2142 * @return An MP_STATUS indicating if the operation was successful or if
2143 * an error occurred.
2145 * @retval MP_STATUS_SUCCESS
2146 * Returned when the operation is successful.
2148 * @retval MP_STATUS_INVALID_PARAMETER
2149 * Returned if oid is NULL or specifies a memory area that is not
2150 * a valid plugin oid.
2152 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2153 * Returned if oid does not specify any valid object type.
2155 *******************************************************************************
2157 MP_STATUS
MP_DisableAutoProbing(
2163 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2164 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2165 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2166 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
2170 (void) pthread_mutex_lock(&mp_lib_mutex
);
2172 index
= oid
.ownerId
- 1;
2173 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2174 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
2175 MP_DisableAutoProbingPluginFn PassFunc
;
2176 PassFunc
= (MP_DisableAutoProbingPluginFn
)
2177 dlsym(plugintable
[index
].hdlPlugin
,
2178 "MP_DisableAutoProbingPlugin");
2180 if (PassFunc
!= NULL
) {
2181 status
= PassFunc();
2183 status
= MP_STATUS_UNSUPPORTED
;
2185 } else if (oid
.objectType
== MP_OBJECT_TYPE_MULTIPATH_LU
) {
2186 MP_DisableAutoFailbackLuFn PassFunc
;
2187 PassFunc
= (MP_DisableAutoProbingLuFn
)
2188 dlsym(plugintable
[index
].hdlPlugin
,
2189 "MP_DisableAutoProbingLu");
2191 if (PassFunc
!= NULL
) {
2192 status
= PassFunc(oid
);
2194 status
= MP_STATUS_UNSUPPORTED
;
2197 status
= MP_STATUS_INVALID_PARAMETER
;
2201 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2206 *******************************************************************************
2208 * Enables a path. This API may cause failover in a logical unit with
2209 * asymmetric access.
2212 * The oid of the path.
2214 * @return An MP_STATUS indicating if the operation was successful or if
2215 * an error occurred.
2217 * @retval MP_STATUS_SUCCESS
2218 * Returned when the operation is successful.
2220 * @retval MP_STATUS_INVALID_PARAMETER
2221 * Returned if oid is NULL or specifies a memory area that is not
2224 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2225 * Returned if oid does not specify any valid object type.
2227 *******************************************************************************
2229 MP_STATUS
MP_EnablePath(
2232 MP_EnablePathFn PassFunc
;
2236 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PATH_LU
,
2237 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2241 (void) pthread_mutex_lock(&mp_lib_mutex
);
2243 index
= oid
.ownerId
- 1;
2244 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2245 PassFunc
= (MP_EnablePathFn
)
2246 dlsym(plugintable
[index
].hdlPlugin
,
2249 if (PassFunc
!= NULL
) {
2250 status
= PassFunc(oid
);
2252 status
= MP_STATUS_UNSUPPORTED
;
2255 status
= MP_STATUS_FAILED
;
2258 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2263 *******************************************************************************
2265 * Disables a path. This API may cause failover in a logical unit with
2266 * asymmetric access. This API may cause a logical unit to become unavailable.
2269 * The oid of the path.
2271 * @return An MP_STATUS indicating if the operation was successful or if
2272 * an error occurred.
2274 * @retval MP_STATUS_SUCCESS
2275 * Returned when the operation is successful.
2277 * @retval MP_STATUS_INVALID_PARAMETER
2278 * Returned if oid is NULL or specifies a memory area that is not
2281 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2282 * Returned if oid does not specify any valid object type.
2284 *******************************************************************************
2286 MP_STATUS
MP_DisablePath(
2289 MP_DisablePathFn PassFunc
;
2293 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PATH_LU
,
2294 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2298 (void) pthread_mutex_lock(&mp_lib_mutex
);
2300 index
= oid
.ownerId
- 1;
2301 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2302 PassFunc
= (MP_DisablePathFn
)
2303 dlsym(plugintable
[index
].hdlPlugin
,
2306 if (PassFunc
!= NULL
) {
2307 status
= PassFunc(oid
);
2309 status
= MP_STATUS_UNSUPPORTED
;
2312 status
= MP_STATUS_FAILED
;
2315 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2320 *******************************************************************************
2322 * Set the multipath logical unit s load balancing policy.
2324 * @param logicalUnitoid
2325 * The object ID of the multipath logical unit.
2327 * @param loadBanlance
2328 * The desired load balance policy for the specified logical unit.
2330 * @return An MP_STATUS indicating if the operation was successful or if
2331 * an error occurred.
2333 * @retval MP_STATUS_SUCCESS
2334 * Returned when the operation is successful.
2336 * @retval MP_STATUS_INVALID_PARAMETER
2337 * Returned if no MP_MULTIPATH_LOGICAL_UNIT associated with
2338 * @ref ligicalUnitrOid is found or invalid MP_LOAD_BALANCE_TYPE is
2341 * @retval MP_STATUS_FAILED
2342 * Returned when the specified loadBalance type cannot be handled
2345 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2346 * Returned if oid does not specify any valid object type.
2348 *******************************************************************************
2350 MP_STATUS
MP_SetLogicalUnitLoadBalanceType(
2351 MP_OID logicalUnitOid
,
2352 MP_LOAD_BALANCE_TYPE loadBalance
)
2354 MP_SetLogicalUnitLoadBalanceTypeFn PassFunc
;
2358 if ((status
= validate_object(logicalUnitOid
,
2359 MP_OBJECT_TYPE_MULTIPATH_LU
,
2360 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2364 (void) pthread_mutex_lock(&mp_lib_mutex
);
2366 index
= logicalUnitOid
.ownerId
- 1;
2367 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2368 PassFunc
= (MP_SetLogicalUnitLoadBalanceTypeFn
)
2369 dlsym(plugintable
[index
].hdlPlugin
,
2370 "MP_SetLogicalUnitLoadBalanceType");
2372 if (PassFunc
!= NULL
) {
2373 status
= PassFunc(logicalUnitOid
, loadBalance
);
2375 status
= MP_STATUS_UNSUPPORTED
;
2378 status
= MP_STATUS_FAILED
;
2381 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2386 *******************************************************************************
2388 * Set the weight to be assigned to a particular path.
2391 * The object ID of the path logical unit.
2394 * weight that will be assigned to the path logical unit.
2396 * @return An MP_STATUS indicating if the operation was successful or if
2397 * an error occurred.
2399 * @retval MP_STATUS_SUCCESS
2400 * Returned when the operation is successful.
2402 * @retval MP_STATUS_OBJECT_NOT_FOUND
2403 * Returned when the MP Path specified by the PathOid could not be
2406 * @retval MP_STATUS_UNSUPPORTED
2407 * Returned when the implementation does not support the API
2409 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2410 * Returned if oid does not specify any valid object type.
2412 * @retval MP_STATUS_FAILED
2413 * Returned when the operation failed.
2415 * @retval MP_STATUS_PATH_NONOPERATIONAL
2416 * Returned when the driver cannot communicate through selected path.
2418 * @retval MP_STATUS_INVALID_WEIGHT
2419 * Returned when the weight parameter is greater than the plugin's
2420 * maxWeight property.
2422 *******************************************************************************
2424 MP_STATUS
MP_SetPathWeight(
2428 MP_SetPathWeightFn PassFunc
;
2432 if ((status
= validate_object(pathOid
, MP_OBJECT_TYPE_PATH_LU
,
2433 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2437 (void) pthread_mutex_lock(&mp_lib_mutex
);
2439 index
= pathOid
.ownerId
- 1;
2440 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2441 PassFunc
= (MP_SetPathWeightFn
)
2442 dlsym(plugintable
[index
].hdlPlugin
,
2443 "MP_SetPathWeight");
2445 if (PassFunc
!= NULL
) {
2446 status
= PassFunc(pathOid
, weight
);
2448 status
= MP_STATUS_UNSUPPORTED
;
2451 status
= MP_STATUS_FAILED
;
2454 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2459 *******************************************************************************
2461 * Set the default load balance policy for the plugin.
2464 * The object ID of the plugin
2466 * @param loadBalance
2467 * The desired default load balance policy for the specified plugin.
2469 * @return An MP_STATUS indicating if the operation was successful or if
2470 * an error occurred.
2472 * @retval MP_STATUS_SUCCESS
2473 * Returned when the operation is successful.
2475 * @retval MP_STATUS_OBJECT_NOT_FOUND
2476 * Returned when the the plugin specified by @ref oid could not be
2479 * @retval MP_STATUS_INVALID_PARAMETER
2480 * Returned if the oid of the object is not valid.
2482 * @retval MP_STATUS_UNSUPPORTED
2483 * Returned when the implementation does not support the API
2485 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2486 * Returned if oid does not specify any valid object type.
2488 * @retval MP_STATUS_FAILED
2489 * Returned when the specified loadBalance type cannot be handled
2492 *******************************************************************************
2494 MP_STATUS
MP_SetPluginLoadBalanceType(
2496 MP_LOAD_BALANCE_TYPE loadBalance
)
2498 MP_SetPluginLoadBalanceTypePluginFn PassFunc
;
2502 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2503 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2507 (void) pthread_mutex_lock(&mp_lib_mutex
);
2509 index
= oid
.ownerId
- 1;
2510 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2511 PassFunc
= (MP_SetPluginLoadBalanceTypePluginFn
)
2512 dlsym(plugintable
[index
].hdlPlugin
,
2513 "MP_SetPluginLoadBalanceTypePlugin");
2515 if (PassFunc
!= NULL
) {
2516 status
= PassFunc(loadBalance
);
2518 status
= MP_STATUS_UNSUPPORTED
;
2521 status
= MP_STATUS_FAILED
;
2524 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2529 *******************************************************************************
2531 * Set the failback polling rates. Setting both rates to zero disables polling.
2534 * The object ID of the plugin or multipath lu.
2536 * @param pollingRate
2537 * The value to be set in MP_PLUGIN_PROPERTIES currentPollingRate.or
2538 * MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES pollingRate.
2540 * @return An MP_STATUS indicating if the operation was successful or if
2541 * an error occurred.
2543 * @retval MP_STATUS_SUCCESS
2544 * Returned when the operation is successful.
2546 * @retval MP_STATUS_OBJECT_NOT_FOUND
2547 * Returned when the the plugin specified by @ref oid could not be
2550 * @retval MP_STATUS_INVALID_PARAMETER
2551 * Returned if one of the polling values is outside the range
2552 * supported by the driver.
2554 * @retval MP_STATUS_UNSUPPORTED
2555 * Returned when the implementation does not support the API
2557 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2558 * Returned if oid does not specify any valid object type.
2560 *******************************************************************************
2562 MP_STATUS
MP_SetFailbackPollingRate(
2564 MP_UINT32 pollingRate
)
2569 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2570 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2571 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2572 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
2576 (void) pthread_mutex_lock(&mp_lib_mutex
);
2578 index
= oid
.ownerId
- 1;
2579 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2580 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
2581 MP_SetFailbackPollingRatePluginFn PassFunc
;
2582 PassFunc
= (MP_SetFailbackPollingRatePluginFn
)
2583 dlsym(plugintable
[index
].hdlPlugin
,
2584 "MP_SetFailbackPollingRatePlugin");
2586 if (PassFunc
!= NULL
) {
2587 status
= PassFunc(pollingRate
);
2589 status
= MP_STATUS_UNSUPPORTED
;
2591 } else if (oid
.objectType
== MP_OBJECT_TYPE_MULTIPATH_LU
) {
2592 MP_SetFailbackPollingRateLuFn PassFunc
;
2593 PassFunc
= (MP_SetFailbackPollingRateLuFn
)
2594 dlsym(plugintable
[index
].hdlPlugin
,
2595 "MP_SetFailbackPollingRateLu");
2597 if (PassFunc
!= NULL
) {
2598 status
= PassFunc(oid
, pollingRate
);
2600 status
= MP_STATUS_UNSUPPORTED
;
2603 status
= MP_STATUS_INVALID_PARAMETER
;
2607 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2612 *******************************************************************************
2614 * Set the probing polling rates. Setting both rates to zero disables polling.
2617 * The object ID of either the plugin or a multipath logical unit.
2619 * @param pollingRate
2620 * The value to be set in MP_PLUGIN_PROPERTIES current pollingRate or
2621 * MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES pollingRate.
2623 * @return An MP_STATUS indicating if the operation was successful or if
2624 * an error occurred.
2626 * @retval MP_STATUS_SUCCESS
2627 * Returned when the operation is successful.
2629 * @retval MP_STATUS_OBJECT_NOT_FOUND
2630 * Returned when the the plugin specified by @ref oid could not be
2633 * @retval MP_STATUS_INVALID_PARAMETER
2634 * Returned if one of the polling values is outside the range
2635 * supported by the driver.
2637 * @retval MP_STATUS_UNSUPPORTED
2638 * Returned when the implementation does not support the API
2640 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2641 * Returned if oid does not specify any valid object type.
2643 *******************************************************************************
2645 MP_STATUS
MP_SetProbingPollingRate(
2647 MP_UINT32 pollingRate
)
2652 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2653 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2654 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2655 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
2659 (void) pthread_mutex_lock(&mp_lib_mutex
);
2661 index
= oid
.ownerId
- 1;
2662 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2663 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
2664 MP_SetProbingPollingRatePluginFn PassFunc
;
2665 PassFunc
= (MP_SetProbingPollingRatePluginFn
)
2666 dlsym(plugintable
[index
].hdlPlugin
,
2667 "MP_SetProbingPollingRatePlugin");
2669 if (PassFunc
!= NULL
) {
2670 status
= PassFunc(pollingRate
);
2672 status
= MP_STATUS_UNSUPPORTED
;
2674 } else if (oid
.objectType
== MP_OBJECT_TYPE_MULTIPATH_LU
) {
2675 MP_SetProbingPollingRateLuFn PassFunc
;
2676 PassFunc
= (MP_SetProbingPollingRateLuFn
)
2677 dlsym(plugintable
[index
].hdlPlugin
,
2678 "MP_SetProbingPollingRateLu");
2680 if (PassFunc
!= NULL
) {
2681 status
= PassFunc(oid
, pollingRate
);
2683 status
= MP_STATUS_UNSUPPORTED
;
2686 status
= MP_STATUS_INVALID_PARAMETER
;
2690 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2695 *******************************************************************************
2697 * Set proprietary properties in supported object instances.
2700 * The object ID of MP_LOAD_BALANCE_PROPRIETARY_TYPE, MP_PLUGIN_PROPERTIES
2701 * or MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES.
2704 * The number of valid items in pPropertyList.
2706 * @param pPropertyList
2707 * A pointer to an array of property name/value pairs. This array must
2708 * contain the same number of elements as count.
2710 * @return An MP_STATUS indicating if the operation was successful or if
2711 * an error occurred.
2713 * @retval MP_STATUS_SUCCESS
2714 * Returned when the operation is successful.
2716 * @retval MP_STATUS_OBJECT_NOT_FOUND
2717 * Returned when the the plugin specified by @ref oid could not be
2720 * @retval MP_STATUS_INVALID_PARAMETER
2721 * Returned if one of the polling values is outside the range
2722 * supported by the driver.
2724 * @retval MP_STATUS_UNSUPPORTED
2725 * Returned when the implementation does not support the API
2727 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2728 * Returned if oid does not specify any valid object type.
2730 *******************************************************************************
2732 MP_STATUS
MP_SetProprietaryProperties(
2735 MP_PROPRIETARY_PROPERTY
*pPropertyList
)
2737 MP_SetProprietaryPropertiesFn PassFunc
;
2741 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2742 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2743 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2744 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2745 ((status
= validate_object(oid
, MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE
,
2746 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
2750 (void) pthread_mutex_lock(&mp_lib_mutex
);
2752 index
= oid
.ownerId
- 1;
2753 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2754 PassFunc
= (MP_SetProprietaryPropertiesFn
)
2755 dlsym(plugintable
[index
].hdlPlugin
,
2756 "MP_SetProprietaryProperties");
2758 if (PassFunc
!= NULL
) {
2759 status
= PassFunc(oid
, count
, pPropertyList
);
2761 status
= MP_STATUS_UNSUPPORTED
;
2764 status
= MP_STATUS_FAILED
;
2767 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2772 *******************************************************************************
2774 * Set the access state for a list of target port groups. This allows
2775 * a client to force a failover or failback to a desired set of target port
2779 * The object ID of the logical unit where the command is sent.
2782 * The number of valid items in the pTpgStateList.
2784 * @param pTpgStateList
2785 * A pointer to an array of TPG/access-state values. This array must
2786 * contain the same number of elements as @ref count.
2788 * @return An MP_STATUS indicating if the operation was successful or if
2789 * an error occurred.
2791 * @retval MP_STATUS_SUCCESS
2792 * Returned when the operation is successful.
2794 * @retval MP_STATUS_OBJECT_NOT_FOUND
2795 * Returned when the MP_MULTIPATH_LOGICAL_UNIT associated with @ref
2796 * oid could not be found.
2798 * @retval MP_STATUS_INVALID_PARAMETER
2799 * Returned if pTpgStateList is null or if one of the TPGs referenced
2800 * in the list is not associated with the specified MP logical unit.
2802 * @retval MP_STATUS_UNSUPPORTED
2803 * Returned when the implementation does not support the API
2805 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2806 * Returned if oid does not specify any valid object type.
2808 * @retval MP_STATUS_ACCESS_STATE_INVALID
2809 * Returned if the target device returns a status indicating the caller
2810 * is attempting to establish an illegal combination of access states.
2812 * @retval MP_STATUS_FAILED
2813 * Returned if the underlying interface failed the commend for some
2814 * reason other than MP_STATUS_ACCESS_STATE_INVALID
2816 *******************************************************************************
2818 MP_STATUS
MP_SetTPGAccess(
2821 MP_TPG_STATE_PAIR
*pTpgStateList
)
2823 MP_SetTPGAccessFn PassFunc
;
2827 if ((status
= validate_object(luOid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2828 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2832 (void) pthread_mutex_lock(&mp_lib_mutex
);
2834 index
= luOid
.ownerId
- 1;
2835 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2836 PassFunc
= (MP_SetTPGAccessFn
)
2837 dlsym(plugintable
[index
].hdlPlugin
,
2840 if (PassFunc
!= NULL
) {
2841 status
= PassFunc(luOid
, count
, pTpgStateList
);
2843 status
= MP_STATUS_UNSUPPORTED
;
2846 status
= MP_STATUS_FAILED
;
2849 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2854 *******************************************************************************
2856 * Registers a client function that is to be called
2857 * whenever the property of an an object changes.
2860 * A pointer to an MP_OBJECT_PROPERTY_FN function defined by the
2861 * client. On successful return this function will be called to
2862 * inform the client of objects that have had one or more properties
2866 * The type of object the client wishes to deregister for
2867 * property change callbacks. If null, then all objects types are
2870 * @param pCallerData
2871 * A pointer that is passed to the callback routine with each event.
2872 * This may be used by the caller to correlate the event to source of
2875 * @return An MP_STATUS indicating if the operation was successful or if
2876 * an error occurred.
2878 * @retval MP_STATUS_SUCCESS
2879 * Returned when the operation is successful.
2881 * @retval MP_STATUS_INVALID_PARAMETER
2882 * Returned if pClientFn is NULL or specifies a memory area
2883 * that is not executable.
2885 * @retval MP_STATUS_FN_REPLACED
2886 * Returned when an existing client function is replaced with the one
2887 * specified in pClientFn.
2889 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2890 * Returned if oid does not specify any valid object type.
2892 *******************************************************************************
2894 MP_STATUS
MP_RegisterForObjectPropertyChanges(
2895 MP_OBJECT_PROPERTY_FN pClientFn
,
2896 MP_OBJECT_TYPE objectType
,
2900 MP_RegisterForObjectPropertyChangesPluginFn PassFunc
;
2905 if (pClientFn
== NULL
) {
2906 return (MP_STATUS_INVALID_PARAMETER
);
2909 if (objectType
> MP_OBJECT_TYPE_MAX
) {
2910 return (MP_STATUS_INVALID_OBJECT_TYPE
);
2913 if (!(is_zero_oid(pluginOid
))) {
2914 if ((status
= validate_object(pluginOid
, MP_OBJECT_TYPE_PLUGIN
,
2915 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2920 (void) pthread_mutex_lock(&mp_lib_mutex
);
2922 if (is_zero_oid(pluginOid
)) {
2923 for (i
= 0; i
< number_of_plugins
; i
++) {
2924 if (plugintable
[i
].hdlPlugin
!= NULL
) {
2925 PassFunc
= (MP_RegisterForObjectPropertyChangesPluginFn
)
2926 dlsym(plugintable
[i
].hdlPlugin
,
2927 "MP_RegisterForObjectPropertyChangesPlugin");
2930 if (PassFunc
!= NULL
) {
2932 PassFunc(pClientFn
, objectType
, pCallerData
);
2933 /* ignore an error and continue */
2937 index
= pluginOid
.ownerId
- 1;
2938 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2939 PassFunc
= (MP_RegisterForObjectPropertyChangesPluginFn
)
2940 dlsym(plugintable
[index
].hdlPlugin
,
2941 "MP_RegisterForObjectPropertyChangesPlugin");
2944 if (PassFunc
!= NULL
) {
2945 status
= PassFunc(pClientFn
, objectType
, pCallerData
);
2948 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2953 *******************************************************************************
2955 * Deregisters a previously registered client function that is to be invoked
2956 * whenever an object's property changes.
2959 * A pointer to an MP_OBJECT_PROPERTY_FN function defined by the
2960 * client that was previously registered using
2961 * the MP_RegisterForObjectPropertyChanges API. On successful return
2962 * this function will no longer be called to inform the client of
2963 * object property changes.
2966 * The type of object the client wishes to deregister for
2967 * property change callbacks. If null, then all objects types are
2970 * @return An MP_STATUS indicating if the operation was successful or if
2971 * an error occurred.
2973 * @retval MP_STATUS_SUCCESS
2974 * Returned when the operation is successful.
2976 * @retval MP_STATUS_INVALID_PARAMETER
2977 * Returned if pClientFn is NULL or specifies a memory area
2978 * that is not executable.
2980 * @retval MP_STATUS_UNKNOWN_FN
2981 * Returned if pClientFn is not the same as the previously registered
2984 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2985 * Returned if oid does not specify any valid object type.
2987 * @retval MP_STATUS_FAILED
2988 * Returned if pClientFn deregistration is not possible at this time.
2990 *******************************************************************************
2992 MP_STATUS
MP_DeregisterForObjectPropertyChanges(
2993 MP_OBJECT_PROPERTY_FN pClientFn
,
2994 MP_OBJECT_TYPE objectType
,
2997 MP_DeregisterForObjectPropertyChangesPluginFn PassFunc
;
3002 if (pClientFn
== NULL
) {
3003 return (MP_STATUS_INVALID_PARAMETER
);
3006 if (objectType
> MP_OBJECT_TYPE_MAX
) {
3007 return (MP_STATUS_INVALID_OBJECT_TYPE
);
3010 if (!(is_zero_oid(pluginOid
))) {
3011 if ((status
= validate_object(pluginOid
, MP_OBJECT_TYPE_PLUGIN
,
3012 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
3017 (void) pthread_mutex_lock(&mp_lib_mutex
);
3019 if (is_zero_oid(pluginOid
)) {
3020 for (i
= 0; i
< number_of_plugins
; i
++) {
3021 if (plugintable
[i
].hdlPlugin
!= NULL
) {
3022 PassFunc
= (MP_DeregisterForObjectPropertyChangesPluginFn
)
3023 dlsym(plugintable
[i
].hdlPlugin
,
3024 "MP_DeregisterForObjectPropertyChangesPlugin");
3027 if (PassFunc
!= NULL
) {
3028 status
= PassFunc(pClientFn
, objectType
);
3032 index
= pluginOid
.ownerId
- 1;
3033 if (plugintable
[index
].hdlPlugin
!= NULL
) {
3034 PassFunc
= (MP_DeregisterForObjectPropertyChangesPluginFn
)
3035 dlsym(plugintable
[index
].hdlPlugin
,
3036 "MP_DeregisterForObjectPropertyChangesPlugin");
3039 if (PassFunc
!= NULL
) {
3040 status
= PassFunc(pClientFn
, objectType
);
3043 (void) pthread_mutex_unlock(&mp_lib_mutex
);
3048 *******************************************************************************
3050 * Registers a client function that is to be called
3051 * whenever a high level object appears or disappears.
3054 * A pointer to an MP_OBJECT_VISIBILITY_FN function defined by the
3055 * client. On successful return this function will be called to
3056 * inform the client of objects whose visibility has changed.
3059 * The type of object the client wishes to deregister for
3060 * property change callbacks. If null, then all objects types are
3063 * @param pCallerData
3064 * A pointer that is passed to the callback routine with each event.
3065 * This may be used by the caller to correlate the event to source of
3068 * @return An MP_STATUS indicating if the operation was successful or if
3069 * an error occurred.
3071 * @retval MP_STATUS_SUCCESS
3072 * Returned when the operation is successful.
3074 * @retval MP_STATUS_INVALID_PARAMETER
3075 * Returned if pClientFn is NULL or specifies a memory area
3076 * that is not executable.
3078 * @retval MP_STATUS_FN_REPLACED
3079 * Returned when an existing client function is replaced with the one
3080 * specified in pClientFn.
3082 * @retval MP_STATUS_INVALID_OBJECT_TYPE
3083 * Returned if objectType does not specify any valid object type.
3085 *******************************************************************************
3087 MP_STATUS
MP_RegisterForObjectVisibilityChanges(
3088 MP_OBJECT_VISIBILITY_FN pClientFn
,
3089 MP_OBJECT_TYPE objectType
,
3093 MP_RegisterForObjectVisibilityChangesPluginFn PassFunc
;
3098 if (pClientFn
== NULL
) {
3099 return (MP_STATUS_INVALID_PARAMETER
);
3102 if (objectType
> MP_OBJECT_TYPE_MAX
) {
3103 return (MP_STATUS_INVALID_OBJECT_TYPE
);
3106 if (!(is_zero_oid(pluginOid
))) {
3107 if ((status
= validate_object(pluginOid
, MP_OBJECT_TYPE_PLUGIN
,
3108 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
3113 (void) pthread_mutex_lock(&mp_lib_mutex
);
3115 if (is_zero_oid(pluginOid
)) {
3116 for (i
= 0; i
< number_of_plugins
; i
++) {
3117 if (plugintable
[i
].hdlPlugin
!= NULL
) {
3118 PassFunc
= (MP_RegisterForObjectVisibilityChangesPluginFn
)
3119 dlsym(plugintable
[i
].hdlPlugin
,
3120 "MP_RegisterForObjectVisibilityChangesPlugin");
3123 if (PassFunc
!= NULL
) {
3124 status
= PassFunc(pClientFn
, objectType
, pCallerData
);
3125 /* ignore an error and continue. */
3129 index
= pluginOid
.ownerId
- 1;
3130 if (plugintable
[index
].hdlPlugin
!= NULL
) {
3131 PassFunc
= (MP_RegisterForObjectVisibilityChangesPluginFn
)
3132 dlsym(plugintable
[index
].hdlPlugin
,
3133 "MP_RegisterForObjectVisibilityChangesPlugin");
3136 if (PassFunc
!= NULL
) {
3137 status
= PassFunc(pClientFn
, objectType
, pCallerData
);
3140 (void) pthread_mutex_unlock(&mp_lib_mutex
);
3146 *******************************************************************************
3148 * Deregisters a previously registered client function that is to be invoked
3149 * whenever a high level object appears or disappears.
3152 * A pointer to an MP_OBJECT_VISIBILITY_FN function defined by the
3153 * client that was previously registered using
3154 * the MP_RegisterForObjectVisibilityChanges API. On successful return
3155 * this function will no longer be called to inform the client of
3156 * object property changes.
3159 * The type of object the client wishes to deregister for visibility
3160 * change callbacks. If null, then all objects types are
3163 * @return An MP_STATUS indicating if the operation was successful or if
3164 * an error occurred.
3166 * @retval MP_STATUS_SUCCESS
3167 * Returned when the operation is successful.
3169 * @retval MP_STATUS_INVALID_PARAMETER
3170 * Returned if pClientFn is NULL or specifies a memory area
3171 * that is not executable.
3173 * @retval MP_STATUS_UNKNOWN_FN
3174 * Returned if pClientFn is not the same as the previously registered
3177 * @retval MP_STATUS_INVALID_OBJECT_TYPE
3178 * Returned if objectType does not specify any valid object type.
3180 * @retval MP_STATUS_FAILED
3181 * Returned if pClientFn deregistration is not possible at this time.
3183 *******************************************************************************
3185 MP_STATUS
MP_DeregisterForObjectVisibilityChanges(
3186 MP_OBJECT_VISIBILITY_FN pClientFn
,
3187 MP_OBJECT_TYPE objectType
,
3190 MP_DeregisterForObjectVisibilityChangesPluginFn PassFunc
;
3195 if (pClientFn
== NULL
) {
3196 return (MP_STATUS_INVALID_PARAMETER
);
3199 if (objectType
> MP_OBJECT_TYPE_MAX
) {
3200 return (MP_STATUS_INVALID_OBJECT_TYPE
);
3203 if (!(is_zero_oid(pluginOid
))) {
3204 if ((status
= validate_object(pluginOid
, MP_OBJECT_TYPE_PLUGIN
,
3205 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
3210 (void) pthread_mutex_lock(&mp_lib_mutex
);
3212 if (is_zero_oid(pluginOid
)) {
3213 for (i
= 0; i
< number_of_plugins
; i
++) {
3214 if (plugintable
[i
].hdlPlugin
!= NULL
) {
3215 PassFunc
= (MP_DeregisterForObjectVisibilityChangesPluginFn
)
3216 dlsym(plugintable
[i
].hdlPlugin
,
3217 "MP_DeregisterForObjectVisibilityChangesPlugin");
3218 if (PassFunc
!= NULL
) {
3219 status
= PassFunc(pClientFn
, objectType
);
3224 index
= pluginOid
.ownerId
- 1;
3225 if (plugintable
[index
].hdlPlugin
!= NULL
) {
3226 PassFunc
= (MP_DeregisterForObjectVisibilityChangesPluginFn
)
3227 dlsym(plugintable
[index
].hdlPlugin
,
3228 "MP_DeregisterForObjectVisibilityChangesPlugin");
3229 if (PassFunc
!= NULL
) {
3230 status
= PassFunc(pClientFn
, objectType
);
3235 (void) pthread_mutex_unlock(&mp_lib_mutex
);
3240 *******************************************************************************
3242 * Compare two Oids for equality to see whether they refer to the same object.
3250 * @return An MP_STATUS indicating if the operation was successful or if
3251 * an error occurred.
3253 * @retval MP_STATUS_SUCCESS
3254 * Returned when the two Oids do refer to the same object.
3256 * @retval MP_STATUS_FAILED
3257 * Returned if the Oids don't compare.
3259 *******************************************************************************
3261 MP_STATUS
MP_CompareOIDs(
3265 if ((oid1
.objectType
== oid2
.objectType
) && (oid1
.ownerId
== oid2
.ownerId
)
3266 && (oid1
.objectSequenceNumber
== oid2
.objectSequenceNumber
)) {
3267 return (MP_STATUS_SUCCESS
);
3269 return (MP_STATUS_FAILED
);
3274 *******************************************************************************
3276 * Frees memory returned by an MP API.
3279 * A pointer to the memory returned by an MP API. On successful
3280 return, the allocated memory is freed.
3282 * @return An MP_STATUS indicating if the operation was successful or if
3283 * an error occurred.
3285 * @retval MP_STATUS_SUCCESS
3286 * Returned when pPluginId is deregistered successfully.
3288 * @retval MP_STATUS_INVALID_PARAMETER
3289 * Returned if pMemory is NULL or specifies a memory area to which
3290 * data cannot be written.
3292 *******************************************************************************
3294 MP_STATUS
MP_FreeOidList(MP_OID_LIST
*pOidList
)
3296 if (pOidList
== NULL
) {
3297 return (MP_STATUS_INVALID_PARAMETER
);
3302 return (MP_STATUS_SUCCESS
);
3305 static MP_CHAR
*HDR
=
3307 "# This file contains names and references to MP API plugin libraries\n"
3309 "# Do NOT manually edit this file\n"
3313 "# <library ID> <library pathname>\n"
3316 #define CLEANUP_N_RET(fd, ret) \
3317 if (lock_register(fd, F_SETLK, F_UNLCK, 0, SEEK_SET, 0) < 0) { \
3319 return (MP_STATUS_FAILED); \
3325 * This function sets an advisory lock on the file pointed to by the argument
3326 * fd, which is a file descriptor. The lock is set using fcntl() which uses
3330 lock_register(int fd
, int cmd
, int type
, off_t offset
, int whence
, off_t len
)
3335 lock
.l_start
= offset
;
3336 lock
.l_whence
= whence
;
3339 return (fcntl(fd
, cmd
, &lock
));
3343 * This function searches for "srch_str" (of length "slen") in "buf" (of length
3344 * "buflen"). If it is not found, "write_offset" has the offset in "buf" where
3345 * "srch_str" would have to be added in "buf". If "srch_str" is found in "buf",
3346 * "write_offset" has its offset in "buf"
3349 * buf - buffer to search in
3350 * buflen - length of buffer
3351 * srch_id - id to search
3352 * id_len - length of srch_id
3353 * write_offset - Set in function on exit
3354 * - It is the offset in buf where srch_str is or should be
3355 * bytes_left - Set in function on exit
3356 * - It is the # of bytes left beyond write_offset in buf
3358 * Zero - "srch_id" found in "buf"... "write_offset" has offset in "buf"
3359 * != 0 - "srch_str" NOT found in "buf" ... "write_offset" points to the end of
3363 search_line(MP_CHAR
*buf
, size_t buflen
, MP_CHAR
*srch_id
, size_t id_len
,
3364 int *write_offset
, int *bytes_left
)
3366 int retval
, sizeof_conf_hdr
= strlen(HDR
);
3367 MP_CHAR
*sol
; /* Pointer to Start-Of-Line */
3368 MP_CHAR
*cur_pos
; /* current position */
3370 *bytes_left
= buflen
;
3373 if (buf
== NULL
|| buflen
<= 0)
3376 if (srch_id
== NULL
|| id_len
<= 0)
3379 sol
= cur_pos
= buf
;
3382 * mp conf file should not be edited but takes care of
3383 * any extra white space when parsing the line.
3385 * The line should have id + delimiter + name + newline.
3387 while (*bytes_left
>= (id_len
+ 3)) {
3388 /* skip leading blank or space. */
3389 while ((*cur_pos
== ' ') || (*cur_pos
== '\t')) {
3393 if (strncmp(cur_pos
, srch_id
, id_len
) == 0) {
3397 while (*cur_pos
!= '\n') {
3400 *write_offset
= (sol
- buf
);
3401 *bytes_left
= buflen
- ((cur_pos
+ 1) - buf
);
3404 /* move to the next line */
3405 while (*cur_pos
!= '\n') {
3408 *bytes_left
= buflen
- ((cur_pos
+ 1) - buf
);
3410 sol
= cur_pos
= cur_pos
+ 1;
3413 /* Given strings are not found. */
3414 *write_offset
= buflen
;
3419 *******************************************************************************
3421 * Registers a plugin with common library. The implementation of this routine
3422 * is based on configuration file /etc/mpapi.conf that contains a list of
3426 * A pointer to the key name shall be the reversed domain name of
3427 * the vendor followed by followed by the vendor specific name for
3428 * the plugin that uniquely identifies the plugin. Should be NULL
3432 * The full path to the plugin library.
3433 * Should be NULL terminated.
3435 * @return An MP_STATUS indicating if the operation was successful or if
3436 * an error occurred.
3438 * @retval MP_STATUS_SUCCESS
3439 * Returned when pPluginId is deregistered successfully.
3441 * @retval MP_STATUS_INVALID_PARAMETER
3442 * Returned if pPluginId is NULL or specifies a memory area that
3443 * is not executable.
3445 * @retval MP_STATUS_FAILED
3446 * Returned if pClientFn deregistration is not possible at this time.
3448 *******************************************************************************
3450 MP_STATUS
MP_RegisterPlugin(
3451 MP_WCHAR
*pPluginId
,
3454 int mpconf
, bytes_left
, write_offset
;
3455 MP_CHAR fullline
[MAX_LINE_SIZE
]; /* Full line to add to mpapi.conf */
3456 MP_CHAR
*mpconf_buf
;
3457 MP_CHAR pluginid
[MAX_NAME_SIZE
];
3458 char systemPath
[MAX_NAME_SIZE
], mpConfFilePath
[MAX_NAME_SIZE
];
3459 MP_UINT32 new_file_flag
= 0;
3460 MP_UINT32 sizeof_conf_hdr
= strlen(HDR
);
3463 if ((pPluginId
== NULL
) || (pFileName
== NULL
)) {
3464 return (MP_STATUS_INVALID_PARAMETER
);
3467 if (stat(pFileName
, &stbuf
) != 0) {
3468 return (MP_STATUS_INVALID_PARAMETER
);
3471 if (wcstombs(pluginid
, pPluginId
, MAX_NAME_SIZE
) != wcslen(pPluginId
)) {
3472 return (MP_STATUS_INVALID_PARAMETER
);
3476 strncpy(fullline
, pluginid
, MAX_NAME_SIZE
);
3478 strncat(fullline
, "\t", MAX_LINE_SIZE
- strlen(pluginid
));
3479 strncat(fullline
, pFileName
, MAX_LINE_SIZE
- strlen(pluginid
) - 1);
3480 /* add a new line. */
3481 strncat(fullline
, "\n",
3482 MAX_LINE_SIZE
- strlen(pluginid
) - strlen(pFileName
) -1);
3484 /* Open configuration file from known location */
3485 strncpy(mpConfFilePath
, "/etc/mpapi.conf", MAX_NAME_SIZE
);
3487 if ((chmod(mpConfFilePath
, S_IRUSR
|S_IRGRP
|S_IROTH
) == -1) &&
3488 (errno
== ENOENT
)) {
3492 if ((mpconf
= open(mpConfFilePath
, O_RDWR
| O_CREAT
)) == -1) {
3493 return (MP_STATUS_FAILED
);
3496 if (fchmod(mpconf
, S_IRUSR
| S_IRGRP
| S_IROTH
) < 0) {
3498 return (MP_STATUS_FAILED
);
3501 if (lock_register(mpconf
, F_SETLKW
, F_WRLCK
, 0, SEEK_SET
, 0) < 0) {
3503 return (MP_STATUS_FAILED
);
3506 if (fstat(mpconf
, &stbuf
) == -1) {
3507 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3510 if ((new_file_flag
) || (stbuf
.st_size
== 0)) {
3511 if (write(mpconf
, HDR
, sizeof_conf_hdr
) !=
3513 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3516 if (pwrite(mpconf
, fullline
, strlen(fullline
),
3519 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3521 CLEANUP_N_RET(mpconf
, MP_STATUS_SUCCESS
);
3524 if ((mpconf_buf
= (MP_CHAR
*)mmap(0, stbuf
.st_size
,
3525 PROT_READ
| PROT_WRITE
,
3526 MAP_SHARED
, mpconf
, 0)) == MAP_FAILED
) {
3527 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3530 if (search_line(mpconf_buf
, stbuf
.st_size
,
3531 pluginid
, strlen(pluginid
), &write_offset
, &bytes_left
) == 0) {
3532 /* found a match. */
3533 munmap((void *)mpconf_buf
, stbuf
.st_size
);
3534 CLEANUP_N_RET(mpconf
, MP_STATUS_SUCCESS
);
3536 munmap((void *)mpconf_buf
, stbuf
.st_size
);
3537 /* append the fullline to the mpconf. */
3538 if (pwrite(mpconf
, fullline
, strlen(fullline
),
3541 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3543 CLEANUP_N_RET(mpconf
, MP_STATUS_SUCCESS
);
3549 *******************************************************************************
3551 * Deregisters a plugin from the common library. This routine is based on
3552 * configuration file /etc/mpapi.conf that contains a list of plugin libraries.
3555 * A pointer to a Plugin ID previously registered using
3556 * the MP_RegisterPlugin API..
3558 * @return An MP_STATUS indicating if the operation was successful or if
3559 * an error occurred.
3561 * @retval MP_STATUS_SUCCESS
3562 * Returned when pPluginId is deregistered successfully.
3564 * @retval MP_STATUS_INVALID_PARAMETER
3565 * Returned if pPluginId is NULL or specifies a memory area that
3566 * is not executable.
3568 * @retval MP_STATUS_FAILED
3569 * Returned if pClientFn deregistration is not possible at this time.
3571 *******************************************************************************
3573 MP_STATUS
MP_DeregisterPlugin(
3574 MP_WCHAR
*pPluginId
)
3576 int mpconf
, tmp_mpconf
, bytes_left
, write_offset
;
3577 char systemPath
[MAX_NAME_SIZE
], mpConfFilePath
[MAX_NAME_SIZE
],
3578 tmp_mpConfFilePath
[MAX_NAME_SIZE
+ sizeof(pid_t
)];
3579 MP_CHAR pluginid
[MAX_NAME_SIZE
];
3580 MP_CHAR
*mpconf_buf
;
3581 MP_UINT32 sizeof_conf_hdr
= strlen(HDR
);
3584 if (pPluginId
== NULL
) {
3585 return (MP_STATUS_INVALID_PARAMETER
);
3588 if (wcstombs(pluginid
, pPluginId
, MAX_NAME_SIZE
) != wcslen(pPluginId
)) {
3589 return (MP_STATUS_INVALID_PARAMETER
);
3592 /* Open configuration file from known location */
3593 strncpy(mpConfFilePath
, "/etc/mpapi.conf", MAX_NAME_SIZE
);
3595 if ((chmod(mpConfFilePath
, S_IRUSR
|S_IRGRP
|S_IROTH
) == -1) &&
3596 (errno
== ENOENT
)) {
3598 return (MP_STATUS_UNKNOWN_FN
);
3601 if ((mpconf
= open(mpConfFilePath
, O_RDWR
)) == -1) {
3602 return (MP_STATUS_FAILED
);
3605 if (fchmod(mpconf
, S_IRUSR
| S_IRGRP
| S_IROTH
) < 0) {
3607 return (MP_STATUS_FAILED
);
3610 if (lock_register(mpconf
, F_SETLKW
, F_WRLCK
, 0, SEEK_SET
, 0) < 0) {
3612 return (MP_STATUS_FAILED
);
3615 if (fstat(mpconf
, &stbuf
) == -1) {
3616 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3619 if (stbuf
.st_size
== 0) {
3620 CLEANUP_N_RET(mpconf
, MP_STATUS_SUCCESS
);
3623 if ((mpconf_buf
= (MP_CHAR
*)mmap(0, stbuf
.st_size
,
3624 PROT_READ
| PROT_WRITE
,
3625 MAP_SHARED
, mpconf
, 0)) == MAP_FAILED
) {
3626 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3629 if (search_line(mpconf_buf
, stbuf
.st_size
, pluginid
, strlen(pluginid
),
3630 &write_offset
, &bytes_left
) != 0) {
3631 munmap((void *)mpconf_buf
, stbuf
.st_size
);
3632 CLEANUP_N_RET(mpconf
, MP_STATUS_UNKNOWN_FN
);
3636 * construct temp file name using pid.
3638 (void) snprintf(tmp_mpConfFilePath
, MAX_NAME_SIZE
,
3639 "%s%ld", "/etc/mpapi.conf", getpid());
3641 if ((tmp_mpconf
= open(tmp_mpConfFilePath
,
3642 O_RDWR
|O_CREAT
|O_TRUNC
, S_IRUSR
| S_IWUSR
)) < 0) {
3643 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3646 if (write(tmp_mpconf
, mpconf_buf
, write_offset
) != write_offset
) {
3648 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3651 if (pwrite(tmp_mpconf
, mpconf_buf
+ (stbuf
.st_size
- bytes_left
),
3652 bytes_left
, write_offset
) != bytes_left
) {
3654 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3658 munmap((void *)mpconf_buf
, stbuf
.st_size
);
3660 /* rename temp file to mpConfFile before unlock and close. */
3661 if (rename(tmp_mpConfFilePath
, mpConfFilePath
) != 0) {
3662 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3664 CLEANUP_N_RET(mpconf
, MP_STATUS_SUCCESS
);