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
;
266 wcsncpy(plugintable
[i
].pluginName
,
267 name
, MAX_NAME_SIZE
);
268 strncpy(plugintable
[i
].pluginPath
,
269 path
, MAX_NAME_SIZE
);
271 plugintable
[i
].ownerId
= i
+ 1;
273 PassFunc
= (InitializeFn
)
274 dlsym(plugintable
[i
].hdlPlugin
, "Initialize");
275 if (PassFunc
!= NULL
) {
276 status
= PassFunc(plugintable
[i
].ownerId
);
284 if (lock_register(fd_mpconf
, F_SETLK
, F_UNLCK
, 0, SEEK_SET
, 0) < 0) {
287 (void) pthread_mutex_unlock(&mp_lib_mutex
);
293 number_of_plugins
= i
;
294 (void) pthread_mutex_unlock(&mp_lib_mutex
);
298 ******************************************************************************
300 * Exit by calling Terminate routine of plugin libraries.
302 * Note: The build of libMPAPI.so should include a linker option to make this
303 * routine executed when it is unloaded.
305 ******************************************************************************
311 if(number_of_plugins
== -1)
314 (void) pthread_mutex_lock(&mp_lib_mutex
);
315 for (i
= 0; i
< number_of_plugins
; i
++) {
316 if (plugintable
[i
].hdlPlugin
!= NULL
) {
317 TerminateFn ExitPassFunc
;
319 ExitPassFunc
= (TerminateFn
)
320 dlsym(plugintable
[i
].hdlPlugin
, "Terminate");
322 if (ExitPassFunc
!= NULL
) {
326 /* Unload plugin from memory */
327 dlclose(plugintable
[i
].hdlPlugin
);
331 number_of_plugins
= -1;
333 (void) pthread_mutex_unlock(&mp_lib_mutex
);
334 (void) pthread_mutex_destroy(&mp_lib_mutex
);
338 ******************************************************************************
340 * Gets the properties of the MP API library that is being used.
343 * A pointer to an @ref MP_LIBRARY_PROPERTIES structure allocated by
344 * the caller. On successful return this structure will contain the
345 * properties of the MP library.
347 * @return An MP_STATUS indicating if the operation was successful or
348 * if an error occurred.
350 * @retval MP_STATUS_SUCCESS
351 * Returned if the library properties were successfully returned.
353 * @retval MP_STATUS_INVALID_PARAMETER Returned if @a pProps is NULL or
354 * specifies a memory area to which data cannot be written.
356 ******************************************************************************
358 MP_STATUS
MP_GetLibraryProperties(
359 MP_LIBRARY_PROPERTIES
*pProps
)
361 char mpPath
[MAX_NAME_SIZE
];
364 return MP_STATUS_INVALID_PARAMETER
;
367 /* Fill in properties */
368 if (mbstowcs(pProps
->buildTime
, BUILD_TIME
, 256) !=
369 strlen(BUILD_TIME
)) {
370 return (MP_STATUS_INVALID_PARAMETER
);
372 pProps
->supportedMpVersion
= LIBRARY_SUPPORTED_MP_VERSION
;
374 wcsncpy(pProps
->implementationVersion
,
375 LIBRARY_IMPLEMENTATION_VERSION
, MAX_NAME_SIZE
);
376 wcsncpy(pProps
->vendor
, LIBRARY_VENDOR
, MAX_NAME_SIZE
);
378 snprintf(pProps
->fileName
, MAX_NAME_SIZE
, "%s",
381 return MP_STATUS_SUCCESS
;
386 ******************************************************************************
388 * Gets a list of the object IDs of all currently loaded plugins.
390 * @param ppList A pointer to a pointer to an @ref MP_OID_LIST. On successful
391 * return this will contain a pointer to an @ref MP_OID_LIST
392 * which contains the object IDs of all of the plugins currently loaded
394 * @return An MP_STATUS indicating if the operation was successful or if
397 * @retval MP_SUCCESS Returned if the plugin ID list was successfully returned.
398 * @retval MP_STATUS_INVALID_PARAMETER Returned if @a ppList is NULL or
399 * specifies a memory area to which data cannot be written.
401 ******************************************************************************
403 MP_STATUS
MP_GetPluginOidList(
404 MP_OID_LIST
**ppList
)
409 return (MP_STATUS_INVALID_PARAMETER
);
411 (void) pthread_mutex_lock(&mp_lib_mutex
);
413 if (number_of_plugins
== 0) {
414 *ppList
= (MP_OID_LIST
*)calloc(1, sizeof(MP_OID_LIST
));
416 *ppList
= (MP_OID_LIST
*)calloc(1,
417 sizeof(MP_OID_LIST
) + (number_of_plugins
- 1)* sizeof(MP_OID
) );
420 if ((*ppList
) == NULL
) {
421 (void) pthread_mutex_unlock(&mp_lib_mutex
);
422 return (MP_STATUS_INSUFFICIENT_MEMORY
);
425 (*ppList
)->oidCount
= number_of_plugins
;
427 if (number_of_plugins
!= 0) {
428 for (i
= 0; i
< number_of_plugins
; i
++) {
429 (*ppList
)->oids
[i
].objectType
= MP_OBJECT_TYPE_PLUGIN
;
430 (*ppList
)->oids
[i
].ownerId
= plugintable
[i
].ownerId
;
431 (*ppList
)->oids
[i
].objectSequenceNumber
= 0;
435 (void) pthread_mutex_unlock(&mp_lib_mutex
);
436 return MP_STATUS_SUCCESS
;
440 *******************************************************************************
442 * Gets the properties of the specified vendor plugin.
445 * The ID of the plugin whose properties are being retrieved.
448 * A pointer to an @ref MP_PLUGIN_PROPERTIES structure allocated by
449 * the caller. On successful return this will contain the properties
450 * of the plugin specified by pluginOid.
452 * @return An MP_STATUS indicating if the operation was successful or if an
455 * @retval MP_STATUS_SUCCESS
456 * Returned if the plugin properties were successfully returned.
458 * @retval MP_STATUS_INVALID_OBJECT_TYPE
459 * Returned if oid does not specify any valid object type.
461 * @retval MP_STATUS_OBJECT_NOT_FOUND
462 * Returned if oid has an owner that is not currently known to
465 * @retval MP_STATUS_INVALID_PARAMETER
466 * Returned if 'pProps' is NULL or specifies a memory area to
467 * which data cannot be written.
469 *******************************************************************************
471 MP_STATUS
MP_GetPluginProperties(
473 MP_PLUGIN_PROPERTIES
*pProps
)
475 MP_GetPluginPropertiesPluginFn PassFunc
;
480 return (MP_STATUS_INVALID_PARAMETER
);
482 if ((status
= validate_object(pluginOid
, MP_OBJECT_TYPE_PLUGIN
,
483 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
487 (void) pthread_mutex_lock(&mp_lib_mutex
);
489 index
= pluginOid
.ownerId
- 1;
490 if (plugintable
[index
].hdlPlugin
!= NULL
) {
491 PassFunc
= (MP_GetPluginPropertiesPluginFn
)
492 dlsym(plugintable
[index
].hdlPlugin
, "MP_GetPluginPropertiesPlugin");
494 if (PassFunc
!= NULL
) {
495 status
= PassFunc(pProps
);
497 status
= MP_STATUS_UNSUPPORTED
;
500 status
= MP_STATUS_FAILED
;
503 (void) pthread_mutex_unlock(&mp_lib_mutex
);
508 *******************************************************************************
510 * Gets the object ID for the plugin associated with the specified object ID.
513 * The object ID of an object that has been received from a previous
517 * A pointer to an MP_OID structure allocated by the caller. On
518 * successful return this will contain the object ID of the plugin
519 * associated with the object specified by @a objectId.
521 * @return An MP_STATUS indicating if the operation was successful or if
524 * @retval MP_STATUS_SUCCESS
525 * Returned if the associated plugin ID was successfully returned.
527 * @retval MP_STATUS_OBJECT_NOT_FOUND
528 * Returned if oid does not specify a plugin that is currently known to
531 * @retval MP_STATUS_INVALID_PARAMETER
532 * Returned if 'oid' specifies an object not owned by a plugin or
533 * if pPluginOid is NULL or specifies a memory area to which data
536 * @retval MP_STATUS_INVALID_OBJECT_TYPE
537 * Returned if 'oid' specifies an object with an invalid type.
539 *******************************************************************************
541 MP_STATUS
MP_GetAssociatedPluginOid(
548 if (pPluginId
== NULL
)
549 return (MP_STATUS_INVALID_PARAMETER
);
551 if ((status
= validate_object(objectId
, 0, MP_OBJECT_TYPE_ANY
)) !=
556 pPluginId
->objectType
= MP_OBJECT_TYPE_PLUGIN
;
557 pPluginId
->ownerId
= objectId
.ownerId
;
558 pPluginId
->objectSequenceNumber
= 0;
560 return (MP_STATUS_SUCCESS
);
564 *******************************************************************************
566 * Gets the object type of an initialized object ID.
569 * The object ID of an object that has been received from a previous
573 * A pointer to an MP_OBJECT_TYPE variable allocated by the caller.
574 * On successful return this will contain the object type of oid.
576 * @return An MP_STATUS indicating if the operation was successful or
577 * if an error occurred.
579 * @retval MP_STATUS_OBJECT_NOT_FOUND
580 * Returned if oid has an owner that is not currently known to
583 * @retval MP_STATUS_INVALID_PARAMETER
584 * Returned if oid does not specify any valid object type.
586 * @retval MP_STATUS_SUCCESS
587 * Returned when the operation is successful.
589 *******************************************************************************
591 MP_STATUS
MP_GetObjectType(
593 MP_OBJECT_TYPE
*pObjectType
)
597 if (pObjectType
== NULL
)
598 return MP_STATUS_INVALID_PARAMETER
;
600 if ((status
= validate_object(oid
, 0, MP_OBJECT_TYPE_ANY
))
601 != MP_STATUS_SUCCESS
) {
605 *pObjectType
= oid
.objectType
;
606 return MP_STATUS_SUCCESS
;
610 *******************************************************************************
612 * Gets a list of the object IDs of all the device product properties
613 * associated with this plugin.
616 * The object ID of plugin.
619 * A pointer to a pointer to an MP_OID_LIST structure.
620 * On a successful return, this will contain a pointer to
621 * an MP_OID_LIST that contains the object IDs of all the device
622 * product descriptors associated with the specified plugin.
624 * @return An MP_STATUS indicating if the operation was successful or if
627 * @retval MP_STATUS_SUCCESS
628 * Returned when the operation is successful.
630 * @retval MP_STATUS_INVALID_PARAMETER
631 * Returned if ppList pointer passed as placeholder for holding
632 * the device product list is found to be invalid.
634 * @retval MP_STATUS_INVALID_OBJECT_TYPE
635 * Returned if oid does not specify any valid object type.
637 * @retval MP_STATUS_FAILED
638 * Returned when the plugin for the specified oid is not found.
640 * @retval MP_STATUS_INSUFFICIENT_MEMORY
641 * Returned when memory allocation failure occurs
643 * @retval MP_STATUS_UNSUPPORTED
644 * Returned when the API is not supported.
646 *******************************************************************************
648 MP_STATUS
MP_GetDeviceProductOidList(
650 MP_OID_LIST
**ppList
)
652 MP_GetDeviceProductOidListPluginFn PassFunc
;
657 return MP_STATUS_INVALID_PARAMETER
;
659 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
660 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
664 (void) pthread_mutex_lock(&mp_lib_mutex
);
666 index
= oid
.ownerId
- 1;
667 if (plugintable
[index
].hdlPlugin
!= NULL
) {
668 PassFunc
= (MP_GetDeviceProductOidListPluginFn
)
669 dlsym(plugintable
[index
].hdlPlugin
,
670 "MP_GetDeviceProductOidListPlugin");
671 if (PassFunc
!= NULL
) {
672 status
= PassFunc(ppList
);
674 status
= MP_STATUS_UNSUPPORTED
;
677 status
= MP_STATUS_FAILED
;
680 (void) pthread_mutex_unlock(&mp_lib_mutex
);
685 *******************************************************************************
687 * Gets the device product properties of the specified plugin oid.
690 * The object ID of the plugin.
693 * A pointer to a pointer to an MP_DEVICE_PRODUCT_PROPERTIES structure
694 * allocated by the caller. On successful return it will contain
695 * a pointer to an MP_DEVICE_PRODUCT_PROPERTIES structure allocated
698 * @return An MP_STATUS indicating if the operation was successful or if
701 * @retval MP_STATUS_SUCCESS
702 * Returned when the operation is successful.
704 * @retval MP_STATUS_INVALID_PARAMETER
705 * Returned if ppProps pointer passed as placeholder for holding
706 * the device product properties is found to be invalid.
708 * @retval MP_STATUS_INVALID_OBJECT_TYPE
709 * Returned if oid does not specify any valid object type.
711 * @retval MP_STATUS_FAILED
712 * Returned when the plugin for the specified oid is not found.
714 * @retval MP_STATUS_INSUFFICIENT_MEMORY
715 * Returned when memory allocation failure occurs
717 * @retval MP_STATUS_UNSUPPORTED
718 * Returned when the API is not supported.
720 *******************************************************************************
722 MP_STATUS
MP_GetDeviceProductProperties(
724 MP_DEVICE_PRODUCT_PROPERTIES
*pProps
)
726 MP_GetDeviceProductPropertiesFn PassFunc
;
731 return MP_STATUS_INVALID_PARAMETER
;
733 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_DEVICE_PRODUCT
,
734 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
738 (void) pthread_mutex_lock(&mp_lib_mutex
);
740 index
= oid
.ownerId
- 1;
741 if (plugintable
[index
].hdlPlugin
!= NULL
) {
742 PassFunc
= (MP_GetDeviceProductPropertiesFn
)
743 dlsym(plugintable
[index
].hdlPlugin
,
744 "MP_GetDeviceProductProperties");
746 if (PassFunc
!= NULL
) {
747 status
= PassFunc(oid
, pProps
);
749 status
= MP_STATUS_UNSUPPORTED
;
752 status
= MP_STATUS_FAILED
;
755 (void) pthread_mutex_unlock(&mp_lib_mutex
);
760 *******************************************************************************
762 * Gets a list of the object IDs of all the initiator ports associated
766 * The object ID of plugin.
769 * A pointer to a pointer to an MP_OID_LIST structure.
770 * On a successful return, this will contain a pointer to
771 * an MP_OID_LIST that contains the object IDs of all the initiator
772 * ports associated with the specified plugin.
774 * @return An MP_STATUS indicating if the operation was successful or if
777 * @retval MP_STATUS_SUCCESS
778 * Returned when the operation is successful.
780 * @retval MP_STATUS_INVALID_PARAMETER
781 * Returned if ppList pointer passed as placeholder for holding
782 * the initiator port list is found to be invalid.
784 * @retval MP_STATUS_INVALID_OBJECT_TYPE
785 * Returned if oid does not specify any valid object type.
787 * @retval MP_STATUS_FAILED
788 * Returned when the plugin for the specified oid is not found.
790 * @retval MP_STATUS_INSUFFICIENT_MEMORY
791 * Returned when memory allocation failure occurs
793 * @retval MP_STATUS_UNSUPPORTED
794 * Returned when the API is not supported.
796 *******************************************************************************
798 MP_STATUS
MP_GetInitiatorPortOidList(
800 MP_OID_LIST
**ppList
)
802 MP_GetInitiatorPortOidListPluginFn PassFunc
;
807 return MP_STATUS_INVALID_PARAMETER
;
809 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
810 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
814 (void) pthread_mutex_lock(&mp_lib_mutex
);
816 index
= oid
.ownerId
- 1;
817 if (plugintable
[index
].hdlPlugin
!= NULL
) {
818 PassFunc
= (MP_GetDeviceProductOidListPluginFn
)
819 dlsym(plugintable
[index
].hdlPlugin
, "MP_GetInitiatorPortOidListPlugin");
821 if (PassFunc
!= NULL
) {
822 status
= PassFunc(ppList
);
824 status
= MP_STATUS_UNSUPPORTED
;
827 status
= MP_STATUS_FAILED
;
830 (void) pthread_mutex_unlock(&mp_lib_mutex
);
835 *******************************************************************************
837 * Gets the properties of the specified initiator port.
840 * The object ID of the initiator port.
843 * A pointer to an MP_INITIATOR_PORT_PROPERTIES structure
844 * allocated by the caller. On successful return, this structure
845 * will contain the properties of the port specified by oid.
847 * @return An MP_STATUS indicating if the operation was successful or if
850 * @retval MP_STATUS_SUCCESS
851 * Returned when the operation is successful.
853 * @retval MP_STATUS_INVALID_PARAMETER
854 * Returned if pProps is NULL or specifies a memory area to
855 * which data cannot be written.
857 * @retval MP_STATUS_INVALID_OBJECT_TYPE
858 * Returned if oid does not specify any valid object type.
860 * @retval MP_STATUS_OBJECT_NOT_FOUND
861 * Returned if oid has an owner that is not currently known to
864 *******************************************************************************
866 MP_STATUS
MP_GetInitiatorPortProperties(
868 MP_INITIATOR_PORT_PROPERTIES
*pProps
)
870 MP_GetInitiatorPortPropertiesFn PassFunc
;
875 return MP_STATUS_INVALID_PARAMETER
;
877 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_INITIATOR_PORT
,
878 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
882 (void) pthread_mutex_lock(&mp_lib_mutex
);
884 index
= oid
.ownerId
- 1;
885 if (plugintable
[index
].hdlPlugin
!= NULL
) {
886 PassFunc
= (MP_GetInitiatorPortPropertiesFn
)
887 dlsym(plugintable
[index
].hdlPlugin
,
888 "MP_GetInitiatorPortProperties");
890 if (PassFunc
!= NULL
) {
891 status
= PassFunc(oid
, pProps
);
893 status
= MP_STATUS_UNSUPPORTED
;
896 status
= MP_STATUS_FAILED
;
899 (void) pthread_mutex_unlock(&mp_lib_mutex
);
904 *******************************************************************************
906 * Gets a list of multipath logical units associated to a plugin.
909 * The object ID of plugin.
912 * A pointer to a pointer to an MP_OID_LIST structure.
913 * On a successful return, this will contain a pointer to
914 * an MP_OID_LIST that contains the object IDs of all the multipath
915 * logical units associated with the specified plugin.
917 * @return An MP_STATUS indicating if the operation was successful or if
920 * @retval MP_STATUS_SUCCESS
921 * Returned when the operation is successful.
923 * @retval MP_STATUS_INVALID_PARAMETER
924 * Returned if ppList pointer passed as placeholder for holding
925 * the multipath logical unit list is found to be invalid.
927 * @retval MP_STATUS_INVALID_OBJECT_TYPE
928 * Returned if oid does not specify any valid object type.
930 * @retval MP_STATUS_FAILED
931 * Returned when the plugin for the specified oid is not found.
933 * @retval MP_STATUS_INSUFFICIENT_MEMORY
934 * Returned when memory allocation failure occurs
936 * @retval MP_STATUS_UNSUPPORTED
937 * Returned when the API is not supported.
939 *******************************************************************************
941 MP_STATUS
MP_GetMultipathLus(
943 MP_OID_LIST
**ppList
)
949 return MP_STATUS_INVALID_PARAMETER
;
951 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
952 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
953 ((status
= validate_object(oid
, MP_OBJECT_TYPE_DEVICE_PRODUCT
,
954 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
958 (void) pthread_mutex_lock(&mp_lib_mutex
);
960 index
= oid
.ownerId
- 1;
961 if (plugintable
[index
].hdlPlugin
!= NULL
) {
962 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
963 MP_GetMultipathLusPluginFn PassFunc
;
964 PassFunc
= (MP_GetMultipathLusPluginFn
)
965 dlsym(plugintable
[index
].hdlPlugin
,
966 "MP_GetMultipathLusPlugin");
968 if (PassFunc
!= NULL
) {
969 status
= PassFunc(ppList
);
971 status
= MP_STATUS_UNSUPPORTED
;
973 } else if (oid
.objectType
== MP_OBJECT_TYPE_DEVICE_PRODUCT
) {
974 MP_GetMultipathLusDevProdFn PassFunc
;
975 PassFunc
= (MP_GetMultipathLusDevProdFn
)
976 dlsym(plugintable
[index
].hdlPlugin
,
977 "MP_GetMultipathLusDevProd");
979 if (PassFunc
!= NULL
) {
980 status
= PassFunc(oid
, ppList
);
982 status
= MP_STATUS_UNSUPPORTED
;
985 status
= MP_STATUS_INVALID_PARAMETER
;
989 (void) pthread_mutex_unlock(&mp_lib_mutex
);
995 *******************************************************************************
997 * Gets the properties of the specified logical unit.
1000 * The object ID of the multipath logical unit.
1003 * A pointer to an MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES structure
1004 * allocated by the caller. On successful return, this structure
1005 * will contain the properties of the port specified by oid.
1007 * @return An MP_STATUS indicating if the operation was successful or if
1008 * an error occurred.
1010 * @retval MP_STATUS_SUCCESS
1011 * Returned when the operation is successful.
1013 * @retval MP_STATUS_INVALID_PARAMETER
1014 * Returned if pProps is NULL or specifies a memory area to
1015 * which data cannot be written.
1017 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1018 * Returned if oid does not specify any valid object type.
1020 * @retval MP_STATUS_OBJECT_NOT_FOUND
1021 * Returned if oid has an owner that is not currently known to
1024 *******************************************************************************
1026 MP_STATUS
MP_GetMPLogicalUnitProperties(
1028 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
*pProps
)
1030 MP_GetMPLogicalUnitPropertiesFn PassFunc
;
1035 return MP_STATUS_INVALID_PARAMETER
;
1037 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1038 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1042 (void) pthread_mutex_lock(&mp_lib_mutex
);
1044 index
= oid
.ownerId
- 1;
1045 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1046 PassFunc
= (MP_GetMPLogicalUnitPropertiesFn
)
1047 dlsym(plugintable
[index
].hdlPlugin
,
1048 "MP_GetMPLogicalUnitProperties");
1050 if (PassFunc
!= NULL
) {
1051 status
= PassFunc(oid
, pProps
);
1053 status
= MP_STATUS_UNSUPPORTED
;
1056 status
= MP_STATUS_FAILED
;
1059 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1064 *******************************************************************************
1066 * Gets a list of the object IDs of all the path logical units associated
1067 * with the specified multipath logical unit, initiator port, or target port.
1070 * The object ID of multipath logical unit, initiator port, or
1074 * A pointer to a pointer to an MP_OID_LIST structure.
1075 * On a successful return, this will contain a pointer to
1076 * an MP_OID_LIST that contains the object IDs of all the mp path
1077 * logical units associated with the specified OID.
1079 * @return An MP_STATUS indicating if the operation was successful or if
1080 * an error occurred.
1082 * @retval MP_STATUS_SUCCESS
1083 * Returned when the operation is successful.
1085 * @retval MP_STATUS_INVALID_PARAMETER
1086 * Returned if ppList pointer passed as placeholder for holding
1087 * the device product list is found to be invalid.
1089 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1090 * Returned if oid does not specify any valid object type.
1092 * @retval MP_STATUS_FAILED
1093 * Returned when the plugin for the specified oid is not found.
1095 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1096 * Returned when memory allocation failure occurs
1098 * @retval MP_STATUS_OBJECT_NOT_FOUND
1099 * Returned if oid has an owner that is not currently known to
1102 *******************************************************************************
1104 MP_STATUS
MP_GetAssociatedPathOidList(
1106 MP_OID_LIST
**ppList
)
1108 MP_GetAssociatedPathOidListFn PassFunc
;
1113 return MP_STATUS_INVALID_PARAMETER
;
1115 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_INITIATOR_PORT
,
1116 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
1117 ((status
= validate_object(oid
, MP_OBJECT_TYPE_TARGET_PORT
,
1118 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
1119 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1120 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
1124 (void) pthread_mutex_lock(&mp_lib_mutex
);
1126 index
= oid
.ownerId
- 1;
1127 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1128 PassFunc
= (MP_GetAssociatedPathOidListFn
)
1129 dlsym(plugintable
[index
].hdlPlugin
,
1130 "MP_GetAssociatedPathOidList");
1132 if (PassFunc
!= NULL
) {
1133 status
= PassFunc(oid
, ppList
);
1135 status
= MP_STATUS_UNSUPPORTED
;
1138 status
= MP_STATUS_FAILED
;
1141 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1146 *******************************************************************************
1148 * Gets the properties of the specified path logical unit.
1151 * The object ID of the path logical unit.
1154 * A pointer to an MP_PATH_LOGICAL_UNIT_PROPERTIES structure
1155 * allocated by the caller. On successful return, this structure
1156 * will contain the properties of the port specified by oid.
1158 * @return An MP_STATUS indicating if the operation was successful or if
1159 * an error occurred.
1161 * @retval MP_STATUS_SUCCESS
1162 * Returned when the operation is successful.
1164 * @retval MP_STATUS_INVALID_PARAMETER
1165 * Returned if pProps is NULL or specifies a memory area to
1166 * which data cannot be written.
1168 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1169 * Returned if oid does not specify any valid object type.
1171 * @retval MP_STATUS_OBJECT_NOT_FOUND
1172 * Returned if oid has an owner that is not currently known to
1175 *******************************************************************************
1177 MP_STATUS
MP_GetPathLogicalUnitProperties(
1179 MP_PATH_LOGICAL_UNIT_PROPERTIES
*pProps
)
1181 MP_GetPathLogicalUnitPropertiesFn PassFunc
;
1186 return MP_STATUS_INVALID_PARAMETER
;
1188 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PATH_LU
,
1189 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1193 (void) pthread_mutex_lock(&mp_lib_mutex
);
1195 index
= oid
.ownerId
- 1;
1196 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1197 PassFunc
= (MP_GetPathLogicalUnitPropertiesFn
)
1198 dlsym(plugintable
[index
].hdlPlugin
,
1199 "MP_GetPathLogicalUnitProperties");
1201 if (PassFunc
!= NULL
) {
1202 status
= PassFunc(oid
, pProps
);
1204 status
= MP_STATUS_UNSUPPORTED
;
1207 status
= MP_STATUS_FAILED
;
1210 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1215 *******************************************************************************
1217 * Gets a list of the object IDs of all the target port group associated
1218 * with the specified multipath logical unit.
1221 * The object ID of the multiple logical unit.
1224 * A pointer to a pointer to an MP_OID_LIST structure.
1225 * On a successful return, this will contain a pointer to
1226 * an MP_OID_LIST that contains the object IDs of all the target
1227 * port group associated with the specified multipath logical unit.
1229 * @return An MP_STATUS indicating if the operation was successful or if
1230 * an error occurred.
1232 * @retval MP_STATUS_SUCCESS
1233 * Returned when the operation is successful.
1235 * @retval MP_STATUS_INVALID_PARAMETER
1236 * Returned if ppList pointer passed as placeholder for holding
1237 * the target port group list is found to be invalid.
1239 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1240 * Returned if oid does not specify any valid object type.
1242 * @retval MP_STATUS_FAILED
1243 * Returned when the plugin for the specified oid is not found.
1245 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1246 * Returned when memory allocation failure occurs
1249 *******************************************************************************
1251 MP_STATUS
MP_GetAssociatedTPGOidList(
1253 MP_OID_LIST
**ppList
)
1255 MP_GetAssociatedTPGOidListFn PassFunc
;
1260 return MP_STATUS_INVALID_PARAMETER
;
1262 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1263 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1267 (void) pthread_mutex_lock(&mp_lib_mutex
);
1269 index
= oid
.ownerId
- 1;
1270 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1271 PassFunc
= (MP_GetAssociatedTPGOidListFn
)
1272 dlsym(plugintable
[index
].hdlPlugin
,
1273 "MP_GetAssociatedTPGOidList");
1275 if (PassFunc
!= NULL
) {
1276 status
= PassFunc(oid
, ppList
);
1278 status
= MP_STATUS_UNSUPPORTED
;
1281 status
= MP_STATUS_FAILED
;
1284 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1289 *******************************************************************************
1291 * Gets the properties of the specified target port group.
1294 * The object ID of the target port group.
1297 * A pointer to an MP_TARGET_PORT_GROUP_PROPERTIES structure
1298 * allocated by the caller. On successful return, this structure
1299 * will contain the properties of the port specified by oid.
1301 * @return An MP_STATUS indicating if the operation was successful or if
1302 * an error occurred.
1304 * @retval MP_STATUS_SUCCESS
1305 * Returned when the operation is successful.
1307 * @retval MP_STATUS_INVALID_PARAMETER
1308 * Returned if pProps is NULL or specifies a memory area to
1309 * which data cannot be written.
1311 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1312 * Returned if oid does not specify any valid object type.
1314 * @retval MP_STATUS_OBJECT_NOT_FOUND
1315 * Returned if oid has an owner that is not currently known to
1318 *******************************************************************************
1320 MP_STATUS
MP_GetTargetPortGroupProperties(
1322 MP_TARGET_PORT_GROUP_PROPERTIES
*pProps
)
1324 MP_GetTargetPortGroupPropertiesFn PassFunc
;
1329 return MP_STATUS_INVALID_PARAMETER
;
1331 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_TARGET_PORT_GROUP
,
1332 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1336 (void) pthread_mutex_lock(&mp_lib_mutex
);
1338 index
= oid
.ownerId
- 1;
1339 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1340 PassFunc
= (MP_GetTargetPortGroupPropertiesFn
)
1341 dlsym(plugintable
[index
].hdlPlugin
,
1342 "MP_GetTargetPortGroupProperties");
1344 if (PassFunc
!= NULL
) {
1345 status
= PassFunc(oid
, pProps
);
1347 status
= MP_STATUS_UNSUPPORTED
;
1350 status
= MP_STATUS_FAILED
;
1353 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1358 *******************************************************************************
1360 * Gets a list of multipath logical units associated with the specific target
1364 * The object ID of the target port group.
1367 * A pointer to a pointer to an MP_OID_LIST structure.
1368 * On a successful return, this will contain a pointer to
1369 * an MP_OID_LIST that contains the object IDs of all the multipath
1370 * logical units associated with the specified target port group.
1372 * @return An MP_STATUS indicating if the operation was successful or if
1373 * an error occurred.
1375 * @retval MP_STATUS_SUCCESS
1376 * Returned when the operation is successful.
1378 * @retval MP_STATUS_INVALID_PARAMETER
1379 * Returned if ppList pointer passed as placeholder for holding
1380 * the multipath logical unit list is found to be invalid.
1382 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1383 * Returned if oid does not specify any valid object type.
1385 * @retval MP_STATUS_FAILED
1386 * Returned when the plugin for the specified oid is not found.
1388 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1389 * Returned when memory allocation failure occurs
1391 *******************************************************************************
1393 MP_STATUS
MP_GetMPLuOidListFromTPG(
1395 MP_OID_LIST
**ppList
)
1397 MP_GetMPLuOidListFromTPGFn PassFunc
;
1402 return MP_STATUS_INVALID_PARAMETER
;
1404 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_TARGET_PORT_GROUP
,
1405 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1409 (void) pthread_mutex_lock(&mp_lib_mutex
);
1411 index
= oid
.ownerId
- 1;
1412 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1413 PassFunc
= (MP_GetMPLuOidListFromTPGFn
)
1414 dlsym(plugintable
[index
].hdlPlugin
,
1415 "MP_GetMPLuOidListFromTPG");
1417 if (PassFunc
!= NULL
) {
1418 status
= PassFunc(oid
, ppList
);
1420 status
= MP_STATUS_UNSUPPORTED
;
1423 status
= MP_STATUS_FAILED
;
1426 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1431 *******************************************************************************
1433 * Gets a list of the object IDs of all the proprietary load balance
1434 * algorithms associated with this plugin.
1437 * The object ID of the plugin.
1440 * A pointer to a pointer to an MP_OID_LIST structure.
1441 * On a successful return, this will contain a pointer to
1442 * an MP_OID_LIST that contains the object IDs of all the proprietary
1443 * load balance algorithms associated with the specified plugin.
1445 * @return An MP_STATUS indicating if the operation was successful or if
1446 * an error occurred.
1448 * @retval MP_STATUS_SUCCESS
1449 * Returned when the operation is successful.
1451 * @retval MP_STATUS_INVALID_PARAMETER
1452 * Returned if ppList pointer passed as placeholder for holding
1453 * the proprietary load balance oid list is found to be invalid.
1455 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1456 * Returned if oid does not specify any valid object type.
1458 * @retval MP_STATUS_FAILED
1459 * Returned when the plugin for the specified oid is not found.
1461 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1462 * Returned when memory allocation failure occurs
1464 * @retval MP_STATUS_UNSUPPORTED
1465 * Returned when the API is not supported.
1467 *******************************************************************************
1469 MP_STATUS
MP_GetProprietaryLoadBalanceOidList(
1471 MP_OID_LIST
**ppList
)
1473 MP_GetProprietaryLoadBalanceOidListPluginFn PassFunc
;
1478 return MP_STATUS_INVALID_PARAMETER
;
1480 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
1481 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1485 (void) pthread_mutex_lock(&mp_lib_mutex
);
1487 index
= oid
.ownerId
- 1;
1488 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1489 PassFunc
= (MP_GetProprietaryLoadBalanceOidListPluginFn
)
1490 dlsym(plugintable
[index
].hdlPlugin
,
1491 "MP_GetProprietaryLoadBalanceOidListPlugin");
1493 if (PassFunc
!= NULL
) {
1494 status
= PassFunc(ppList
);
1496 status
= MP_STATUS_UNSUPPORTED
;
1499 status
= MP_STATUS_FAILED
;
1502 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1507 *******************************************************************************
1509 * Gets the properties of the specified load balance properties structure.
1512 * The object ID of the load balance properties structure.
1515 * A pointer to an MP_LOAD_BALANCE_PROPRIETARY_TYPE structure
1516 * allocated by the caller. On successful return, this structure
1517 * will contain the properties of the proprietary load balance algorithm
1520 * @return An MP_STATUS indicating if the operation was successful or if
1521 * an error occurred.
1523 * @retval MP_STATUS_SUCCESS
1524 * Returned when the operation is successful.
1526 * @retval MP_STATUS_INVALID_PARAMETER
1527 * Returned if pProps is NULL or specifies a memory area to
1528 * which data cannot be written.
1530 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1531 * Returned if oid does not specify any valid object type.
1533 * @retval MP_STATUS_OBJECT_NOT_FOUND
1534 * Returned if oid has an owner that is not currently known to
1537 *******************************************************************************
1539 MP_STATUS
MP_GetProprietaryLoadBalanceProperties (
1541 MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES
*pProps
)
1543 MP_GetProprietaryLoadBalancePropertiesFn PassFunc
;
1548 return MP_STATUS_INVALID_PARAMETER
;
1550 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE
,
1551 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1555 (void) pthread_mutex_lock(&mp_lib_mutex
);
1557 index
= oid
.ownerId
- 1;
1558 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1559 PassFunc
= (MP_GetProprietaryLoadBalancePropertiesFn
)
1560 dlsym(plugintable
[index
].hdlPlugin
,
1561 "MP_GetProprietaryLoadBalanceProperties");
1563 if (PassFunc
!= NULL
) {
1564 status
= PassFunc(oid
, pProps
);
1566 status
= MP_STATUS_UNSUPPORTED
;
1569 status
= MP_STATUS_FAILED
;
1572 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1577 *******************************************************************************
1579 * Gets a list of the object IDs of the target ports in the specified target
1583 * The object ID of the target port group.
1586 * A pointer to a pointer to an MP_OID_LIST structure.
1587 * On a successful return, this will contain a pointer to
1588 * an MP_OID_LIST that contains the object IDs of all the target ports
1589 * associated with the specified target port group.
1591 * @return An MP_STATUS indicating if the operation was successful or if
1592 * an error occurred.
1594 * @retval MP_STATUS_SUCCESS
1595 * Returned when the operation is successful.
1597 * @retval MP_STATUS_INVALID_PARAMETER
1598 * Returned if ppList pointer passed as placeholder for holding
1599 * the multipath logical unit list is found to be invalid.
1601 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1602 * Returned if oid does not specify any valid object type.
1604 * @retval MP_STATUS_FAILED
1605 * Returned when the plugin for the specified oid is not found.
1607 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1608 * Returned when memory allocation failure occurs
1610 *******************************************************************************
1612 MP_STATUS
MP_GetTargetPortOidList(
1614 MP_OID_LIST
**ppList
)
1616 MP_GetTargetPortOidListFn PassFunc
;
1621 return MP_STATUS_INVALID_PARAMETER
;
1623 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_TARGET_PORT_GROUP
,
1624 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1628 (void) pthread_mutex_lock(&mp_lib_mutex
);
1630 index
= oid
.ownerId
- 1;
1631 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1632 PassFunc
= (MP_GetTargetPortOidListFn
)
1633 dlsym(plugintable
[index
].hdlPlugin
,
1634 "MP_GetTargetPortOidList");
1636 if (PassFunc
!= NULL
) {
1637 status
= PassFunc(oid
, ppList
);
1639 status
= MP_STATUS_UNSUPPORTED
;
1642 status
= MP_STATUS_FAILED
;
1645 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1650 *******************************************************************************
1652 * Gets the properties of the specified target port.
1655 * The object ID of the target port.
1658 * A pointer to an MP_TARGET_PORT_PROPERTIES structure
1659 * allocated by the caller. On successful return, this structure
1660 * will contain the properties of the port specified by oid.
1662 * @return An MP_STATUS indicating if the operation was successful or if
1663 * an error occurred.
1665 * @retval MP_STATUS_SUCCESS
1666 * Returned when the operation is successful.
1668 * @retval MP_STATUS_INVALID_PARAMETER
1669 * Returned if pProps is NULL or specifies a memory area to
1670 * which data cannot be written.
1672 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1673 * Returned if oid does not specify any valid object type.
1675 * @retval MP_STATUS_OBJECT_NOT_FOUND
1676 * Returned if oid has an owner that is not currently known to
1679 *******************************************************************************
1681 MP_STATUS
MP_GetTargetPortProperties(
1683 MP_TARGET_PORT_PROPERTIES
*pProps
)
1685 MP_GetTargetPortPropertiesFn PassFunc
;
1690 return MP_STATUS_INVALID_PARAMETER
;
1692 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_TARGET_PORT
,
1693 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1697 (void) pthread_mutex_lock(&mp_lib_mutex
);
1699 index
= oid
.ownerId
- 1;
1700 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1701 PassFunc
= (MP_GetTargetPortPropertiesFn
)
1702 dlsym(plugintable
[index
].hdlPlugin
,
1703 "MP_GetTargetPortProperties");
1705 if (PassFunc
!= NULL
) {
1706 status
= PassFunc(oid
, pProps
);
1708 status
= MP_STATUS_UNSUPPORTED
;
1711 status
= MP_STATUS_FAILED
;
1714 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1720 *******************************************************************************
1722 * Assign a multipath logical unit to a target port group.
1725 * An MP_TARGET_PORT_GROUP oid. The target port group currently in
1726 * active access state that the administrator would like the LU
1730 * An MP_MULTIPATH_LOGICAL_UNIT oid.
1732 * @return An MP_STATUS indicating if the operation was successful or if
1733 * an error occurred.
1735 * @retval MP_STATUS_SUCCESS
1736 * Returned when the operation is successful.
1738 * @retval MP_STATUS_INVALID_PARAMETER
1739 * Returned when luOid is not associated with tpgOid.
1741 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1742 * Returned if oid does not specify any valid object type.
1744 * @retval MP_STATUS_OBJECT_NOT_FOUND
1745 * Returned if oid has an owner that is not currently known to
1748 *******************************************************************************
1750 MP_STATUS
MP_AssignLogicalUnitToTPG(
1754 MP_AssignLogicalUnitToTPGFn PassFunc
;
1758 if (luOid
.ownerId
!= tpgOid
.ownerId
) {
1759 return (MP_STATUS_INVALID_PARAMETER
);
1762 if ((status
= validate_object(tpgOid
, MP_OBJECT_TYPE_TARGET_PORT_GROUP
,
1763 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1767 if ((status
= validate_object(luOid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1768 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1772 (void) pthread_mutex_lock(&mp_lib_mutex
);
1774 index
= tpgOid
.ownerId
- 1;
1775 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1776 PassFunc
= (MP_AssignLogicalUnitToTPGFn
)
1777 dlsym(plugintable
[index
].hdlPlugin
,
1778 "MP_AssignLogicalUnitToTPG");
1780 if (PassFunc
!= NULL
) {
1781 status
= PassFunc(tpgOid
, luOid
);
1783 status
= MP_STATUS_UNSUPPORTED
;
1786 status
= MP_STATUS_FAILED
;
1789 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1794 *******************************************************************************
1796 * Manually override the path for a logical unit. The path exclusively used to
1797 * access the logical unit until cleared.
1799 * @param logicalUnitOid
1800 * The object ID of the multipath logical unit.
1803 * The object ID of the path logical unit.
1805 * @return An MP_STATUS indicating if the operation was successful or if
1806 * an error occurred.
1808 * @retval MP_STATUS_SUCCESS
1809 * Returned when the operation is successful.
1811 * @retval MP_STATUS_INVALID_PARAMETER
1812 * Returned if the oid of the object is not valid
1814 * @retval MP_STATUS_UNSUPPORTED
1815 * Returned when the implementation does not support the API
1817 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1818 * Returned if oid does not specify any valid object type.
1820 * @retval MP_STATUS_PATH_NONOPERATIONAL
1821 * Returned when the driver cannot communicate through selected path.
1823 *******************************************************************************
1825 MP_STATUS
MP_SetOverridePath(
1826 MP_OID logicalUnitOid
,
1829 MP_SetOverridePathFn PassFunc
;
1833 if ((status
= validate_object(logicalUnitOid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1834 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1837 if ((status
= validate_object(pathOid
, MP_OBJECT_TYPE_PATH_LU
,
1838 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1842 (void) pthread_mutex_lock(&mp_lib_mutex
);
1844 index
= pathOid
.ownerId
- 1;
1845 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1846 PassFunc
= (MP_SetOverridePathFn
)
1847 dlsym(plugintable
[index
].hdlPlugin
,
1848 "MP_SetOverridePath");
1850 if (PassFunc
!= NULL
) {
1851 status
= PassFunc(logicalUnitOid
, pathOid
);
1853 status
= MP_STATUS_UNSUPPORTED
;
1856 status
= MP_STATUS_FAILED
;
1859 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1864 *******************************************************************************
1866 * Cancel a path override and re-enable load balancing.
1869 * An MP_MULTIPATH_LOGICAL_UNIT oid.
1871 * @return An MP_STATUS indicating if the operation was successful or if
1872 * an error occurred.
1874 * @retval MP_STATUS_SUCCESS
1875 * Returned when the operation is successful.
1877 * @retval MP_STATUS_INVALID_PARAMETER
1878 * Returned if MP_MULTIPATH_LOGICAL_UNIT with the luOid is not found.
1880 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1881 * Returned if oid does not specify any valid object type.
1883 * @retval MP_STATUS_OBJECT_NOT_FOUND
1884 * Returned if oid has an owner that is not currently known to
1887 *******************************************************************************
1889 MP_STATUS
MP_CancelOverridePath(
1892 MP_CancelOverridePathFn PassFunc
;
1896 if ((status
= validate_object(luOid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1897 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
1901 (void) pthread_mutex_lock(&mp_lib_mutex
);
1903 index
= luOid
.ownerId
- 1;
1904 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1905 PassFunc
= (MP_CancelOverridePathFn
)
1906 dlsym(plugintable
[index
].hdlPlugin
,
1907 "MP_CancelOverridePath");
1909 if (PassFunc
!= NULL
) {
1910 status
= PassFunc(luOid
);
1912 status
= MP_STATUS_UNSUPPORTED
;
1915 status
= MP_STATUS_FAILED
;
1918 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1923 *******************************************************************************
1925 * Enables Auto-failback.
1928 * The oid of the plugin.
1930 * @return An MP_STATUS indicating if the operation was successful or if
1931 * an error occurred.
1933 * @retval MP_STATUS_SUCCESS
1934 * Returned when the operation is successful.
1936 * @retval MP_STATUS_INVALID_PARAMETER
1937 * Returned if oid is NULL or specifies a memory area that is not
1938 * a valid plugin oid.
1940 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1941 * Returned if oid does not specify any valid object type.
1943 *******************************************************************************
1945 MP_STATUS
MP_EnableAutoFailback(
1951 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
1952 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
1953 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
1954 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
1958 (void) pthread_mutex_lock(&mp_lib_mutex
);
1960 index
= oid
.ownerId
- 1;
1961 if (plugintable
[index
].hdlPlugin
!= NULL
) {
1962 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
1963 MP_EnableAutoFailbackPluginFn PassFunc
;
1964 PassFunc
= (MP_EnableAutoFailbackPluginFn
)
1965 dlsym(plugintable
[index
].hdlPlugin
,
1966 "MP_EnableAutoFailbackPlugin");
1968 if (PassFunc
!= NULL
) {
1969 status
= PassFunc();
1971 status
= MP_STATUS_UNSUPPORTED
;
1973 } else if (oid
.objectType
== MP_OBJECT_TYPE_MULTIPATH_LU
) {
1974 MP_EnableAutoFailbackLuFn PassFunc
;
1975 PassFunc
= (MP_EnableAutoFailbackLuFn
)
1976 dlsym(plugintable
[index
].hdlPlugin
,
1977 "MP_EnableAutoFailbackLu");
1979 if (PassFunc
!= NULL
) {
1980 status
= PassFunc(oid
);
1982 status
= MP_STATUS_UNSUPPORTED
;
1985 status
= MP_STATUS_INVALID_PARAMETER
;
1989 (void) pthread_mutex_unlock(&mp_lib_mutex
);
1994 *******************************************************************************
1996 * Enables Auto-probing.
1999 * The oid of the plugin or the multipath logical unit.
2001 * @return An MP_STATUS indicating if the operation was successful or if
2002 * an error occurred.
2004 * @retval MP_STATUS_SUCCESS
2005 * Returned when the operation is successful.
2007 * @retval MP_STATUS_INVALID_PARAMETER
2008 * Returned if oid is NULL or specifies a memory area that is not
2009 * a valid plugin oid.
2011 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2012 * Returned if oid does not specify any valid object type.
2014 *******************************************************************************
2016 MP_STATUS
MP_EnableAutoProbing(
2022 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2023 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2024 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2025 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
2029 (void) pthread_mutex_lock(&mp_lib_mutex
);
2031 index
= oid
.ownerId
- 1;
2032 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2033 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
2034 MP_EnableAutoProbingPluginFn PassFunc
;
2035 PassFunc
= (MP_EnableAutoProbingPluginFn
)
2036 dlsym(plugintable
[index
].hdlPlugin
,
2037 "MP_EnableAutoProbingPlugin");
2039 if (PassFunc
!= NULL
) {
2040 status
= PassFunc();
2042 status
= MP_STATUS_UNSUPPORTED
;
2044 } else if (oid
.objectType
== MP_OBJECT_TYPE_MULTIPATH_LU
) {
2045 MP_EnableAutoProbingLuFn PassFunc
;
2046 PassFunc
= (MP_EnableAutoProbingLuFn
)
2047 dlsym(plugintable
[index
].hdlPlugin
,
2048 "MP_EnableAutoProbingLu");
2050 if (PassFunc
!= NULL
) {
2051 status
= PassFunc(oid
);
2053 status
= MP_STATUS_UNSUPPORTED
;
2056 status
= MP_STATUS_INVALID_PARAMETER
;
2060 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2065 *******************************************************************************
2067 * Disables Auto-failback.
2070 * The oid of the plugin.
2072 * @return An MP_STATUS indicating if the operation was successful or if
2073 * an error occurred.
2075 * @retval MP_STATUS_SUCCESS
2076 * Returned when the operation is successful.
2078 * @retval MP_STATUS_INVALID_PARAMETER
2079 * Returned if oid is NULL or specifies a memory area that is not
2080 * a valid plugin oid.
2082 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2083 * Returned if oid does not specify any valid object type.
2085 *******************************************************************************
2087 MP_STATUS
MP_DisableAutoFailback(
2093 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2094 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2095 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2096 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
2100 (void) pthread_mutex_lock(&mp_lib_mutex
);
2102 index
= oid
.ownerId
- 1;
2103 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2104 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
2105 MP_DisableAutoFailbackPluginFn PassFunc
;
2106 PassFunc
= (MP_DisableAutoFailbackPluginFn
)
2107 dlsym(plugintable
[index
].hdlPlugin
,
2108 "MP_DisableAutoFailbackPlugin");
2110 if (PassFunc
!= NULL
) {
2111 status
= PassFunc();
2113 status
= MP_STATUS_UNSUPPORTED
;
2115 } else if (oid
.objectType
== MP_OBJECT_TYPE_MULTIPATH_LU
) {
2116 MP_DisableAutoFailbackLuFn PassFunc
;
2117 PassFunc
= (MP_DisableAutoFailbackLuFn
)
2118 dlsym(plugintable
[index
].hdlPlugin
,
2119 "MP_DisableAutoFailbackLu");
2121 if (PassFunc
!= NULL
) {
2122 status
= PassFunc(oid
);
2124 status
= MP_STATUS_UNSUPPORTED
;
2127 status
= MP_STATUS_INVALID_PARAMETER
;
2131 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2136 *******************************************************************************
2138 * Disables Auto-probing.
2141 * The oid of the plugin or the multipath logical unit.
2143 * @return An MP_STATUS indicating if the operation was successful or if
2144 * an error occurred.
2146 * @retval MP_STATUS_SUCCESS
2147 * Returned when the operation is successful.
2149 * @retval MP_STATUS_INVALID_PARAMETER
2150 * Returned if oid is NULL or specifies a memory area that is not
2151 * a valid plugin oid.
2153 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2154 * Returned if oid does not specify any valid object type.
2156 *******************************************************************************
2158 MP_STATUS
MP_DisableAutoProbing(
2164 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2165 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2166 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2167 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
2171 (void) pthread_mutex_lock(&mp_lib_mutex
);
2173 index
= oid
.ownerId
- 1;
2174 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2175 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
2176 MP_DisableAutoProbingPluginFn PassFunc
;
2177 PassFunc
= (MP_DisableAutoProbingPluginFn
)
2178 dlsym(plugintable
[index
].hdlPlugin
,
2179 "MP_DisableAutoProbingPlugin");
2181 if (PassFunc
!= NULL
) {
2182 status
= PassFunc();
2184 status
= MP_STATUS_UNSUPPORTED
;
2186 } else if (oid
.objectType
== MP_OBJECT_TYPE_MULTIPATH_LU
) {
2187 MP_DisableAutoFailbackLuFn PassFunc
;
2188 PassFunc
= (MP_DisableAutoProbingLuFn
)
2189 dlsym(plugintable
[index
].hdlPlugin
,
2190 "MP_DisableAutoProbingLu");
2192 if (PassFunc
!= NULL
) {
2193 status
= PassFunc(oid
);
2195 status
= MP_STATUS_UNSUPPORTED
;
2198 status
= MP_STATUS_INVALID_PARAMETER
;
2202 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2207 *******************************************************************************
2209 * Enables a path. This API may cause failover in a logical unit with
2210 * asymmetric access.
2213 * The oid of the path.
2215 * @return An MP_STATUS indicating if the operation was successful or if
2216 * an error occurred.
2218 * @retval MP_STATUS_SUCCESS
2219 * Returned when the operation is successful.
2221 * @retval MP_STATUS_INVALID_PARAMETER
2222 * Returned if oid is NULL or specifies a memory area that is not
2225 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2226 * Returned if oid does not specify any valid object type.
2228 *******************************************************************************
2230 MP_STATUS
MP_EnablePath(
2233 MP_EnablePathFn PassFunc
;
2237 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PATH_LU
,
2238 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2242 (void) pthread_mutex_lock(&mp_lib_mutex
);
2244 index
= oid
.ownerId
- 1;
2245 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2246 PassFunc
= (MP_EnablePathFn
)
2247 dlsym(plugintable
[index
].hdlPlugin
,
2250 if (PassFunc
!= NULL
) {
2251 status
= PassFunc(oid
);
2253 status
= MP_STATUS_UNSUPPORTED
;
2256 status
= MP_STATUS_FAILED
;
2259 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2264 *******************************************************************************
2266 * Disables a path. This API may cause failover in a logical unit with
2267 * asymmetric access. This API may cause a logical unit to become unavailable.
2270 * The oid of the path.
2272 * @return An MP_STATUS indicating if the operation was successful or if
2273 * an error occurred.
2275 * @retval MP_STATUS_SUCCESS
2276 * Returned when the operation is successful.
2278 * @retval MP_STATUS_INVALID_PARAMETER
2279 * Returned if oid is NULL or specifies a memory area that is not
2282 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2283 * Returned if oid does not specify any valid object type.
2285 *******************************************************************************
2287 MP_STATUS
MP_DisablePath(
2290 MP_DisablePathFn PassFunc
;
2294 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PATH_LU
,
2295 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2299 (void) pthread_mutex_lock(&mp_lib_mutex
);
2301 index
= oid
.ownerId
- 1;
2302 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2303 PassFunc
= (MP_DisablePathFn
)
2304 dlsym(plugintable
[index
].hdlPlugin
,
2307 if (PassFunc
!= NULL
) {
2308 status
= PassFunc(oid
);
2310 status
= MP_STATUS_UNSUPPORTED
;
2313 status
= MP_STATUS_FAILED
;
2316 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2321 *******************************************************************************
2323 * Set the multipath logical unit s load balancing policy.
2325 * @param logicalUnitoid
2326 * The object ID of the multipath logical unit.
2328 * @param loadBanlance
2329 * The desired load balance policy for the specified logical unit.
2331 * @return An MP_STATUS indicating if the operation was successful or if
2332 * an error occurred.
2334 * @retval MP_STATUS_SUCCESS
2335 * Returned when the operation is successful.
2337 * @retval MP_STATUS_INVALID_PARAMETER
2338 * Returned if no MP_MULTIPATH_LOGICAL_UNIT associated with
2339 * @ref ligicalUnitrOid is found or invalid MP_LOAD_BALANCE_TYPE is
2342 * @retval MP_STATUS_FAILED
2343 * Returned when the specified loadBalance type cannot be handled
2346 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2347 * Returned if oid does not specify any valid object type.
2349 *******************************************************************************
2351 MP_STATUS
MP_SetLogicalUnitLoadBalanceType(
2352 MP_OID logicalUnitOid
,
2353 MP_LOAD_BALANCE_TYPE loadBalance
)
2355 MP_SetLogicalUnitLoadBalanceTypeFn PassFunc
;
2359 if ((status
= validate_object(logicalUnitOid
,
2360 MP_OBJECT_TYPE_MULTIPATH_LU
,
2361 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2365 (void) pthread_mutex_lock(&mp_lib_mutex
);
2367 index
= logicalUnitOid
.ownerId
- 1;
2368 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2369 PassFunc
= (MP_SetLogicalUnitLoadBalanceTypeFn
)
2370 dlsym(plugintable
[index
].hdlPlugin
,
2371 "MP_SetLogicalUnitLoadBalanceType");
2373 if (PassFunc
!= NULL
) {
2374 status
= PassFunc(logicalUnitOid
, loadBalance
);
2376 status
= MP_STATUS_UNSUPPORTED
;
2379 status
= MP_STATUS_FAILED
;
2382 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2387 *******************************************************************************
2389 * Set the weight to be assigned to a particular path.
2392 * The object ID of the path logical unit.
2395 * weight that will be assigned to the path logical unit.
2397 * @return An MP_STATUS indicating if the operation was successful or if
2398 * an error occurred.
2400 * @retval MP_STATUS_SUCCESS
2401 * Returned when the operation is successful.
2403 * @retval MP_STATUS_OBJECT_NOT_FOUND
2404 * Returned when the MP Path specified by the PathOid could not be
2407 * @retval MP_STATUS_UNSUPPORTED
2408 * Returned when the implementation does not support the API
2410 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2411 * Returned if oid does not specify any valid object type.
2413 * @retval MP_STATUS_FAILED
2414 * Returned when the operation failed.
2416 * @retval MP_STATUS_PATH_NONOPERATIONAL
2417 * Returned when the driver cannot communicate through selected path.
2419 * @retval MP_STATUS_INVALID_WEIGHT
2420 * Returned when the weight parameter is greater than the plugin's
2421 * maxWeight property.
2423 *******************************************************************************
2425 MP_STATUS
MP_SetPathWeight(
2429 MP_SetPathWeightFn PassFunc
;
2433 if ((status
= validate_object(pathOid
, MP_OBJECT_TYPE_PATH_LU
,
2434 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2438 (void) pthread_mutex_lock(&mp_lib_mutex
);
2440 index
= pathOid
.ownerId
- 1;
2441 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2442 PassFunc
= (MP_SetPathWeightFn
)
2443 dlsym(plugintable
[index
].hdlPlugin
,
2444 "MP_SetPathWeight");
2446 if (PassFunc
!= NULL
) {
2447 status
= PassFunc(pathOid
, weight
);
2449 status
= MP_STATUS_UNSUPPORTED
;
2452 status
= MP_STATUS_FAILED
;
2455 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2460 *******************************************************************************
2462 * Set the default load balance policy for the plugin.
2465 * The object ID of the plugin
2467 * @param loadBalance
2468 * The desired default load balance policy for the specified plugin.
2470 * @return An MP_STATUS indicating if the operation was successful or if
2471 * an error occurred.
2473 * @retval MP_STATUS_SUCCESS
2474 * Returned when the operation is successful.
2476 * @retval MP_STATUS_OBJECT_NOT_FOUND
2477 * Returned when the the plugin specified by @ref oid could not be
2480 * @retval MP_STATUS_INVALID_PARAMETER
2481 * Returned if the oid of the object is not valid.
2483 * @retval MP_STATUS_UNSUPPORTED
2484 * Returned when the implementation does not support the API
2486 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2487 * Returned if oid does not specify any valid object type.
2489 * @retval MP_STATUS_FAILED
2490 * Returned when the specified loadBalance type cannot be handled
2493 *******************************************************************************
2495 MP_STATUS
MP_SetPluginLoadBalanceType(
2497 MP_LOAD_BALANCE_TYPE loadBalance
)
2499 MP_SetPluginLoadBalanceTypePluginFn PassFunc
;
2503 if ((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2504 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2508 (void) pthread_mutex_lock(&mp_lib_mutex
);
2510 index
= oid
.ownerId
- 1;
2511 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2512 PassFunc
= (MP_SetPluginLoadBalanceTypePluginFn
)
2513 dlsym(plugintable
[index
].hdlPlugin
,
2514 "MP_SetPluginLoadBalanceTypePlugin");
2516 if (PassFunc
!= NULL
) {
2517 status
= PassFunc(loadBalance
);
2519 status
= MP_STATUS_UNSUPPORTED
;
2522 status
= MP_STATUS_FAILED
;
2525 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2530 *******************************************************************************
2532 * Set the failback polling rates. Setting both rates to zero disables polling.
2535 * The object ID of the plugin or multipath lu.
2537 * @param pollingRate
2538 * The value to be set in MP_PLUGIN_PROPERTIES currentPollingRate.or
2539 * MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES pollingRate.
2541 * @return An MP_STATUS indicating if the operation was successful or if
2542 * an error occurred.
2544 * @retval MP_STATUS_SUCCESS
2545 * Returned when the operation is successful.
2547 * @retval MP_STATUS_OBJECT_NOT_FOUND
2548 * Returned when the the plugin specified by @ref oid could not be
2551 * @retval MP_STATUS_INVALID_PARAMETER
2552 * Returned if one of the polling values is outside the range
2553 * supported by the driver.
2555 * @retval MP_STATUS_UNSUPPORTED
2556 * Returned when the implementation does not support the API
2558 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2559 * Returned if oid does not specify any valid object type.
2561 *******************************************************************************
2563 MP_STATUS
MP_SetFailbackPollingRate(
2565 MP_UINT32 pollingRate
)
2570 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2571 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2572 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2573 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
2577 (void) pthread_mutex_lock(&mp_lib_mutex
);
2579 index
= oid
.ownerId
- 1;
2580 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2581 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
2582 MP_SetFailbackPollingRatePluginFn PassFunc
;
2583 PassFunc
= (MP_SetFailbackPollingRatePluginFn
)
2584 dlsym(plugintable
[index
].hdlPlugin
,
2585 "MP_SetFailbackPollingRatePlugin");
2587 if (PassFunc
!= NULL
) {
2588 status
= PassFunc(pollingRate
);
2590 status
= MP_STATUS_UNSUPPORTED
;
2592 } else if (oid
.objectType
== MP_OBJECT_TYPE_MULTIPATH_LU
) {
2593 MP_SetFailbackPollingRateLuFn PassFunc
;
2594 PassFunc
= (MP_SetFailbackPollingRateLuFn
)
2595 dlsym(plugintable
[index
].hdlPlugin
,
2596 "MP_SetFailbackPollingRateLu");
2598 if (PassFunc
!= NULL
) {
2599 status
= PassFunc(oid
, pollingRate
);
2601 status
= MP_STATUS_UNSUPPORTED
;
2604 status
= MP_STATUS_INVALID_PARAMETER
;
2608 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2613 *******************************************************************************
2615 * Set the probing polling rates. Setting both rates to zero disables polling.
2618 * The object ID of either the plugin or a multipath logical unit.
2620 * @param pollingRate
2621 * The value to be set in MP_PLUGIN_PROPERTIES current pollingRate or
2622 * MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES pollingRate.
2624 * @return An MP_STATUS indicating if the operation was successful or if
2625 * an error occurred.
2627 * @retval MP_STATUS_SUCCESS
2628 * Returned when the operation is successful.
2630 * @retval MP_STATUS_OBJECT_NOT_FOUND
2631 * Returned when the the plugin specified by @ref oid could not be
2634 * @retval MP_STATUS_INVALID_PARAMETER
2635 * Returned if one of the polling values is outside the range
2636 * supported by the driver.
2638 * @retval MP_STATUS_UNSUPPORTED
2639 * Returned when the implementation does not support the API
2641 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2642 * Returned if oid does not specify any valid object type.
2644 *******************************************************************************
2646 MP_STATUS
MP_SetProbingPollingRate(
2648 MP_UINT32 pollingRate
)
2653 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2654 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2655 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2656 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
2660 (void) pthread_mutex_lock(&mp_lib_mutex
);
2662 index
= oid
.ownerId
- 1;
2663 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2664 if (oid
.objectType
== MP_OBJECT_TYPE_PLUGIN
) {
2665 MP_SetProbingPollingRatePluginFn PassFunc
;
2666 PassFunc
= (MP_SetProbingPollingRatePluginFn
)
2667 dlsym(plugintable
[index
].hdlPlugin
,
2668 "MP_SetProbingPollingRatePlugin");
2670 if (PassFunc
!= NULL
) {
2671 status
= PassFunc(pollingRate
);
2673 status
= MP_STATUS_UNSUPPORTED
;
2675 } else if (oid
.objectType
== MP_OBJECT_TYPE_MULTIPATH_LU
) {
2676 MP_SetProbingPollingRateLuFn PassFunc
;
2677 PassFunc
= (MP_SetProbingPollingRateLuFn
)
2678 dlsym(plugintable
[index
].hdlPlugin
,
2679 "MP_SetProbingPollingRateLu");
2681 if (PassFunc
!= NULL
) {
2682 status
= PassFunc(oid
, pollingRate
);
2684 status
= MP_STATUS_UNSUPPORTED
;
2687 status
= MP_STATUS_INVALID_PARAMETER
;
2691 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2696 *******************************************************************************
2698 * Set proprietary properties in supported object instances.
2701 * The object ID of MP_LOAD_BALANCE_PROPRIETARY_TYPE, MP_PLUGIN_PROPERTIES
2702 * or MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES.
2705 * The number of valid items in pPropertyList.
2707 * @param pPropertyList
2708 * A pointer to an array of property name/value pairs. This array must
2709 * contain the same number of elements as count.
2711 * @return An MP_STATUS indicating if the operation was successful or if
2712 * an error occurred.
2714 * @retval MP_STATUS_SUCCESS
2715 * Returned when the operation is successful.
2717 * @retval MP_STATUS_OBJECT_NOT_FOUND
2718 * Returned when the the plugin specified by @ref oid could not be
2721 * @retval MP_STATUS_INVALID_PARAMETER
2722 * Returned if one of the polling values is outside the range
2723 * supported by the driver.
2725 * @retval MP_STATUS_UNSUPPORTED
2726 * Returned when the implementation does not support the API
2728 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2729 * Returned if oid does not specify any valid object type.
2731 *******************************************************************************
2733 MP_STATUS
MP_SetProprietaryProperties(
2736 MP_PROPRIETARY_PROPERTY
*pPropertyList
)
2738 MP_SetProprietaryPropertiesFn PassFunc
;
2742 if (((status
= validate_object(oid
, MP_OBJECT_TYPE_PLUGIN
,
2743 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2744 ((status
= validate_object(oid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2745 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) &&
2746 ((status
= validate_object(oid
, MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE
,
2747 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
)) {
2751 (void) pthread_mutex_lock(&mp_lib_mutex
);
2753 index
= oid
.ownerId
- 1;
2754 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2755 PassFunc
= (MP_SetProprietaryPropertiesFn
)
2756 dlsym(plugintable
[index
].hdlPlugin
,
2757 "MP_SetProprietaryProperties");
2759 if (PassFunc
!= NULL
) {
2760 status
= PassFunc(oid
, count
, pPropertyList
);
2762 status
= MP_STATUS_UNSUPPORTED
;
2765 status
= MP_STATUS_FAILED
;
2768 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2773 *******************************************************************************
2775 * Set the access state for a list of target port groups. This allows
2776 * a client to force a failover or failback to a desired set of target port
2780 * The object ID of the logical unit where the command is sent.
2783 * The number of valid items in the pTpgStateList.
2785 * @param pTpgStateList
2786 * A pointer to an array of TPG/access-state values. This array must
2787 * contain the same number of elements as @ref count.
2789 * @return An MP_STATUS indicating if the operation was successful or if
2790 * an error occurred.
2792 * @retval MP_STATUS_SUCCESS
2793 * Returned when the operation is successful.
2795 * @retval MP_STATUS_OBJECT_NOT_FOUND
2796 * Returned when the MP_MULTIPATH_LOGICAL_UNIT associated with @ref
2797 * oid could not be found.
2799 * @retval MP_STATUS_INVALID_PARAMETER
2800 * Returned if pTpgStateList is null or if one of the TPGs referenced
2801 * in the list is not associated with the specified MP logical unit.
2803 * @retval MP_STATUS_UNSUPPORTED
2804 * Returned when the implementation does not support the API
2806 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2807 * Returned if oid does not specify any valid object type.
2809 * @retval MP_STATUS_ACCESS_STATE_INVALID
2810 * Returned if the target device returns a status indicating the caller
2811 * is attempting to establish an illegal combination of access states.
2813 * @retval MP_STATUS_FAILED
2814 * Returned if the underlying interface failed the commend for some
2815 * reason other than MP_STATUS_ACCESS_STATE_INVALID
2817 *******************************************************************************
2819 MP_STATUS
MP_SetTPGAccess(
2822 MP_TPG_STATE_PAIR
*pTpgStateList
)
2824 MP_SetTPGAccessFn PassFunc
;
2828 if ((status
= validate_object(luOid
, MP_OBJECT_TYPE_MULTIPATH_LU
,
2829 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2833 (void) pthread_mutex_lock(&mp_lib_mutex
);
2835 index
= luOid
.ownerId
- 1;
2836 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2837 PassFunc
= (MP_SetTPGAccessFn
)
2838 dlsym(plugintable
[index
].hdlPlugin
,
2841 if (PassFunc
!= NULL
) {
2842 status
= PassFunc(luOid
, count
, pTpgStateList
);
2844 status
= MP_STATUS_UNSUPPORTED
;
2847 status
= MP_STATUS_FAILED
;
2850 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2855 *******************************************************************************
2857 * Registers a client function that is to be called
2858 * whenever the property of an an object changes.
2861 * A pointer to an MP_OBJECT_PROPERTY_FN function defined by the
2862 * client. On successful return this function will be called to
2863 * inform the client of objects that have had one or more properties
2867 * The type of object the client wishes to deregister for
2868 * property change callbacks. If null, then all objects types are
2871 * @param pCallerData
2872 * A pointer that is passed to the callback routine with each event.
2873 * This may be used by the caller to correlate the event to source of
2876 * @return An MP_STATUS indicating if the operation was successful or if
2877 * an error occurred.
2879 * @retval MP_STATUS_SUCCESS
2880 * Returned when the operation is successful.
2882 * @retval MP_STATUS_INVALID_PARAMETER
2883 * Returned if pClientFn is NULL or specifies a memory area
2884 * that is not executable.
2886 * @retval MP_STATUS_FN_REPLACED
2887 * Returned when an existing client function is replaced with the one
2888 * specified in pClientFn.
2890 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2891 * Returned if oid does not specify any valid object type.
2893 *******************************************************************************
2895 MP_STATUS
MP_RegisterForObjectPropertyChanges(
2896 MP_OBJECT_PROPERTY_FN pClientFn
,
2897 MP_OBJECT_TYPE objectType
,
2901 MP_RegisterForObjectPropertyChangesPluginFn PassFunc
;
2906 if (pClientFn
== NULL
) {
2907 return (MP_STATUS_INVALID_PARAMETER
);
2910 if (objectType
> MP_OBJECT_TYPE_MAX
) {
2911 return (MP_STATUS_INVALID_OBJECT_TYPE
);
2914 if (!(is_zero_oid(pluginOid
))) {
2915 if ((status
= validate_object(pluginOid
, MP_OBJECT_TYPE_PLUGIN
,
2916 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
2921 (void) pthread_mutex_lock(&mp_lib_mutex
);
2923 if (is_zero_oid(pluginOid
)) {
2924 for (i
= 0; i
< number_of_plugins
; i
++) {
2925 if (plugintable
[i
].hdlPlugin
!= NULL
) {
2926 PassFunc
= (MP_RegisterForObjectPropertyChangesPluginFn
)
2927 dlsym(plugintable
[i
].hdlPlugin
,
2928 "MP_RegisterForObjectPropertyChangesPlugin");
2931 if (PassFunc
!= NULL
) {
2933 PassFunc(pClientFn
, objectType
, pCallerData
);
2934 /* ignore an error and continue */
2938 index
= pluginOid
.ownerId
- 1;
2939 if (plugintable
[index
].hdlPlugin
!= NULL
) {
2940 PassFunc
= (MP_RegisterForObjectPropertyChangesPluginFn
)
2941 dlsym(plugintable
[index
].hdlPlugin
,
2942 "MP_RegisterForObjectPropertyChangesPlugin");
2945 if (PassFunc
!= NULL
) {
2946 status
= PassFunc(pClientFn
, objectType
, pCallerData
);
2949 (void) pthread_mutex_unlock(&mp_lib_mutex
);
2954 *******************************************************************************
2956 * Deregisters a previously registered client function that is to be invoked
2957 * whenever an object's property changes.
2960 * A pointer to an MP_OBJECT_PROPERTY_FN function defined by the
2961 * client that was previously registered using
2962 * the MP_RegisterForObjectPropertyChanges API. On successful return
2963 * this function will no longer be called to inform the client of
2964 * object property changes.
2967 * The type of object the client wishes to deregister for
2968 * property change callbacks. If null, then all objects types are
2971 * @return An MP_STATUS indicating if the operation was successful or if
2972 * an error occurred.
2974 * @retval MP_STATUS_SUCCESS
2975 * Returned when the operation is successful.
2977 * @retval MP_STATUS_INVALID_PARAMETER
2978 * Returned if pClientFn is NULL or specifies a memory area
2979 * that is not executable.
2981 * @retval MP_STATUS_UNKNOWN_FN
2982 * Returned if pClientFn is not the same as the previously registered
2985 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2986 * Returned if oid does not specify any valid object type.
2988 * @retval MP_STATUS_FAILED
2989 * Returned if pClientFn deregistration is not possible at this time.
2991 *******************************************************************************
2993 MP_STATUS
MP_DeregisterForObjectPropertyChanges(
2994 MP_OBJECT_PROPERTY_FN pClientFn
,
2995 MP_OBJECT_TYPE objectType
,
2998 MP_DeregisterForObjectPropertyChangesPluginFn PassFunc
;
3003 if (pClientFn
== NULL
) {
3004 return (MP_STATUS_INVALID_PARAMETER
);
3007 if (objectType
> MP_OBJECT_TYPE_MAX
) {
3008 return (MP_STATUS_INVALID_OBJECT_TYPE
);
3011 if (!(is_zero_oid(pluginOid
))) {
3012 if ((status
= validate_object(pluginOid
, MP_OBJECT_TYPE_PLUGIN
,
3013 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
3018 (void) pthread_mutex_lock(&mp_lib_mutex
);
3020 if (is_zero_oid(pluginOid
)) {
3021 for (i
= 0; i
< number_of_plugins
; i
++) {
3022 if (plugintable
[i
].hdlPlugin
!= NULL
) {
3023 PassFunc
= (MP_DeregisterForObjectPropertyChangesPluginFn
)
3024 dlsym(plugintable
[i
].hdlPlugin
,
3025 "MP_DeregisterForObjectPropertyChangesPlugin");
3028 if (PassFunc
!= NULL
) {
3029 status
= PassFunc(pClientFn
, objectType
);
3033 index
= pluginOid
.ownerId
- 1;
3034 if (plugintable
[index
].hdlPlugin
!= NULL
) {
3035 PassFunc
= (MP_DeregisterForObjectPropertyChangesPluginFn
)
3036 dlsym(plugintable
[index
].hdlPlugin
,
3037 "MP_DeregisterForObjectPropertyChangesPlugin");
3040 if (PassFunc
!= NULL
) {
3041 status
= PassFunc(pClientFn
, objectType
);
3044 (void) pthread_mutex_unlock(&mp_lib_mutex
);
3049 *******************************************************************************
3051 * Registers a client function that is to be called
3052 * whenever a high level object appears or disappears.
3055 * A pointer to an MP_OBJECT_VISIBILITY_FN function defined by the
3056 * client. On successful return this function will be called to
3057 * inform the client of objects whose visibility has changed.
3060 * The type of object the client wishes to deregister for
3061 * property change callbacks. If null, then all objects types are
3064 * @param pCallerData
3065 * A pointer that is passed to the callback routine with each event.
3066 * This may be used by the caller to correlate the event to source of
3069 * @return An MP_STATUS indicating if the operation was successful or if
3070 * an error occurred.
3072 * @retval MP_STATUS_SUCCESS
3073 * Returned when the operation is successful.
3075 * @retval MP_STATUS_INVALID_PARAMETER
3076 * Returned if pClientFn is NULL or specifies a memory area
3077 * that is not executable.
3079 * @retval MP_STATUS_FN_REPLACED
3080 * Returned when an existing client function is replaced with the one
3081 * specified in pClientFn.
3083 * @retval MP_STATUS_INVALID_OBJECT_TYPE
3084 * Returned if objectType does not specify any valid object type.
3086 *******************************************************************************
3088 MP_STATUS
MP_RegisterForObjectVisibilityChanges(
3089 MP_OBJECT_VISIBILITY_FN pClientFn
,
3090 MP_OBJECT_TYPE objectType
,
3094 MP_RegisterForObjectVisibilityChangesPluginFn PassFunc
;
3099 if (pClientFn
== NULL
) {
3100 return (MP_STATUS_INVALID_PARAMETER
);
3103 if (objectType
> MP_OBJECT_TYPE_MAX
) {
3104 return (MP_STATUS_INVALID_OBJECT_TYPE
);
3107 if (!(is_zero_oid(pluginOid
))) {
3108 if ((status
= validate_object(pluginOid
, MP_OBJECT_TYPE_PLUGIN
,
3109 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
3114 (void) pthread_mutex_lock(&mp_lib_mutex
);
3116 if (is_zero_oid(pluginOid
)) {
3117 for (i
= 0; i
< number_of_plugins
; i
++) {
3118 if (plugintable
[i
].hdlPlugin
!= NULL
) {
3119 PassFunc
= (MP_RegisterForObjectVisibilityChangesPluginFn
)
3120 dlsym(plugintable
[i
].hdlPlugin
,
3121 "MP_RegisterForObjectVisibilityChangesPlugin");
3124 if (PassFunc
!= NULL
) {
3125 status
= PassFunc(pClientFn
, objectType
, pCallerData
);
3126 /* ignore an error and continue. */
3130 index
= pluginOid
.ownerId
- 1;
3131 if (plugintable
[index
].hdlPlugin
!= NULL
) {
3132 PassFunc
= (MP_RegisterForObjectVisibilityChangesPluginFn
)
3133 dlsym(plugintable
[index
].hdlPlugin
,
3134 "MP_RegisterForObjectVisibilityChangesPlugin");
3137 if (PassFunc
!= NULL
) {
3138 status
= PassFunc(pClientFn
, objectType
, pCallerData
);
3141 (void) pthread_mutex_unlock(&mp_lib_mutex
);
3147 *******************************************************************************
3149 * Deregisters a previously registered client function that is to be invoked
3150 * whenever a high level object appears or disappears.
3153 * A pointer to an MP_OBJECT_VISIBILITY_FN function defined by the
3154 * client that was previously registered using
3155 * the MP_RegisterForObjectVisibilityChanges API. On successful return
3156 * this function will no longer be called to inform the client of
3157 * object property changes.
3160 * The type of object the client wishes to deregister for visibility
3161 * change callbacks. If null, then all objects types are
3164 * @return An MP_STATUS indicating if the operation was successful or if
3165 * an error occurred.
3167 * @retval MP_STATUS_SUCCESS
3168 * Returned when the operation is successful.
3170 * @retval MP_STATUS_INVALID_PARAMETER
3171 * Returned if pClientFn is NULL or specifies a memory area
3172 * that is not executable.
3174 * @retval MP_STATUS_UNKNOWN_FN
3175 * Returned if pClientFn is not the same as the previously registered
3178 * @retval MP_STATUS_INVALID_OBJECT_TYPE
3179 * Returned if objectType does not specify any valid object type.
3181 * @retval MP_STATUS_FAILED
3182 * Returned if pClientFn deregistration is not possible at this time.
3184 *******************************************************************************
3186 MP_STATUS
MP_DeregisterForObjectVisibilityChanges(
3187 MP_OBJECT_VISIBILITY_FN pClientFn
,
3188 MP_OBJECT_TYPE objectType
,
3191 MP_DeregisterForObjectVisibilityChangesPluginFn PassFunc
;
3196 if (pClientFn
== NULL
) {
3197 return (MP_STATUS_INVALID_PARAMETER
);
3200 if (objectType
> MP_OBJECT_TYPE_MAX
) {
3201 return (MP_STATUS_INVALID_OBJECT_TYPE
);
3204 if (!(is_zero_oid(pluginOid
))) {
3205 if ((status
= validate_object(pluginOid
, MP_OBJECT_TYPE_PLUGIN
,
3206 MP_OBJECT_TYPE_MATCH
)) != MP_STATUS_SUCCESS
) {
3211 (void) pthread_mutex_lock(&mp_lib_mutex
);
3213 if (is_zero_oid(pluginOid
)) {
3214 for (i
= 0; i
< number_of_plugins
; i
++) {
3215 if (plugintable
[i
].hdlPlugin
!= NULL
) {
3216 PassFunc
= (MP_DeregisterForObjectVisibilityChangesPluginFn
)
3217 dlsym(plugintable
[i
].hdlPlugin
,
3218 "MP_DeregisterForObjectVisibilityChangesPlugin");
3219 if (PassFunc
!= NULL
) {
3220 status
= PassFunc(pClientFn
, objectType
);
3225 index
= pluginOid
.ownerId
- 1;
3226 if (plugintable
[index
].hdlPlugin
!= NULL
) {
3227 PassFunc
= (MP_DeregisterForObjectVisibilityChangesPluginFn
)
3228 dlsym(plugintable
[index
].hdlPlugin
,
3229 "MP_DeregisterForObjectVisibilityChangesPlugin");
3230 if (PassFunc
!= NULL
) {
3231 status
= PassFunc(pClientFn
, objectType
);
3236 (void) pthread_mutex_unlock(&mp_lib_mutex
);
3241 *******************************************************************************
3243 * Compare two Oids for equality to see whether they refer to the same object.
3251 * @return An MP_STATUS indicating if the operation was successful or if
3252 * an error occurred.
3254 * @retval MP_STATUS_SUCCESS
3255 * Returned when the two Oids do refer to the same object.
3257 * @retval MP_STATUS_FAILED
3258 * Returned if the Oids don't compare.
3260 *******************************************************************************
3262 MP_STATUS
MP_CompareOIDs(
3266 if ((oid1
.objectType
== oid2
.objectType
) && (oid1
.ownerId
== oid2
.ownerId
)
3267 && (oid1
.objectSequenceNumber
== oid2
.objectSequenceNumber
)) {
3268 return (MP_STATUS_SUCCESS
);
3270 return (MP_STATUS_FAILED
);
3275 *******************************************************************************
3277 * Frees memory returned by an MP API.
3280 * A pointer to the memory returned by an MP API. On successful
3281 return, the allocated memory is freed.
3283 * @return An MP_STATUS indicating if the operation was successful or if
3284 * an error occurred.
3286 * @retval MP_STATUS_SUCCESS
3287 * Returned when pPluginId is deregistered successfully.
3289 * @retval MP_STATUS_INVALID_PARAMETER
3290 * Returned if pMemory is NULL or specifies a memory area to which
3291 * data cannot be written.
3293 *******************************************************************************
3295 MP_STATUS
MP_FreeOidList(MP_OID_LIST
*pOidList
)
3297 if (pOidList
== NULL
) {
3298 return (MP_STATUS_INVALID_PARAMETER
);
3303 return (MP_STATUS_SUCCESS
);
3306 static MP_CHAR
*HDR
=
3308 "# This file contains names and references to MP API plugin libraries\n"
3310 "# Do NOT manually edit this file\n"
3314 "# <library ID> <library pathname>\n"
3317 #define CLEANUP_N_RET(fd, ret) \
3318 if (lock_register(fd, F_SETLK, F_UNLCK, 0, SEEK_SET, 0) < 0) { \
3320 return (MP_STATUS_FAILED); \
3326 * This function sets an advisory lock on the file pointed to by the argument
3327 * fd, which is a file descriptor. The lock is set using fcntl() which uses
3331 lock_register(int fd
, int cmd
, int type
, off_t offset
, int whence
, off_t len
)
3336 lock
.l_start
= offset
;
3337 lock
.l_whence
= whence
;
3340 return (fcntl(fd
, cmd
, &lock
));
3344 * This function searches for "srch_str" (of length "slen") in "buf" (of length
3345 * "buflen"). If it is not found, "write_offset" has the offset in "buf" where
3346 * "srch_str" would have to be added in "buf". If "srch_str" is found in "buf",
3347 * "write_offset" has its offset in "buf"
3350 * buf - buffer to search in
3351 * buflen - length of buffer
3352 * srch_id - id to search
3353 * id_len - length of srch_id
3354 * write_offset - Set in function on exit
3355 * - It is the offset in buf where srch_str is or should be
3356 * bytes_left - Set in function on exit
3357 * - It is the # of bytes left beyond write_offset in buf
3359 * Zero - "srch_id" found in "buf"... "write_offset" has offset in "buf"
3360 * != 0 - "srch_str" NOT found in "buf" ... "write_offset" points to the end of
3364 search_line(MP_CHAR
*buf
, size_t buflen
, MP_CHAR
*srch_id
, size_t id_len
,
3365 int *write_offset
, int *bytes_left
)
3367 int retval
, sizeof_conf_hdr
= strlen(HDR
);
3368 MP_CHAR
*sol
; /* Pointer to Start-Of-Line */
3369 MP_CHAR
*cur_pos
; /* current position */
3371 *bytes_left
= buflen
;
3374 if (buf
== NULL
|| buflen
<= 0)
3377 if (srch_id
== NULL
|| id_len
<= 0)
3380 sol
= cur_pos
= buf
;
3383 * mp conf file should not be edited but takes care of
3384 * any extra white space when parsing the line.
3386 * The line should have id + delimiter + name + newline.
3388 while (*bytes_left
>= (id_len
+ 3)) {
3389 /* skip leading blank or space. */
3390 while ((*cur_pos
== ' ') || (*cur_pos
== '\t')) {
3394 if (strncmp(cur_pos
, srch_id
, id_len
) == 0) {
3398 while (*cur_pos
!= '\n') {
3401 *write_offset
= (sol
- buf
);
3402 *bytes_left
= buflen
- ((cur_pos
+ 1) - buf
);
3405 /* move to the next line */
3406 while (*cur_pos
!= '\n') {
3409 *bytes_left
= buflen
- ((cur_pos
+ 1) - buf
);
3411 sol
= cur_pos
= cur_pos
+ 1;
3414 /* Given strings are not found. */
3415 *write_offset
= buflen
;
3420 *******************************************************************************
3422 * Registers a plugin with common library. The implementation of this routine
3423 * is based on configuration file /etc/mpapi.conf that contains a list of
3427 * A pointer to the key name shall be the reversed domain name of
3428 * the vendor followed by followed by the vendor specific name for
3429 * the plugin that uniquely identifies the plugin. Should be NULL
3433 * The full path to the plugin library.
3434 * Should be NULL terminated.
3436 * @return An MP_STATUS indicating if the operation was successful or if
3437 * an error occurred.
3439 * @retval MP_STATUS_SUCCESS
3440 * Returned when pPluginId is deregistered successfully.
3442 * @retval MP_STATUS_INVALID_PARAMETER
3443 * Returned if pPluginId is NULL or specifies a memory area that
3444 * is not executable.
3446 * @retval MP_STATUS_FAILED
3447 * Returned if pClientFn deregistration is not possible at this time.
3449 *******************************************************************************
3451 MP_STATUS
MP_RegisterPlugin(
3452 MP_WCHAR
*pPluginId
,
3455 int mpconf
, bytes_left
, write_offset
;
3456 MP_CHAR fullline
[MAX_LINE_SIZE
]; /* Full line to add to mpapi.conf */
3457 MP_CHAR
*mpconf_buf
;
3458 MP_CHAR pluginid
[MAX_NAME_SIZE
];
3459 char systemPath
[MAX_NAME_SIZE
], mpConfFilePath
[MAX_NAME_SIZE
];
3460 MP_UINT32 new_file_flag
= 0;
3461 MP_UINT32 sizeof_conf_hdr
= strlen(HDR
);
3464 if ((pPluginId
== NULL
) || (pFileName
== NULL
)) {
3465 return (MP_STATUS_INVALID_PARAMETER
);
3468 if (stat(pFileName
, &stbuf
) != 0) {
3469 return (MP_STATUS_INVALID_PARAMETER
);
3472 if (wcstombs(pluginid
, pPluginId
, MAX_NAME_SIZE
) != wcslen(pPluginId
)) {
3473 return (MP_STATUS_INVALID_PARAMETER
);
3477 strncpy(fullline
, pluginid
, MAX_NAME_SIZE
);
3479 strncat(fullline
, "\t", MAX_LINE_SIZE
- strlen(pluginid
));
3480 strncat(fullline
, pFileName
, MAX_LINE_SIZE
- strlen(pluginid
) - 1);
3481 /* add a new line. */
3482 strncat(fullline
, "\n",
3483 MAX_LINE_SIZE
- strlen(pluginid
) - strlen(pFileName
) -1);
3485 /* Open configuration file from known location */
3486 strncpy(mpConfFilePath
, "/etc/mpapi.conf", MAX_NAME_SIZE
);
3488 if ((chmod(mpConfFilePath
, S_IRUSR
|S_IRGRP
|S_IROTH
) == -1) &&
3489 (errno
== ENOENT
)) {
3493 if ((mpconf
= open(mpConfFilePath
, O_RDWR
| O_CREAT
)) == -1) {
3494 return (MP_STATUS_FAILED
);
3497 if (fchmod(mpconf
, S_IRUSR
| S_IRGRP
| S_IROTH
) < 0) {
3499 return (MP_STATUS_FAILED
);
3502 if (lock_register(mpconf
, F_SETLKW
, F_WRLCK
, 0, SEEK_SET
, 0) < 0) {
3504 return (MP_STATUS_FAILED
);
3507 if (fstat(mpconf
, &stbuf
) == -1) {
3508 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3511 if ((new_file_flag
) || (stbuf
.st_size
== 0)) {
3512 if (write(mpconf
, HDR
, sizeof_conf_hdr
) !=
3514 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3517 if (pwrite(mpconf
, fullline
, strlen(fullline
),
3520 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3522 CLEANUP_N_RET(mpconf
, MP_STATUS_SUCCESS
);
3525 if ((mpconf_buf
= mmap(NULL
, stbuf
.st_size
,
3526 PROT_READ
| PROT_WRITE
,
3527 MAP_SHARED
, mpconf
, 0)) == MAP_FAILED
) {
3528 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3531 if (search_line(mpconf_buf
, stbuf
.st_size
,
3532 pluginid
, strlen(pluginid
), &write_offset
, &bytes_left
) == 0) {
3533 /* found a match. */
3534 munmap((void *)mpconf_buf
, stbuf
.st_size
);
3535 CLEANUP_N_RET(mpconf
, MP_STATUS_SUCCESS
);
3537 munmap((void *)mpconf_buf
, stbuf
.st_size
);
3538 /* append the fullline to the mpconf. */
3539 if (pwrite(mpconf
, fullline
, strlen(fullline
),
3542 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3544 CLEANUP_N_RET(mpconf
, MP_STATUS_SUCCESS
);
3550 *******************************************************************************
3552 * Deregisters a plugin from the common library. This routine is based on
3553 * configuration file /etc/mpapi.conf that contains a list of plugin libraries.
3556 * A pointer to a Plugin ID previously registered using
3557 * the MP_RegisterPlugin API..
3559 * @return An MP_STATUS indicating if the operation was successful or if
3560 * an error occurred.
3562 * @retval MP_STATUS_SUCCESS
3563 * Returned when pPluginId is deregistered successfully.
3565 * @retval MP_STATUS_INVALID_PARAMETER
3566 * Returned if pPluginId is NULL or specifies a memory area that
3567 * is not executable.
3569 * @retval MP_STATUS_FAILED
3570 * Returned if pClientFn deregistration is not possible at this time.
3572 *******************************************************************************
3574 MP_STATUS
MP_DeregisterPlugin(
3575 MP_WCHAR
*pPluginId
)
3577 int mpconf
, tmp_mpconf
, bytes_left
, write_offset
;
3578 char systemPath
[MAX_NAME_SIZE
], mpConfFilePath
[MAX_NAME_SIZE
],
3579 tmp_mpConfFilePath
[MAX_NAME_SIZE
+ sizeof(pid_t
)];
3580 MP_CHAR pluginid
[MAX_NAME_SIZE
];
3581 MP_CHAR
*mpconf_buf
;
3582 MP_UINT32 sizeof_conf_hdr
= strlen(HDR
);
3585 if (pPluginId
== NULL
) {
3586 return (MP_STATUS_INVALID_PARAMETER
);
3589 if (wcstombs(pluginid
, pPluginId
, MAX_NAME_SIZE
) != wcslen(pPluginId
)) {
3590 return (MP_STATUS_INVALID_PARAMETER
);
3593 /* Open configuration file from known location */
3594 strncpy(mpConfFilePath
, "/etc/mpapi.conf", MAX_NAME_SIZE
);
3596 if ((chmod(mpConfFilePath
, S_IRUSR
|S_IRGRP
|S_IROTH
) == -1) &&
3597 (errno
== ENOENT
)) {
3599 return (MP_STATUS_UNKNOWN_FN
);
3602 if ((mpconf
= open(mpConfFilePath
, O_RDWR
)) == -1) {
3603 return (MP_STATUS_FAILED
);
3606 if (fchmod(mpconf
, S_IRUSR
| S_IRGRP
| S_IROTH
) < 0) {
3608 return (MP_STATUS_FAILED
);
3611 if (lock_register(mpconf
, F_SETLKW
, F_WRLCK
, 0, SEEK_SET
, 0) < 0) {
3613 return (MP_STATUS_FAILED
);
3616 if (fstat(mpconf
, &stbuf
) == -1) {
3617 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3620 if (stbuf
.st_size
== 0) {
3621 CLEANUP_N_RET(mpconf
, MP_STATUS_SUCCESS
);
3624 if ((mpconf_buf
= mmap(NULL
, stbuf
.st_size
,
3625 PROT_READ
| PROT_WRITE
,
3626 MAP_SHARED
, mpconf
, 0)) == MAP_FAILED
) {
3627 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3630 if (search_line(mpconf_buf
, stbuf
.st_size
, pluginid
, strlen(pluginid
),
3631 &write_offset
, &bytes_left
) != 0) {
3632 munmap((void *)mpconf_buf
, stbuf
.st_size
);
3633 CLEANUP_N_RET(mpconf
, MP_STATUS_UNKNOWN_FN
);
3637 * construct temp file name using pid.
3639 (void) snprintf(tmp_mpConfFilePath
, MAX_NAME_SIZE
,
3640 "%s%ld", "/etc/mpapi.conf", getpid());
3642 if ((tmp_mpconf
= open(tmp_mpConfFilePath
,
3643 O_RDWR
|O_CREAT
|O_TRUNC
, S_IRUSR
| S_IWUSR
)) < 0) {
3644 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3647 if (write(tmp_mpconf
, mpconf_buf
, write_offset
) != write_offset
) {
3649 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3652 if (pwrite(tmp_mpconf
, mpconf_buf
+ (stbuf
.st_size
- bytes_left
),
3653 bytes_left
, write_offset
) != bytes_left
) {
3655 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3659 munmap((void *)mpconf_buf
, stbuf
.st_size
);
3661 /* rename temp file to mpConfFile before unlock and close. */
3662 if (rename(tmp_mpConfFilePath
, mpConfFilePath
) != 0) {
3663 CLEANUP_N_RET(mpconf
, MP_STATUS_FAILED
);
3665 CLEANUP_N_RET(mpconf
, MP_STATUS_SUCCESS
);