dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / mpapi / libmpapi / common / mpapi.c
blob346265232e6feddc0ee6d8e324e10c6c24aea794
1 /******************************************************************************
3 * Description
4 * mpapi.c - Implements Multipath Management API Version 1.0
6 * License:
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
16 * under the License.
18 * The Original Code is SNIA iSCSI Management API and Multipath Management
19 * API header files.
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)
27 * Contributor(s):
28 * Paul von Behren Sun Microsystems(paul.vonbehren@sun.com)
30 ******************************************************************************
32 * Changes:
33 * 1/15/2005 Implemented SNIA MP API specification 1.0
34 * 10/11/2005
35 * - License location was specified in the header comment.
36 * - validate_object() routine was updated per the latest
37 * specification.
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 ******************************************************************************
57 #include <sys/sem.h>
58 #include <dlfcn.h>
59 #include <stdarg.h>
60 #include <unistd.h>
61 #include <sys/stat.h>
62 #include <sys/types.h>
63 #include <sys/mman.h>
64 #include <errno.h>
65 #include <stdio.h>
66 #include <fcntl.h>
67 #include <time.h>
68 #include <pthread.h>
69 #include "mpapi.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;
86 void InitLibrary();
87 void ExitLibrary();
88 static int lock_register(int fd, int cmd, int type, off_t offset, int whence,
89 off_t len);
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);
94 /**
95 ******************************************************************************
97 * Validate the oid.
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
106 * argument.
107 * - Otherwise return MP_STATUS_SUCCESS.
109 ******************************************************************************
111 MP_STATUS validate_object(MP_OID obj, MP_OBJECT_TYPE objType,
112 MP_UINT32 flag)
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
141 * - Return 0 if not.
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)) {
150 return (0);
153 return (1);
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 ******************************************************************************
169 void InitLibrary()
171 FILE *mpconf;
172 int fd_mpconf;
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];
177 MP_WCHAR *charPtr;
178 MP_WCHAR *sol;
179 struct stat stat_buf;
181 MP_UINT32 i = 0; /* index for plugin table */
183 if(number_of_plugins != -1) {
184 return;
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);
196 return;
199 if (lock_register(fd_mpconf, F_SETLKW, F_RDLCK, 0, SEEK_SET, 0) < 0) {
200 close(fd_mpconf);
201 (void) pthread_mutex_unlock(&mp_lib_mutex);
202 return;
205 if ((mpconf = fdopen(fd_mpconf, "r")) == NULL) {
206 lock_register(fd_mpconf, F_SETLK, F_UNLCK, 0, SEEK_SET, 0);
207 close(fd_mpconf);
208 (void) pthread_mutex_unlock(&mp_lib_mutex);
209 return;
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)
218 *charPtr = L'\0';
220 charPtr = fullline;
221 /* remove leading blank or taps. */
222 while ((fullline[0] == L' ') || (fullline[0] == L'\t'))
223 charPtr++;
225 sol = charPtr;
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) {
235 *charPtr++ = L'\0';
236 wcsncpy(name, sol, MAX_NAME_SIZE);
237 /* Skip space and tab until the next character found */
238 while ((*charPtr == L' ') || (*charPtr == L'\t'))
239 charPtr++;
240 } else {
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
249 * invalid
251 if ((wcslen(name) == 0) ||
252 (strlen(path) == 0))
253 continue;
255 /* Load the plugin now */
256 if (stat(path, &stat_buf) != -1) {
257 plugintable[i].hdlPlugin = dlopen(path, RTLD_LAZY);
258 } else {
259 continue;
262 if (plugintable[i].hdlPlugin != NULL) {
263 InitializeFn PassFunc;
264 MP_STATUS status;
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);
279 i++;
284 if (lock_register(fd_mpconf, F_SETLK, F_UNLCK, 0, SEEK_SET, 0) < 0) {
285 fclose(mpconf);
286 close(fd_mpconf);
287 (void) pthread_mutex_unlock(&mp_lib_mutex);
288 return;
290 fclose(mpconf);
291 close(fd_mpconf);
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 ******************************************************************************
307 void ExitLibrary()
309 MP_UINT32 i, j;
311 if(number_of_plugins == -1)
312 return;
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) {
323 ExitPassFunc();
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.
342 * @param pProps
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];
363 if(pProps == NULL) {
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",
379 LIBRARY_FILE_NAME);
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
393 * by the library.
394 * @return An MP_STATUS indicating if the operation was successful or if
395 * an error
396 * occurred.
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)
406 MP_UINT32 i;
408 if (ppList == NULL)
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));
415 } else {
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.
444 * @param oid
445 * The ID of the plugin whose properties are being retrieved.
447 * @param pProps
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
453 * error occurred.
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
463 * the system.
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(
472 MP_OID pluginOid,
473 MP_PLUGIN_PROPERTIES *pProps)
475 MP_GetPluginPropertiesPluginFn PassFunc;
476 MP_UINT32 index;
477 MP_STATUS status;
479 if(pProps == NULL)
480 return (MP_STATUS_INVALID_PARAMETER);
482 if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN,
483 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
484 return (status);
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);
496 } else {
497 status = MP_STATUS_UNSUPPORTED;
499 } else {
500 status = MP_STATUS_FAILED;
503 (void) pthread_mutex_unlock(&mp_lib_mutex);
504 return status;
508 *******************************************************************************
510 * Gets the object ID for the plugin associated with the specified object ID.
512 * @param oid
513 * The object ID of an object that has been received from a previous
514 * library call.
516 * @param pPluginOid
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
522 * an error occurred.
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
529 * the system.
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
534 * cannot be written.
536 * @retval MP_STATUS_INVALID_OBJECT_TYPE
537 * Returned if 'oid' specifies an object with an invalid type.
539 *******************************************************************************
541 MP_STATUS MP_GetAssociatedPluginOid(
542 MP_OID objectId,
543 MP_OID *pPluginId)
545 MP_UINT32 i;
546 MP_STATUS status;
548 if (pPluginId == NULL)
549 return (MP_STATUS_INVALID_PARAMETER);
551 if ((status = validate_object(objectId, 0, MP_OBJECT_TYPE_ANY)) !=
552 MP_STATUS_SUCCESS) {
553 return (status);
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.
568 * @param oid
569 * The object ID of an object that has been received from a previous
570 * library call.
572 * @param pObjectType
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
581 * the system.
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(
592 MP_OID oid,
593 MP_OBJECT_TYPE *pObjectType)
595 MP_STATUS status;
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) {
602 return (status);
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.
615 * @param oid
616 * The object ID of plugin.
618 * @param ppList
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
625 * an error occurred.
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(
649 MP_OID oid,
650 MP_OID_LIST **ppList)
652 MP_GetDeviceProductOidListPluginFn PassFunc;
653 MP_UINT32 index;
654 MP_STATUS status;
656 if (ppList == NULL)
657 return MP_STATUS_INVALID_PARAMETER;
659 if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
660 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
661 return (status);
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);
673 } else {
674 status = MP_STATUS_UNSUPPORTED;
676 } else {
677 status = MP_STATUS_FAILED;
680 (void) pthread_mutex_unlock(&mp_lib_mutex);
681 return status;
685 *******************************************************************************
687 * Gets the device product properties of the specified plugin oid.
689 * @param oid
690 * The object ID of the plugin.
692 * @param ppProps
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
696 * by the library.
698 * @return An MP_STATUS indicating if the operation was successful or if
699 * an error occurred.
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(
723 MP_OID oid,
724 MP_DEVICE_PRODUCT_PROPERTIES *pProps)
726 MP_GetDeviceProductPropertiesFn PassFunc;
727 MP_UINT32 index;
728 MP_STATUS status;
730 if (pProps == NULL)
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) {
735 return (status);
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);
748 } else {
749 status = MP_STATUS_UNSUPPORTED;
751 } else {
752 status = MP_STATUS_FAILED;
755 (void) pthread_mutex_unlock(&mp_lib_mutex);
756 return status;
760 *******************************************************************************
762 * Gets a list of the object IDs of all the initiator ports associated
763 * with this plugin.
765 * @param oid
766 * The object ID of plugin.
768 * @param ppList
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
775 * an error occurred.
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(
799 MP_OID oid,
800 MP_OID_LIST **ppList)
802 MP_GetInitiatorPortOidListPluginFn PassFunc;
803 MP_UINT32 index;
804 MP_STATUS status;
806 if (ppList == NULL)
807 return MP_STATUS_INVALID_PARAMETER;
809 if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
810 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
811 return (status);
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);
823 } else {
824 status = MP_STATUS_UNSUPPORTED;
826 } else {
827 status = MP_STATUS_FAILED;
830 (void) pthread_mutex_unlock(&mp_lib_mutex);
831 return (status);
835 *******************************************************************************
837 * Gets the properties of the specified initiator port.
839 * @param oid
840 * The object ID of the initiator port.
842 * @param pProps
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
848 * an error occurred.
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
862 * the system.
864 *******************************************************************************
866 MP_STATUS MP_GetInitiatorPortProperties(
867 MP_OID oid,
868 MP_INITIATOR_PORT_PROPERTIES *pProps)
870 MP_GetInitiatorPortPropertiesFn PassFunc;
871 MP_UINT32 index;
872 MP_STATUS status;
874 if (pProps == NULL)
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) {
879 return (status);
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);
892 } else {
893 status = MP_STATUS_UNSUPPORTED;
895 } else {
896 status = MP_STATUS_FAILED;
899 (void) pthread_mutex_unlock(&mp_lib_mutex);
900 return status;
904 *******************************************************************************
906 * Gets a list of multipath logical units associated to a plugin.
908 * @param oid
909 * The object ID of plugin.
911 * @param ppList
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
918 * an error occurred.
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(
942 MP_OID oid,
943 MP_OID_LIST **ppList)
945 MP_UINT32 index;
946 MP_STATUS status;
948 if (ppList == NULL)
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)) {
955 return (status);
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);
970 } else {
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);
981 } else {
982 status = MP_STATUS_UNSUPPORTED;
984 } else {
985 status = MP_STATUS_INVALID_PARAMETER;
989 (void) pthread_mutex_unlock(&mp_lib_mutex);
990 return (status);
995 *******************************************************************************
997 * Gets the properties of the specified logical unit.
999 * @param oid
1000 * The object ID of the multipath logical unit.
1002 * @param pProps
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
1022 * the system.
1024 *******************************************************************************
1026 MP_STATUS MP_GetMPLogicalUnitProperties(
1027 MP_OID oid,
1028 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES *pProps)
1030 MP_GetMPLogicalUnitPropertiesFn PassFunc;
1031 MP_UINT32 index;
1032 MP_STATUS status;
1034 if (pProps == NULL)
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) {
1039 return (status);
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);
1052 } else {
1053 status = MP_STATUS_UNSUPPORTED;
1055 } else {
1056 status = MP_STATUS_FAILED;
1059 (void) pthread_mutex_unlock(&mp_lib_mutex);
1060 return (status);
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.
1069 * @param oid
1070 * The object ID of multipath logical unit, initiator port, or
1071 * target port.
1073 * @param ppList
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
1100 * the system.
1102 *******************************************************************************
1104 MP_STATUS MP_GetAssociatedPathOidList(
1105 MP_OID oid,
1106 MP_OID_LIST **ppList)
1108 MP_GetAssociatedPathOidListFn PassFunc;
1109 MP_UINT32 index;
1110 MP_STATUS status;
1112 if (ppList == NULL)
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)) {
1121 return (status);
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);
1134 } else {
1135 status = MP_STATUS_UNSUPPORTED;
1137 } else {
1138 status = MP_STATUS_FAILED;
1141 (void) pthread_mutex_unlock(&mp_lib_mutex);
1142 return (status);
1146 *******************************************************************************
1148 * Gets the properties of the specified path logical unit.
1150 * @param oid
1151 * The object ID of the path logical unit.
1153 * @param pProps
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
1173 * the system.
1175 *******************************************************************************
1177 MP_STATUS MP_GetPathLogicalUnitProperties(
1178 MP_OID oid,
1179 MP_PATH_LOGICAL_UNIT_PROPERTIES *pProps)
1181 MP_GetPathLogicalUnitPropertiesFn PassFunc;
1182 MP_UINT32 index;
1183 MP_STATUS status;
1185 if (pProps == NULL)
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) {
1190 return (status);
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);
1203 } else {
1204 status = MP_STATUS_UNSUPPORTED;
1206 } else {
1207 status = MP_STATUS_FAILED;
1210 (void) pthread_mutex_unlock(&mp_lib_mutex);
1211 return (status);
1215 *******************************************************************************
1217 * Gets a list of the object IDs of all the target port group associated
1218 * with the specified multipath logical unit.
1220 * @param oid
1221 * The object ID of the multiple logical unit.
1223 * @param ppList
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(
1252 MP_OID oid,
1253 MP_OID_LIST **ppList)
1255 MP_GetAssociatedTPGOidListFn PassFunc;
1256 MP_UINT32 index;
1257 MP_STATUS status;
1259 if (ppList == NULL)
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) {
1264 return (status);
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);
1277 } else {
1278 status = MP_STATUS_UNSUPPORTED;
1280 } else {
1281 status = MP_STATUS_FAILED;
1284 (void) pthread_mutex_unlock(&mp_lib_mutex);
1285 return (status);
1289 *******************************************************************************
1291 * Gets the properties of the specified target port group.
1293 * @param oid
1294 * The object ID of the target port group.
1296 * @param pProps
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
1316 * the system.
1318 *******************************************************************************
1320 MP_STATUS MP_GetTargetPortGroupProperties(
1321 MP_OID oid,
1322 MP_TARGET_PORT_GROUP_PROPERTIES *pProps)
1324 MP_GetTargetPortGroupPropertiesFn PassFunc;
1325 MP_UINT32 index;
1326 MP_STATUS status;
1328 if (pProps == NULL)
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) {
1333 return (status);
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);
1346 } else {
1347 status = MP_STATUS_UNSUPPORTED;
1349 } else {
1350 status = MP_STATUS_FAILED;
1353 (void) pthread_mutex_unlock(&mp_lib_mutex);
1354 return (status);
1358 *******************************************************************************
1360 * Gets a list of multipath logical units associated with the specific target
1361 * port group.
1363 * @param oid
1364 * The object ID of the target port group.
1366 * @param ppList
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(
1394 MP_OID oid,
1395 MP_OID_LIST **ppList)
1397 MP_GetMPLuOidListFromTPGFn PassFunc;
1398 MP_UINT32 index;
1399 MP_STATUS status;
1401 if (ppList == NULL)
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) {
1406 return (status);
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);
1419 } else {
1420 status = MP_STATUS_UNSUPPORTED;
1422 } else {
1423 status = MP_STATUS_FAILED;
1426 (void) pthread_mutex_unlock(&mp_lib_mutex);
1427 return (status);
1431 *******************************************************************************
1433 * Gets a list of the object IDs of all the proprietary load balance
1434 * algorithms associated with this plugin.
1436 * @param oid
1437 * The object ID of the plugin.
1439 * @param ppList
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(
1470 MP_OID oid,
1471 MP_OID_LIST **ppList)
1473 MP_GetProprietaryLoadBalanceOidListPluginFn PassFunc;
1474 MP_UINT32 index;
1475 MP_STATUS status;
1477 if (ppList == NULL)
1478 return MP_STATUS_INVALID_PARAMETER;
1480 if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
1481 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1482 return (status);
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);
1495 } else {
1496 status = MP_STATUS_UNSUPPORTED;
1498 } else {
1499 status = MP_STATUS_FAILED;
1502 (void) pthread_mutex_unlock(&mp_lib_mutex);
1503 return (status);
1507 *******************************************************************************
1509 * Gets the properties of the specified load balance properties structure.
1511 * @param oid
1512 * The object ID of the load balance properties structure.
1514 * @param pProps
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
1518 * specified by oid.
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
1535 * the system.
1537 *******************************************************************************
1539 MP_STATUS MP_GetProprietaryLoadBalanceProperties (
1540 MP_OID oid,
1541 MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES *pProps)
1543 MP_GetProprietaryLoadBalancePropertiesFn PassFunc;
1544 MP_UINT32 index;
1545 MP_STATUS status;
1547 if (pProps == NULL)
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) {
1552 return (status);
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);
1565 } else {
1566 status = MP_STATUS_UNSUPPORTED;
1568 } else {
1569 status = MP_STATUS_FAILED;
1572 (void) pthread_mutex_unlock(&mp_lib_mutex);
1573 return (status);
1577 *******************************************************************************
1579 * Gets a list of the object IDs of the target ports in the specified target
1580 * port group.
1582 * @param oid
1583 * The object ID of the target port group.
1585 * @param ppList
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(
1613 MP_OID oid,
1614 MP_OID_LIST **ppList)
1616 MP_GetTargetPortOidListFn PassFunc;
1617 MP_UINT32 index;
1618 MP_STATUS status;
1620 if (ppList == NULL)
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) {
1625 return (status);
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);
1638 } else {
1639 status = MP_STATUS_UNSUPPORTED;
1641 } else {
1642 status = MP_STATUS_FAILED;
1645 (void) pthread_mutex_unlock(&mp_lib_mutex);
1646 return (status);
1650 *******************************************************************************
1652 * Gets the properties of the specified target port.
1654 * @param oid
1655 * The object ID of the target port.
1657 * @param pProps
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
1677 * the system.
1679 *******************************************************************************
1681 MP_STATUS MP_GetTargetPortProperties(
1682 MP_OID oid,
1683 MP_TARGET_PORT_PROPERTIES *pProps)
1685 MP_GetTargetPortPropertiesFn PassFunc;
1686 MP_UINT32 index;
1687 MP_STATUS status;
1689 if (pProps == NULL)
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) {
1694 return (status);
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);
1707 } else {
1708 status = MP_STATUS_UNSUPPORTED;
1710 } else {
1711 status = MP_STATUS_FAILED;
1714 (void) pthread_mutex_unlock(&mp_lib_mutex);
1715 return (status);
1720 *******************************************************************************
1722 * Assign a multipath logical unit to a target port group.
1724 * @param tpgOid
1725 * An MP_TARGET_PORT_GROUP oid. The target port group currently in
1726 * active access state that the administrator would like the LU
1727 * assigned to.
1729 * @param luOid
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
1746 * the system.
1748 *******************************************************************************
1750 MP_STATUS MP_AssignLogicalUnitToTPG(
1751 MP_OID tpgOid,
1752 MP_OID luOid)
1754 MP_AssignLogicalUnitToTPGFn PassFunc;
1755 MP_UINT32 index;
1756 MP_STATUS status;
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) {
1764 return (status);
1767 if ((status = validate_object(luOid, MP_OBJECT_TYPE_MULTIPATH_LU,
1768 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1769 return (status);
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);
1782 } else {
1783 status = MP_STATUS_UNSUPPORTED;
1785 } else {
1786 status = MP_STATUS_FAILED;
1789 (void) pthread_mutex_unlock(&mp_lib_mutex);
1790 return (status);
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.
1802 * @param pathOid
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,
1827 MP_OID pathOid)
1829 MP_SetOverridePathFn PassFunc;
1830 MP_UINT32 index;
1831 MP_STATUS status;
1833 if ((status = validate_object(logicalUnitOid, MP_OBJECT_TYPE_MULTIPATH_LU,
1834 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1835 return (status);
1837 if ((status = validate_object(pathOid, MP_OBJECT_TYPE_PATH_LU,
1838 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1839 return (status);
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);
1852 } else {
1853 status = MP_STATUS_UNSUPPORTED;
1855 } else {
1856 status = MP_STATUS_FAILED;
1859 (void) pthread_mutex_unlock(&mp_lib_mutex);
1860 return (status);
1864 *******************************************************************************
1866 * Cancel a path override and re-enable load balancing.
1868 * @param luOid
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
1885 * the system.
1887 *******************************************************************************
1889 MP_STATUS MP_CancelOverridePath(
1890 MP_OID luOid)
1892 MP_CancelOverridePathFn PassFunc;
1893 MP_UINT32 index;
1894 MP_STATUS status;
1896 if ((status = validate_object(luOid, MP_OBJECT_TYPE_MULTIPATH_LU,
1897 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1898 return (status);
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);
1911 } else {
1912 status = MP_STATUS_UNSUPPORTED;
1914 } else {
1915 status = MP_STATUS_FAILED;
1918 (void) pthread_mutex_unlock(&mp_lib_mutex);
1919 return (status);
1923 *******************************************************************************
1925 * Enables Auto-failback.
1927 * @param oid
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(
1946 MP_OID oid)
1948 MP_UINT32 index;
1949 MP_STATUS status;
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)) {
1955 return (status);
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();
1970 } else {
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);
1981 } else {
1982 status = MP_STATUS_UNSUPPORTED;
1984 } else {
1985 status = MP_STATUS_INVALID_PARAMETER;
1989 (void) pthread_mutex_unlock(&mp_lib_mutex);
1990 return (status);
1994 *******************************************************************************
1996 * Enables Auto-probing.
1998 * @param oid
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(
2017 MP_OID oid)
2019 MP_UINT32 index;
2020 MP_STATUS status;
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)) {
2026 return (status);
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();
2041 } else {
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);
2052 } else {
2053 status = MP_STATUS_UNSUPPORTED;
2055 } else {
2056 status = MP_STATUS_INVALID_PARAMETER;
2060 (void) pthread_mutex_unlock(&mp_lib_mutex);
2061 return (status);
2065 *******************************************************************************
2067 * Disables Auto-failback.
2069 * @param oid
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(
2088 MP_OID oid)
2090 MP_UINT32 index;
2091 MP_STATUS status;
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)) {
2097 return (status);
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();
2112 } else {
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);
2123 } else {
2124 status = MP_STATUS_UNSUPPORTED;
2126 } else {
2127 status = MP_STATUS_INVALID_PARAMETER;
2131 (void) pthread_mutex_unlock(&mp_lib_mutex);
2132 return (status);
2136 *******************************************************************************
2138 * Disables Auto-probing.
2140 * @param oid
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(
2159 MP_OID oid)
2161 MP_UINT32 index;
2162 MP_STATUS status;
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)) {
2168 return (status);
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();
2183 } else {
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);
2194 } else {
2195 status = MP_STATUS_UNSUPPORTED;
2197 } else {
2198 status = MP_STATUS_INVALID_PARAMETER;
2202 (void) pthread_mutex_unlock(&mp_lib_mutex);
2203 return (status);
2207 *******************************************************************************
2209 * Enables a path. This API may cause failover in a logical unit with
2210 * asymmetric access.
2212 * @param oid
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
2223 * a valid path oid.
2225 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2226 * Returned if oid does not specify any valid object type.
2228 *******************************************************************************
2230 MP_STATUS MP_EnablePath(
2231 MP_OID oid)
2233 MP_EnablePathFn PassFunc;
2234 MP_UINT32 index;
2235 MP_STATUS status;
2237 if ((status = validate_object(oid, MP_OBJECT_TYPE_PATH_LU,
2238 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2239 return (status);
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,
2248 "MP_EnablePath");
2250 if (PassFunc != NULL) {
2251 status = PassFunc(oid);
2252 } else {
2253 status = MP_STATUS_UNSUPPORTED;
2255 } else {
2256 status = MP_STATUS_FAILED;
2259 (void) pthread_mutex_unlock(&mp_lib_mutex);
2260 return (status);
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.
2269 * @param oid
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
2280 * a valid path oid.
2282 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2283 * Returned if oid does not specify any valid object type.
2285 *******************************************************************************
2287 MP_STATUS MP_DisablePath(
2288 MP_OID oid)
2290 MP_DisablePathFn PassFunc;
2291 MP_UINT32 index;
2292 MP_STATUS status;
2294 if ((status = validate_object(oid, MP_OBJECT_TYPE_PATH_LU,
2295 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2296 return (status);
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,
2305 "MP_DisablePath");
2307 if (PassFunc != NULL) {
2308 status = PassFunc(oid);
2309 } else {
2310 status = MP_STATUS_UNSUPPORTED;
2312 } else {
2313 status = MP_STATUS_FAILED;
2316 (void) pthread_mutex_unlock(&mp_lib_mutex);
2317 return (status);
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
2340 * specified.
2342 * @retval MP_STATUS_FAILED
2343 * Returned when the specified loadBalance type cannot be handled
2344 * by the plugin.
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;
2356 MP_UINT32 index;
2357 MP_STATUS status;
2359 if ((status = validate_object(logicalUnitOid,
2360 MP_OBJECT_TYPE_MULTIPATH_LU,
2361 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2362 return (status);
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);
2375 } else {
2376 status = MP_STATUS_UNSUPPORTED;
2378 } else {
2379 status = MP_STATUS_FAILED;
2382 (void) pthread_mutex_unlock(&mp_lib_mutex);
2383 return (status);
2387 *******************************************************************************
2389 * Set the weight to be assigned to a particular path.
2391 * @param pathOid
2392 * The object ID of the path logical unit.
2394 * @param weight
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
2405 * found.
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(
2426 MP_OID pathOid,
2427 MP_UINT32 weight)
2429 MP_SetPathWeightFn PassFunc;
2430 MP_UINT32 index;
2431 MP_STATUS status;
2433 if ((status = validate_object(pathOid, MP_OBJECT_TYPE_PATH_LU,
2434 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2435 return (status);
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);
2448 } else {
2449 status = MP_STATUS_UNSUPPORTED;
2451 } else {
2452 status = MP_STATUS_FAILED;
2455 (void) pthread_mutex_unlock(&mp_lib_mutex);
2456 return (status);
2460 *******************************************************************************
2462 * Set the default load balance policy for the plugin.
2464 * @param oid
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
2478 * found.
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
2491 * by the plugin.
2493 *******************************************************************************
2495 MP_STATUS MP_SetPluginLoadBalanceType(
2496 MP_OID oid,
2497 MP_LOAD_BALANCE_TYPE loadBalance)
2499 MP_SetPluginLoadBalanceTypePluginFn PassFunc;
2500 MP_UINT32 index;
2501 MP_STATUS status;
2503 if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2504 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2505 return (status);
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);
2518 } else {
2519 status = MP_STATUS_UNSUPPORTED;
2521 } else {
2522 status = MP_STATUS_FAILED;
2525 (void) pthread_mutex_unlock(&mp_lib_mutex);
2526 return (status);
2530 *******************************************************************************
2532 * Set the failback polling rates. Setting both rates to zero disables polling.
2534 * @param pluginOid
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
2549 * found.
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(
2564 MP_OID oid,
2565 MP_UINT32 pollingRate)
2567 MP_UINT32 index;
2568 MP_STATUS status;
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)) {
2574 return (status);
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);
2589 } else {
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);
2600 } else {
2601 status = MP_STATUS_UNSUPPORTED;
2603 } else {
2604 status = MP_STATUS_INVALID_PARAMETER;
2608 (void) pthread_mutex_unlock(&mp_lib_mutex);
2609 return (status);
2613 *******************************************************************************
2615 * Set the probing polling rates. Setting both rates to zero disables polling.
2617 * @param pluginOid
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
2632 * found.
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(
2647 MP_OID oid,
2648 MP_UINT32 pollingRate)
2650 MP_UINT32 index;
2651 MP_STATUS status;
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)) {
2657 return (status);
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);
2672 } else {
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);
2683 } else {
2684 status = MP_STATUS_UNSUPPORTED;
2686 } else {
2687 status = MP_STATUS_INVALID_PARAMETER;
2691 (void) pthread_mutex_unlock(&mp_lib_mutex);
2692 return (status);
2696 *******************************************************************************
2698 * Set proprietary properties in supported object instances.
2700 * @param pluginOid
2701 * The object ID of MP_LOAD_BALANCE_PROPRIETARY_TYPE, MP_PLUGIN_PROPERTIES
2702 * or MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES.
2704 * @param count
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
2719 * found.
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(
2734 MP_OID oid,
2735 MP_UINT32 count,
2736 MP_PROPRIETARY_PROPERTY *pPropertyList)
2738 MP_SetProprietaryPropertiesFn PassFunc;
2739 MP_UINT32 index;
2740 MP_STATUS status;
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)) {
2748 return (status);
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);
2761 } else {
2762 status = MP_STATUS_UNSUPPORTED;
2764 } else {
2765 status = MP_STATUS_FAILED;
2768 (void) pthread_mutex_unlock(&mp_lib_mutex);
2769 return (status);
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
2777 * groups.
2779 * @param luOid
2780 * The object ID of the logical unit where the command is sent.
2782 * @param count
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(
2820 MP_OID luOid,
2821 MP_UINT32 count,
2822 MP_TPG_STATE_PAIR *pTpgStateList)
2824 MP_SetTPGAccessFn PassFunc;
2825 MP_UINT32 index;
2826 MP_STATUS status;
2828 if ((status = validate_object(luOid, MP_OBJECT_TYPE_MULTIPATH_LU,
2829 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2830 return (status);
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,
2839 "MP_SetTPGAccess");
2841 if (PassFunc != NULL) {
2842 status = PassFunc(luOid, count, pTpgStateList);
2843 } else {
2844 status = MP_STATUS_UNSUPPORTED;
2846 } else {
2847 status = MP_STATUS_FAILED;
2850 (void) pthread_mutex_unlock(&mp_lib_mutex);
2851 return (status);
2855 *******************************************************************************
2857 * Registers a client function that is to be called
2858 * whenever the property of an an object changes.
2860 * @param pClientFn,
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
2864 * change.
2866 * @param objectType
2867 * The type of object the client wishes to deregister for
2868 * property change callbacks. If null, then all objects types are
2869 * deregistered.
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
2874 * the registration.
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,
2898 void *pCallerData,
2899 MP_OID pluginOid)
2901 MP_RegisterForObjectPropertyChangesPluginFn PassFunc;
2902 MP_UINT32 i;
2903 MP_UINT32 index;
2904 MP_STATUS status;
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) {
2917 return (status);
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) {
2932 status =
2933 PassFunc(pClientFn, objectType, pCallerData);
2934 /* ignore an error and continue */
2937 } else {
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);
2950 return (status);
2954 *******************************************************************************
2956 * Deregisters a previously registered client function that is to be invoked
2957 * whenever an object's property changes.
2959 * @param pClientFn,
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.
2966 * @param objectType
2967 * The type of object the client wishes to deregister for
2968 * property change callbacks. If null, then all objects types are
2969 * deregistered.
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
2983 * function.
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,
2996 MP_OID pluginOid)
2998 MP_DeregisterForObjectPropertyChangesPluginFn PassFunc;
2999 MP_UINT32 i;
3000 MP_UINT32 index;
3001 MP_STATUS status;
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) {
3014 return (status);
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);
3032 } else {
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);
3045 return (status);
3049 *******************************************************************************
3051 * Registers a client function that is to be called
3052 * whenever a high level object appears or disappears.
3054 * @param pClientFn,
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.
3059 * @param objectType
3060 * The type of object the client wishes to deregister for
3061 * property change callbacks. If null, then all objects types are
3062 * deregistered.
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
3067 * the registration.
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,
3091 void *pCallerData,
3092 MP_OID pluginOid)
3094 MP_RegisterForObjectVisibilityChangesPluginFn PassFunc;
3095 MP_UINT32 i;
3096 MP_UINT32 index;
3097 MP_STATUS status;
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) {
3110 return (status);
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. */
3129 } else {
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);
3142 return (status);
3147 *******************************************************************************
3149 * Deregisters a previously registered client function that is to be invoked
3150 * whenever a high level object appears or disappears.
3152 * @param pClientFn,
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.
3159 * @param objectType
3160 * The type of object the client wishes to deregister for visibility
3161 * change callbacks. If null, then all objects types are
3162 * deregistered.
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
3176 * function.
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,
3189 MP_OID pluginOid)
3191 MP_DeregisterForObjectVisibilityChangesPluginFn PassFunc;
3192 MP_UINT32 i;
3193 MP_UINT32 index;
3194 MP_STATUS status;
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) {
3207 return (status);
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);
3224 } else {
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);
3237 return (status);
3241 *******************************************************************************
3243 * Compare two Oids for equality to see whether they refer to the same object.
3245 * @param oid1
3246 * Oid to compare.
3248 * @param oid2
3249 * Oid to compare.
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(
3263 MP_OID oid1,
3264 MP_OID oid2)
3266 if ((oid1.objectType == oid2.objectType) && (oid1.ownerId == oid2.ownerId)
3267 && (oid1.objectSequenceNumber == oid2.objectSequenceNumber)) {
3268 return (MP_STATUS_SUCCESS);
3269 } else {
3270 return (MP_STATUS_FAILED);
3275 *******************************************************************************
3277 * Frees memory returned by an MP API.
3279 * @param pOidList
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);
3301 free(pOidList);
3303 return (MP_STATUS_SUCCESS);
3306 static MP_CHAR *HDR =
3307 "#\n"
3308 "# This file contains names and references to MP API plugin libraries\n"
3309 "#\n"
3310 "# Do NOT manually edit this file\n"
3311 "#\n"
3312 "# Format:\n"
3313 "#\n"
3314 "# <library ID> <library pathname>\n"
3315 "#\n";
3317 #define CLEANUP_N_RET(fd, ret) \
3318 if (lock_register(fd, F_SETLK, F_UNLCK, 0, SEEK_SET, 0) < 0) { \
3319 close(fd); \
3320 return (MP_STATUS_FAILED); \
3322 close(fd); \
3323 return (ret)
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
3328 * flock structure.
3330 static int
3331 lock_register(int fd, int cmd, int type, off_t offset, int whence, off_t len)
3333 struct flock lock;
3335 lock.l_type = type;
3336 lock.l_start = offset;
3337 lock.l_whence = whence;
3338 lock.l_len = len;
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"
3349 * ARGUMENTS :
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
3358 * RETURN VALUES :
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
3361 * "buf".
3363 static int
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;
3372 *write_offset = 0;
3374 if (buf == NULL || buflen <= 0)
3375 return (-1);
3377 if (srch_id == NULL || id_len <= 0)
3378 return (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')) {
3391 cur_pos++;
3394 if (strncmp(cur_pos, srch_id, id_len) == 0) {
3395 /* id matched. */
3396 cur_pos += id_len;
3398 while (*cur_pos != '\n') {
3399 cur_pos++;
3401 *write_offset = (sol - buf);
3402 *bytes_left = buflen - ((cur_pos + 1) - buf);
3403 return (0);
3404 } else {
3405 /* move to the next line */
3406 while (*cur_pos != '\n') {
3407 cur_pos++;
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;
3416 return (-1);
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
3424 * plugin libraries.
3426 * @param pPluginId
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
3430 * terminated.
3432 * @param pFileName
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,
3453 char *pFileName)
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);
3462 struct stat stbuf;
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);
3476 *fullline = '\0';
3477 strncpy(fullline, pluginid, MAX_NAME_SIZE);
3478 /* add tab */
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)) {
3490 new_file_flag = 1;
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) {
3498 close(mpconf);
3499 return (MP_STATUS_FAILED);
3502 if (lock_register(mpconf, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0) < 0) {
3503 close(mpconf);
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) !=
3513 sizeof_conf_hdr) {
3514 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3517 if (pwrite(mpconf, fullline, strlen(fullline),
3518 sizeof_conf_hdr) !=
3519 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);
3536 } else {
3537 munmap((void *)mpconf_buf, stbuf.st_size);
3538 /* append the fullline to the mpconf. */
3539 if (pwrite(mpconf, fullline, strlen(fullline),
3540 write_offset) !=
3541 strlen(fullline)) {
3542 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3543 } else {
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.
3555 * @param pPluginId
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);
3583 struct stat stbuf;
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)) {
3598 /* no file found */
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) {
3607 close(mpconf);
3608 return (MP_STATUS_FAILED);
3611 if (lock_register(mpconf, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0) < 0) {
3612 close(mpconf);
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);
3634 } else {
3636 * found a match.
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) {
3648 close(tmp_mpconf);
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) {
3654 close(tmp_mpconf);
3655 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3658 close(tmp_mpconf);
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);
3664 } else {
3665 CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS);