8831 mpapi: variable 'status' set but not used
[unleashed.git] / usr / src / lib / mpapi / libmpapi / common / mpapi.c
blobafbfb148fbfb582300a31ddcdd7396727e1f5b68
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;
265 wcsncpy(plugintable[i].pluginName,
266 name, MAX_NAME_SIZE);
267 strncpy(plugintable[i].pluginPath,
268 path, MAX_NAME_SIZE);
270 plugintable[i].ownerId = i + 1;
272 PassFunc = (InitializeFn)
273 dlsym(plugintable[i].hdlPlugin, "Initialize");
274 if (PassFunc != NULL) {
275 (void) PassFunc(plugintable[i].ownerId);
278 i++;
283 if (lock_register(fd_mpconf, F_SETLK, F_UNLCK, 0, SEEK_SET, 0) < 0) {
284 fclose(mpconf);
285 close(fd_mpconf);
286 (void) pthread_mutex_unlock(&mp_lib_mutex);
287 return;
289 fclose(mpconf);
290 close(fd_mpconf);
292 number_of_plugins = i;
293 (void) pthread_mutex_unlock(&mp_lib_mutex);
297 ******************************************************************************
299 * Exit by calling Terminate routine of plugin libraries.
301 * Note: The build of libMPAPI.so should include a linker option to make this
302 * routine executed when it is unloaded.
304 ******************************************************************************
306 void ExitLibrary()
308 MP_UINT32 i, j;
310 if(number_of_plugins == -1)
311 return;
313 (void) pthread_mutex_lock(&mp_lib_mutex);
314 for (i = 0; i < number_of_plugins; i++) {
315 if (plugintable[i].hdlPlugin != NULL) {
316 TerminateFn ExitPassFunc;
318 ExitPassFunc = (TerminateFn)
319 dlsym(plugintable[i].hdlPlugin, "Terminate");
321 if (ExitPassFunc != NULL) {
322 ExitPassFunc();
325 /* Unload plugin from memory */
326 dlclose(plugintable[i].hdlPlugin);
330 number_of_plugins = -1;
332 (void) pthread_mutex_unlock(&mp_lib_mutex);
333 (void) pthread_mutex_destroy(&mp_lib_mutex);
337 ******************************************************************************
339 * Gets the properties of the MP API library that is being used.
341 * @param pProps
342 * A pointer to an @ref MP_LIBRARY_PROPERTIES structure allocated by
343 * the caller. On successful return this structure will contain the
344 * properties of the MP library.
346 * @return An MP_STATUS indicating if the operation was successful or
347 * if an error occurred.
349 * @retval MP_STATUS_SUCCESS
350 * Returned if the library properties were successfully returned.
352 * @retval MP_STATUS_INVALID_PARAMETER Returned if @a pProps is NULL or
353 * specifies a memory area to which data cannot be written.
355 ******************************************************************************
357 MP_STATUS MP_GetLibraryProperties(
358 MP_LIBRARY_PROPERTIES *pProps)
360 char mpPath[MAX_NAME_SIZE];
362 if(pProps == NULL) {
363 return MP_STATUS_INVALID_PARAMETER;
366 /* Fill in properties */
367 if (mbstowcs(pProps->buildTime, BUILD_TIME, 256) !=
368 strlen(BUILD_TIME)) {
369 return (MP_STATUS_INVALID_PARAMETER);
371 pProps->supportedMpVersion = LIBRARY_SUPPORTED_MP_VERSION;
373 wcsncpy(pProps->implementationVersion,
374 LIBRARY_IMPLEMENTATION_VERSION, MAX_NAME_SIZE);
375 wcsncpy(pProps->vendor, LIBRARY_VENDOR, MAX_NAME_SIZE);
377 snprintf(pProps->fileName, MAX_NAME_SIZE, "%s",
378 LIBRARY_FILE_NAME);
380 return MP_STATUS_SUCCESS;
385 ******************************************************************************
387 * Gets a list of the object IDs of all currently loaded plugins.
389 * @param ppList A pointer to a pointer to an @ref MP_OID_LIST. On successful
390 * return this will contain a pointer to an @ref MP_OID_LIST
391 * which contains the object IDs of all of the plugins currently loaded
392 * by the library.
393 * @return An MP_STATUS indicating if the operation was successful or if
394 * an error
395 * occurred.
396 * @retval MP_SUCCESS Returned if the plugin ID list was successfully returned.
397 * @retval MP_STATUS_INVALID_PARAMETER Returned if @a ppList is NULL or
398 * specifies a memory area to which data cannot be written.
400 ******************************************************************************
402 MP_STATUS MP_GetPluginOidList(
403 MP_OID_LIST **ppList)
405 MP_UINT32 i;
407 if (ppList == NULL)
408 return (MP_STATUS_INVALID_PARAMETER);
410 (void) pthread_mutex_lock(&mp_lib_mutex);
412 if (number_of_plugins == 0) {
413 *ppList = (MP_OID_LIST*)calloc(1, sizeof(MP_OID_LIST));
414 } else {
415 *ppList = (MP_OID_LIST*)calloc(1,
416 sizeof(MP_OID_LIST) + (number_of_plugins - 1)* sizeof(MP_OID) );
419 if ((*ppList) == NULL) {
420 (void) pthread_mutex_unlock(&mp_lib_mutex);
421 return (MP_STATUS_INSUFFICIENT_MEMORY);
424 (*ppList)->oidCount = number_of_plugins;
426 if (number_of_plugins != 0) {
427 for (i = 0; i < number_of_plugins; i++) {
428 (*ppList)->oids[i].objectType = MP_OBJECT_TYPE_PLUGIN;
429 (*ppList)->oids[i].ownerId = plugintable[i].ownerId;
430 (*ppList)->oids[i].objectSequenceNumber = 0;
434 (void) pthread_mutex_unlock(&mp_lib_mutex);
435 return MP_STATUS_SUCCESS;
439 *******************************************************************************
441 * Gets the properties of the specified vendor plugin.
443 * @param oid
444 * The ID of the plugin whose properties are being retrieved.
446 * @param pProps
447 * A pointer to an @ref MP_PLUGIN_PROPERTIES structure allocated by
448 * the caller. On successful return this will contain the properties
449 * of the plugin specified by pluginOid.
451 * @return An MP_STATUS indicating if the operation was successful or if an
452 * error occurred.
454 * @retval MP_STATUS_SUCCESS
455 * Returned if the plugin properties were successfully returned.
457 * @retval MP_STATUS_INVALID_OBJECT_TYPE
458 * Returned if oid does not specify any valid object type.
460 * @retval MP_STATUS_OBJECT_NOT_FOUND
461 * Returned if oid has an owner that is not currently known to
462 * the system.
464 * @retval MP_STATUS_INVALID_PARAMETER
465 * Returned if 'pProps' is NULL or specifies a memory area to
466 * which data cannot be written.
468 *******************************************************************************
470 MP_STATUS MP_GetPluginProperties(
471 MP_OID pluginOid,
472 MP_PLUGIN_PROPERTIES *pProps)
474 MP_GetPluginPropertiesPluginFn PassFunc;
475 MP_UINT32 index;
476 MP_STATUS status;
478 if(pProps == NULL)
479 return (MP_STATUS_INVALID_PARAMETER);
481 if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN,
482 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
483 return (status);
486 (void) pthread_mutex_lock(&mp_lib_mutex);
488 index = pluginOid.ownerId - 1;
489 if (plugintable[index].hdlPlugin != NULL) {
490 PassFunc = (MP_GetPluginPropertiesPluginFn)
491 dlsym(plugintable[index].hdlPlugin, "MP_GetPluginPropertiesPlugin");
493 if (PassFunc != NULL) {
494 status = PassFunc(pProps);
495 } else {
496 status = MP_STATUS_UNSUPPORTED;
498 } else {
499 status = MP_STATUS_FAILED;
502 (void) pthread_mutex_unlock(&mp_lib_mutex);
503 return status;
507 *******************************************************************************
509 * Gets the object ID for the plugin associated with the specified object ID.
511 * @param oid
512 * The object ID of an object that has been received from a previous
513 * library call.
515 * @param pPluginOid
516 * A pointer to an MP_OID structure allocated by the caller. On
517 * successful return this will contain the object ID of the plugin
518 * associated with the object specified by @a objectId.
520 * @return An MP_STATUS indicating if the operation was successful or if
521 * an error occurred.
523 * @retval MP_STATUS_SUCCESS
524 * Returned if the associated plugin ID was successfully returned.
526 * @retval MP_STATUS_OBJECT_NOT_FOUND
527 * Returned if oid does not specify a plugin that is currently known to
528 * the system.
530 * @retval MP_STATUS_INVALID_PARAMETER
531 * Returned if 'oid' specifies an object not owned by a plugin or
532 * if pPluginOid is NULL or specifies a memory area to which data
533 * cannot be written.
535 * @retval MP_STATUS_INVALID_OBJECT_TYPE
536 * Returned if 'oid' specifies an object with an invalid type.
538 *******************************************************************************
540 MP_STATUS MP_GetAssociatedPluginOid(
541 MP_OID objectId,
542 MP_OID *pPluginId)
544 MP_UINT32 i;
545 MP_STATUS status;
547 if (pPluginId == NULL)
548 return (MP_STATUS_INVALID_PARAMETER);
550 if ((status = validate_object(objectId, 0, MP_OBJECT_TYPE_ANY)) !=
551 MP_STATUS_SUCCESS) {
552 return (status);
555 pPluginId->objectType = MP_OBJECT_TYPE_PLUGIN;
556 pPluginId->ownerId = objectId.ownerId;
557 pPluginId->objectSequenceNumber = 0;
559 return (MP_STATUS_SUCCESS);
563 *******************************************************************************
565 * Gets the object type of an initialized object ID.
567 * @param oid
568 * The object ID of an object that has been received from a previous
569 * library call.
571 * @param pObjectType
572 * A pointer to an MP_OBJECT_TYPE variable allocated by the caller.
573 * On successful return this will contain the object type of oid.
575 * @return An MP_STATUS indicating if the operation was successful or
576 * if an error occurred.
578 * @retval MP_STATUS_OBJECT_NOT_FOUND
579 * Returned if oid has an owner that is not currently known to
580 * the system.
582 * @retval MP_STATUS_INVALID_PARAMETER
583 * Returned if oid does not specify any valid object type.
585 * @retval MP_STATUS_SUCCESS
586 * Returned when the operation is successful.
588 *******************************************************************************
590 MP_STATUS MP_GetObjectType(
591 MP_OID oid,
592 MP_OBJECT_TYPE *pObjectType)
594 MP_STATUS status;
596 if (pObjectType == NULL)
597 return MP_STATUS_INVALID_PARAMETER;
599 if ((status = validate_object(oid, 0, MP_OBJECT_TYPE_ANY))
600 != MP_STATUS_SUCCESS) {
601 return (status);
604 *pObjectType = oid.objectType;
605 return MP_STATUS_SUCCESS;
609 *******************************************************************************
611 * Gets a list of the object IDs of all the device product properties
612 * associated with this plugin.
614 * @param oid
615 * The object ID of plugin.
617 * @param ppList
618 * A pointer to a pointer to an MP_OID_LIST structure.
619 * On a successful return, this will contain a pointer to
620 * an MP_OID_LIST that contains the object IDs of all the device
621 * product descriptors associated with the specified plugin.
623 * @return An MP_STATUS indicating if the operation was successful or if
624 * an error occurred.
626 * @retval MP_STATUS_SUCCESS
627 * Returned when the operation is successful.
629 * @retval MP_STATUS_INVALID_PARAMETER
630 * Returned if ppList pointer passed as placeholder for holding
631 * the device product list is found to be invalid.
633 * @retval MP_STATUS_INVALID_OBJECT_TYPE
634 * Returned if oid does not specify any valid object type.
636 * @retval MP_STATUS_FAILED
637 * Returned when the plugin for the specified oid is not found.
639 * @retval MP_STATUS_INSUFFICIENT_MEMORY
640 * Returned when memory allocation failure occurs
642 * @retval MP_STATUS_UNSUPPORTED
643 * Returned when the API is not supported.
645 *******************************************************************************
647 MP_STATUS MP_GetDeviceProductOidList(
648 MP_OID oid,
649 MP_OID_LIST **ppList)
651 MP_GetDeviceProductOidListPluginFn PassFunc;
652 MP_UINT32 index;
653 MP_STATUS status;
655 if (ppList == NULL)
656 return MP_STATUS_INVALID_PARAMETER;
658 if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
659 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
660 return (status);
663 (void) pthread_mutex_lock(&mp_lib_mutex);
665 index = oid.ownerId - 1;
666 if (plugintable[index].hdlPlugin != NULL) {
667 PassFunc = (MP_GetDeviceProductOidListPluginFn)
668 dlsym(plugintable[index].hdlPlugin,
669 "MP_GetDeviceProductOidListPlugin");
670 if (PassFunc != NULL) {
671 status = PassFunc(ppList);
672 } else {
673 status = MP_STATUS_UNSUPPORTED;
675 } else {
676 status = MP_STATUS_FAILED;
679 (void) pthread_mutex_unlock(&mp_lib_mutex);
680 return status;
684 *******************************************************************************
686 * Gets the device product properties of the specified plugin oid.
688 * @param oid
689 * The object ID of the plugin.
691 * @param ppProps
692 * A pointer to a pointer to an MP_DEVICE_PRODUCT_PROPERTIES structure
693 * allocated by the caller. On successful return it will contain
694 * a pointer to an MP_DEVICE_PRODUCT_PROPERTIES structure allocated
695 * by the library.
697 * @return An MP_STATUS indicating if the operation was successful or if
698 * an error occurred.
700 * @retval MP_STATUS_SUCCESS
701 * Returned when the operation is successful.
703 * @retval MP_STATUS_INVALID_PARAMETER
704 * Returned if ppProps pointer passed as placeholder for holding
705 * the device product properties is found to be invalid.
707 * @retval MP_STATUS_INVALID_OBJECT_TYPE
708 * Returned if oid does not specify any valid object type.
710 * @retval MP_STATUS_FAILED
711 * Returned when the plugin for the specified oid is not found.
713 * @retval MP_STATUS_INSUFFICIENT_MEMORY
714 * Returned when memory allocation failure occurs
716 * @retval MP_STATUS_UNSUPPORTED
717 * Returned when the API is not supported.
719 *******************************************************************************
721 MP_STATUS MP_GetDeviceProductProperties(
722 MP_OID oid,
723 MP_DEVICE_PRODUCT_PROPERTIES *pProps)
725 MP_GetDeviceProductPropertiesFn PassFunc;
726 MP_UINT32 index;
727 MP_STATUS status;
729 if (pProps == NULL)
730 return MP_STATUS_INVALID_PARAMETER;
732 if ((status = validate_object(oid, MP_OBJECT_TYPE_DEVICE_PRODUCT,
733 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
734 return (status);
737 (void) pthread_mutex_lock(&mp_lib_mutex);
739 index = oid.ownerId - 1;
740 if (plugintable[index].hdlPlugin != NULL) {
741 PassFunc = (MP_GetDeviceProductPropertiesFn)
742 dlsym(plugintable[index].hdlPlugin,
743 "MP_GetDeviceProductProperties");
745 if (PassFunc != NULL) {
746 status = PassFunc(oid, pProps);
747 } else {
748 status = MP_STATUS_UNSUPPORTED;
750 } else {
751 status = MP_STATUS_FAILED;
754 (void) pthread_mutex_unlock(&mp_lib_mutex);
755 return status;
759 *******************************************************************************
761 * Gets a list of the object IDs of all the initiator ports associated
762 * with this plugin.
764 * @param oid
765 * The object ID of plugin.
767 * @param ppList
768 * A pointer to a pointer to an MP_OID_LIST structure.
769 * On a successful return, this will contain a pointer to
770 * an MP_OID_LIST that contains the object IDs of all the initiator
771 * ports associated with the specified plugin.
773 * @return An MP_STATUS indicating if the operation was successful or if
774 * an error occurred.
776 * @retval MP_STATUS_SUCCESS
777 * Returned when the operation is successful.
779 * @retval MP_STATUS_INVALID_PARAMETER
780 * Returned if ppList pointer passed as placeholder for holding
781 * the initiator port list is found to be invalid.
783 * @retval MP_STATUS_INVALID_OBJECT_TYPE
784 * Returned if oid does not specify any valid object type.
786 * @retval MP_STATUS_FAILED
787 * Returned when the plugin for the specified oid is not found.
789 * @retval MP_STATUS_INSUFFICIENT_MEMORY
790 * Returned when memory allocation failure occurs
792 * @retval MP_STATUS_UNSUPPORTED
793 * Returned when the API is not supported.
795 *******************************************************************************
797 MP_STATUS MP_GetInitiatorPortOidList(
798 MP_OID oid,
799 MP_OID_LIST **ppList)
801 MP_GetInitiatorPortOidListPluginFn PassFunc;
802 MP_UINT32 index;
803 MP_STATUS status;
805 if (ppList == NULL)
806 return MP_STATUS_INVALID_PARAMETER;
808 if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
809 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
810 return (status);
813 (void) pthread_mutex_lock(&mp_lib_mutex);
815 index = oid.ownerId - 1;
816 if (plugintable[index].hdlPlugin != NULL) {
817 PassFunc = (MP_GetDeviceProductOidListPluginFn)
818 dlsym(plugintable[index].hdlPlugin, "MP_GetInitiatorPortOidListPlugin");
820 if (PassFunc != NULL) {
821 status = PassFunc(ppList);
822 } else {
823 status = MP_STATUS_UNSUPPORTED;
825 } else {
826 status = MP_STATUS_FAILED;
829 (void) pthread_mutex_unlock(&mp_lib_mutex);
830 return (status);
834 *******************************************************************************
836 * Gets the properties of the specified initiator port.
838 * @param oid
839 * The object ID of the initiator port.
841 * @param pProps
842 * A pointer to an MP_INITIATOR_PORT_PROPERTIES structure
843 * allocated by the caller. On successful return, this structure
844 * will contain the properties of the port specified by oid.
846 * @return An MP_STATUS indicating if the operation was successful or if
847 * an error occurred.
849 * @retval MP_STATUS_SUCCESS
850 * Returned when the operation is successful.
852 * @retval MP_STATUS_INVALID_PARAMETER
853 * Returned if pProps is NULL or specifies a memory area to
854 * which data cannot be written.
856 * @retval MP_STATUS_INVALID_OBJECT_TYPE
857 * Returned if oid does not specify any valid object type.
859 * @retval MP_STATUS_OBJECT_NOT_FOUND
860 * Returned if oid has an owner that is not currently known to
861 * the system.
863 *******************************************************************************
865 MP_STATUS MP_GetInitiatorPortProperties(
866 MP_OID oid,
867 MP_INITIATOR_PORT_PROPERTIES *pProps)
869 MP_GetInitiatorPortPropertiesFn PassFunc;
870 MP_UINT32 index;
871 MP_STATUS status;
873 if (pProps == NULL)
874 return MP_STATUS_INVALID_PARAMETER;
876 if ((status = validate_object(oid, MP_OBJECT_TYPE_INITIATOR_PORT,
877 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
878 return (status);
881 (void) pthread_mutex_lock(&mp_lib_mutex);
883 index = oid.ownerId - 1;
884 if (plugintable[index].hdlPlugin != NULL) {
885 PassFunc = (MP_GetInitiatorPortPropertiesFn)
886 dlsym(plugintable[index].hdlPlugin,
887 "MP_GetInitiatorPortProperties");
889 if (PassFunc != NULL) {
890 status = PassFunc(oid, pProps);
891 } else {
892 status = MP_STATUS_UNSUPPORTED;
894 } else {
895 status = MP_STATUS_FAILED;
898 (void) pthread_mutex_unlock(&mp_lib_mutex);
899 return status;
903 *******************************************************************************
905 * Gets a list of multipath logical units associated to a plugin.
907 * @param oid
908 * The object ID of plugin.
910 * @param ppList
911 * A pointer to a pointer to an MP_OID_LIST structure.
912 * On a successful return, this will contain a pointer to
913 * an MP_OID_LIST that contains the object IDs of all the multipath
914 * logical units associated with the specified plugin.
916 * @return An MP_STATUS indicating if the operation was successful or if
917 * an error occurred.
919 * @retval MP_STATUS_SUCCESS
920 * Returned when the operation is successful.
922 * @retval MP_STATUS_INVALID_PARAMETER
923 * Returned if ppList pointer passed as placeholder for holding
924 * the multipath logical unit list is found to be invalid.
926 * @retval MP_STATUS_INVALID_OBJECT_TYPE
927 * Returned if oid does not specify any valid object type.
929 * @retval MP_STATUS_FAILED
930 * Returned when the plugin for the specified oid is not found.
932 * @retval MP_STATUS_INSUFFICIENT_MEMORY
933 * Returned when memory allocation failure occurs
935 * @retval MP_STATUS_UNSUPPORTED
936 * Returned when the API is not supported.
938 *******************************************************************************
940 MP_STATUS MP_GetMultipathLus(
941 MP_OID oid,
942 MP_OID_LIST **ppList)
944 MP_UINT32 index;
945 MP_STATUS status;
947 if (ppList == NULL)
948 return MP_STATUS_INVALID_PARAMETER;
950 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
951 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
952 ((status = validate_object(oid, MP_OBJECT_TYPE_DEVICE_PRODUCT,
953 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
954 return (status);
957 (void) pthread_mutex_lock(&mp_lib_mutex);
959 index = oid.ownerId - 1;
960 if (plugintable[index].hdlPlugin != NULL) {
961 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
962 MP_GetMultipathLusPluginFn PassFunc;
963 PassFunc = (MP_GetMultipathLusPluginFn)
964 dlsym(plugintable[index].hdlPlugin,
965 "MP_GetMultipathLusPlugin");
967 if (PassFunc != NULL) {
968 status = PassFunc(ppList);
969 } else {
970 status = MP_STATUS_UNSUPPORTED;
972 } else if (oid.objectType == MP_OBJECT_TYPE_DEVICE_PRODUCT) {
973 MP_GetMultipathLusDevProdFn PassFunc;
974 PassFunc = (MP_GetMultipathLusDevProdFn)
975 dlsym(plugintable[index].hdlPlugin,
976 "MP_GetMultipathLusDevProd");
978 if (PassFunc != NULL) {
979 status = PassFunc(oid, ppList);
980 } else {
981 status = MP_STATUS_UNSUPPORTED;
983 } else {
984 status = MP_STATUS_INVALID_PARAMETER;
988 (void) pthread_mutex_unlock(&mp_lib_mutex);
989 return (status);
994 *******************************************************************************
996 * Gets the properties of the specified logical unit.
998 * @param oid
999 * The object ID of the multipath logical unit.
1001 * @param pProps
1002 * A pointer to an MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES structure
1003 * allocated by the caller. On successful return, this structure
1004 * will contain the properties of the port specified by oid.
1006 * @return An MP_STATUS indicating if the operation was successful or if
1007 * an error occurred.
1009 * @retval MP_STATUS_SUCCESS
1010 * Returned when the operation is successful.
1012 * @retval MP_STATUS_INVALID_PARAMETER
1013 * Returned if pProps is NULL or specifies a memory area to
1014 * which data cannot be written.
1016 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1017 * Returned if oid does not specify any valid object type.
1019 * @retval MP_STATUS_OBJECT_NOT_FOUND
1020 * Returned if oid has an owner that is not currently known to
1021 * the system.
1023 *******************************************************************************
1025 MP_STATUS MP_GetMPLogicalUnitProperties(
1026 MP_OID oid,
1027 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES *pProps)
1029 MP_GetMPLogicalUnitPropertiesFn PassFunc;
1030 MP_UINT32 index;
1031 MP_STATUS status;
1033 if (pProps == NULL)
1034 return MP_STATUS_INVALID_PARAMETER;
1036 if ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
1037 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1038 return (status);
1041 (void) pthread_mutex_lock(&mp_lib_mutex);
1043 index = oid.ownerId - 1;
1044 if (plugintable[index].hdlPlugin != NULL) {
1045 PassFunc = (MP_GetMPLogicalUnitPropertiesFn)
1046 dlsym(plugintable[index].hdlPlugin,
1047 "MP_GetMPLogicalUnitProperties");
1049 if (PassFunc != NULL) {
1050 status = PassFunc(oid, pProps);
1051 } else {
1052 status = MP_STATUS_UNSUPPORTED;
1054 } else {
1055 status = MP_STATUS_FAILED;
1058 (void) pthread_mutex_unlock(&mp_lib_mutex);
1059 return (status);
1063 *******************************************************************************
1065 * Gets a list of the object IDs of all the path logical units associated
1066 * with the specified multipath logical unit, initiator port, or target port.
1068 * @param oid
1069 * The object ID of multipath logical unit, initiator port, or
1070 * target port.
1072 * @param ppList
1073 * A pointer to a pointer to an MP_OID_LIST structure.
1074 * On a successful return, this will contain a pointer to
1075 * an MP_OID_LIST that contains the object IDs of all the mp path
1076 * logical units associated with the specified OID.
1078 * @return An MP_STATUS indicating if the operation was successful or if
1079 * an error occurred.
1081 * @retval MP_STATUS_SUCCESS
1082 * Returned when the operation is successful.
1084 * @retval MP_STATUS_INVALID_PARAMETER
1085 * Returned if ppList pointer passed as placeholder for holding
1086 * the device product list is found to be invalid.
1088 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1089 * Returned if oid does not specify any valid object type.
1091 * @retval MP_STATUS_FAILED
1092 * Returned when the plugin for the specified oid is not found.
1094 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1095 * Returned when memory allocation failure occurs
1097 * @retval MP_STATUS_OBJECT_NOT_FOUND
1098 * Returned if oid has an owner that is not currently known to
1099 * the system.
1101 *******************************************************************************
1103 MP_STATUS MP_GetAssociatedPathOidList(
1104 MP_OID oid,
1105 MP_OID_LIST **ppList)
1107 MP_GetAssociatedPathOidListFn PassFunc;
1108 MP_UINT32 index;
1109 MP_STATUS status;
1111 if (ppList == NULL)
1112 return MP_STATUS_INVALID_PARAMETER;
1114 if (((status = validate_object(oid, MP_OBJECT_TYPE_INITIATOR_PORT,
1115 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
1116 ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT,
1117 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
1118 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
1119 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
1120 return (status);
1123 (void) pthread_mutex_lock(&mp_lib_mutex);
1125 index = oid.ownerId - 1;
1126 if (plugintable[index].hdlPlugin != NULL) {
1127 PassFunc = (MP_GetAssociatedPathOidListFn)
1128 dlsym(plugintable[index].hdlPlugin,
1129 "MP_GetAssociatedPathOidList");
1131 if (PassFunc != NULL) {
1132 status = PassFunc(oid, ppList);
1133 } else {
1134 status = MP_STATUS_UNSUPPORTED;
1136 } else {
1137 status = MP_STATUS_FAILED;
1140 (void) pthread_mutex_unlock(&mp_lib_mutex);
1141 return (status);
1145 *******************************************************************************
1147 * Gets the properties of the specified path logical unit.
1149 * @param oid
1150 * The object ID of the path logical unit.
1152 * @param pProps
1153 * A pointer to an MP_PATH_LOGICAL_UNIT_PROPERTIES structure
1154 * allocated by the caller. On successful return, this structure
1155 * will contain the properties of the port specified by oid.
1157 * @return An MP_STATUS indicating if the operation was successful or if
1158 * an error occurred.
1160 * @retval MP_STATUS_SUCCESS
1161 * Returned when the operation is successful.
1163 * @retval MP_STATUS_INVALID_PARAMETER
1164 * Returned if pProps is NULL or specifies a memory area to
1165 * which data cannot be written.
1167 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1168 * Returned if oid does not specify any valid object type.
1170 * @retval MP_STATUS_OBJECT_NOT_FOUND
1171 * Returned if oid has an owner that is not currently known to
1172 * the system.
1174 *******************************************************************************
1176 MP_STATUS MP_GetPathLogicalUnitProperties(
1177 MP_OID oid,
1178 MP_PATH_LOGICAL_UNIT_PROPERTIES *pProps)
1180 MP_GetPathLogicalUnitPropertiesFn PassFunc;
1181 MP_UINT32 index;
1182 MP_STATUS status;
1184 if (pProps == NULL)
1185 return MP_STATUS_INVALID_PARAMETER;
1187 if ((status = validate_object(oid, MP_OBJECT_TYPE_PATH_LU,
1188 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1189 return (status);
1192 (void) pthread_mutex_lock(&mp_lib_mutex);
1194 index = oid.ownerId - 1;
1195 if (plugintable[index].hdlPlugin != NULL) {
1196 PassFunc = (MP_GetPathLogicalUnitPropertiesFn)
1197 dlsym(plugintable[index].hdlPlugin,
1198 "MP_GetPathLogicalUnitProperties");
1200 if (PassFunc != NULL) {
1201 status = PassFunc(oid, pProps);
1202 } else {
1203 status = MP_STATUS_UNSUPPORTED;
1205 } else {
1206 status = MP_STATUS_FAILED;
1209 (void) pthread_mutex_unlock(&mp_lib_mutex);
1210 return (status);
1214 *******************************************************************************
1216 * Gets a list of the object IDs of all the target port group associated
1217 * with the specified multipath logical unit.
1219 * @param oid
1220 * The object ID of the multiple logical unit.
1222 * @param ppList
1223 * A pointer to a pointer to an MP_OID_LIST structure.
1224 * On a successful return, this will contain a pointer to
1225 * an MP_OID_LIST that contains the object IDs of all the target
1226 * port group associated with the specified multipath logical unit.
1228 * @return An MP_STATUS indicating if the operation was successful or if
1229 * an error occurred.
1231 * @retval MP_STATUS_SUCCESS
1232 * Returned when the operation is successful.
1234 * @retval MP_STATUS_INVALID_PARAMETER
1235 * Returned if ppList pointer passed as placeholder for holding
1236 * the target port group list is found to be invalid.
1238 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1239 * Returned if oid does not specify any valid object type.
1241 * @retval MP_STATUS_FAILED
1242 * Returned when the plugin for the specified oid is not found.
1244 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1245 * Returned when memory allocation failure occurs
1248 *******************************************************************************
1250 MP_STATUS MP_GetAssociatedTPGOidList(
1251 MP_OID oid,
1252 MP_OID_LIST **ppList)
1254 MP_GetAssociatedTPGOidListFn PassFunc;
1255 MP_UINT32 index;
1256 MP_STATUS status;
1258 if (ppList == NULL)
1259 return MP_STATUS_INVALID_PARAMETER;
1261 if ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
1262 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1263 return (status);
1266 (void) pthread_mutex_lock(&mp_lib_mutex);
1268 index = oid.ownerId - 1;
1269 if (plugintable[index].hdlPlugin != NULL) {
1270 PassFunc = (MP_GetAssociatedTPGOidListFn)
1271 dlsym(plugintable[index].hdlPlugin,
1272 "MP_GetAssociatedTPGOidList");
1274 if (PassFunc != NULL) {
1275 status = PassFunc(oid, ppList);
1276 } else {
1277 status = MP_STATUS_UNSUPPORTED;
1279 } else {
1280 status = MP_STATUS_FAILED;
1283 (void) pthread_mutex_unlock(&mp_lib_mutex);
1284 return (status);
1288 *******************************************************************************
1290 * Gets the properties of the specified target port group.
1292 * @param oid
1293 * The object ID of the target port group.
1295 * @param pProps
1296 * A pointer to an MP_TARGET_PORT_GROUP_PROPERTIES structure
1297 * allocated by the caller. On successful return, this structure
1298 * will contain the properties of the port specified by oid.
1300 * @return An MP_STATUS indicating if the operation was successful or if
1301 * an error occurred.
1303 * @retval MP_STATUS_SUCCESS
1304 * Returned when the operation is successful.
1306 * @retval MP_STATUS_INVALID_PARAMETER
1307 * Returned if pProps is NULL or specifies a memory area to
1308 * which data cannot be written.
1310 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1311 * Returned if oid does not specify any valid object type.
1313 * @retval MP_STATUS_OBJECT_NOT_FOUND
1314 * Returned if oid has an owner that is not currently known to
1315 * the system.
1317 *******************************************************************************
1319 MP_STATUS MP_GetTargetPortGroupProperties(
1320 MP_OID oid,
1321 MP_TARGET_PORT_GROUP_PROPERTIES *pProps)
1323 MP_GetTargetPortGroupPropertiesFn PassFunc;
1324 MP_UINT32 index;
1325 MP_STATUS status;
1327 if (pProps == NULL)
1328 return MP_STATUS_INVALID_PARAMETER;
1330 if ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT_GROUP,
1331 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1332 return (status);
1335 (void) pthread_mutex_lock(&mp_lib_mutex);
1337 index = oid.ownerId - 1;
1338 if (plugintable[index].hdlPlugin != NULL) {
1339 PassFunc = (MP_GetTargetPortGroupPropertiesFn)
1340 dlsym(plugintable[index].hdlPlugin,
1341 "MP_GetTargetPortGroupProperties");
1343 if (PassFunc != NULL) {
1344 status = PassFunc(oid, pProps);
1345 } else {
1346 status = MP_STATUS_UNSUPPORTED;
1348 } else {
1349 status = MP_STATUS_FAILED;
1352 (void) pthread_mutex_unlock(&mp_lib_mutex);
1353 return (status);
1357 *******************************************************************************
1359 * Gets a list of multipath logical units associated with the specific target
1360 * port group.
1362 * @param oid
1363 * The object ID of the target port group.
1365 * @param ppList
1366 * A pointer to a pointer to an MP_OID_LIST structure.
1367 * On a successful return, this will contain a pointer to
1368 * an MP_OID_LIST that contains the object IDs of all the multipath
1369 * logical units associated with the specified target port group.
1371 * @return An MP_STATUS indicating if the operation was successful or if
1372 * an error occurred.
1374 * @retval MP_STATUS_SUCCESS
1375 * Returned when the operation is successful.
1377 * @retval MP_STATUS_INVALID_PARAMETER
1378 * Returned if ppList pointer passed as placeholder for holding
1379 * the multipath logical unit list is found to be invalid.
1381 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1382 * Returned if oid does not specify any valid object type.
1384 * @retval MP_STATUS_FAILED
1385 * Returned when the plugin for the specified oid is not found.
1387 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1388 * Returned when memory allocation failure occurs
1390 *******************************************************************************
1392 MP_STATUS MP_GetMPLuOidListFromTPG(
1393 MP_OID oid,
1394 MP_OID_LIST **ppList)
1396 MP_GetMPLuOidListFromTPGFn PassFunc;
1397 MP_UINT32 index;
1398 MP_STATUS status;
1400 if (ppList == NULL)
1401 return MP_STATUS_INVALID_PARAMETER;
1403 if ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT_GROUP,
1404 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1405 return (status);
1408 (void) pthread_mutex_lock(&mp_lib_mutex);
1410 index = oid.ownerId - 1;
1411 if (plugintable[index].hdlPlugin != NULL) {
1412 PassFunc = (MP_GetMPLuOidListFromTPGFn)
1413 dlsym(plugintable[index].hdlPlugin,
1414 "MP_GetMPLuOidListFromTPG");
1416 if (PassFunc != NULL) {
1417 status = PassFunc(oid, ppList);
1418 } else {
1419 status = MP_STATUS_UNSUPPORTED;
1421 } else {
1422 status = MP_STATUS_FAILED;
1425 (void) pthread_mutex_unlock(&mp_lib_mutex);
1426 return (status);
1430 *******************************************************************************
1432 * Gets a list of the object IDs of all the proprietary load balance
1433 * algorithms associated with this plugin.
1435 * @param oid
1436 * The object ID of the plugin.
1438 * @param ppList
1439 * A pointer to a pointer to an MP_OID_LIST structure.
1440 * On a successful return, this will contain a pointer to
1441 * an MP_OID_LIST that contains the object IDs of all the proprietary
1442 * load balance algorithms associated with the specified plugin.
1444 * @return An MP_STATUS indicating if the operation was successful or if
1445 * an error occurred.
1447 * @retval MP_STATUS_SUCCESS
1448 * Returned when the operation is successful.
1450 * @retval MP_STATUS_INVALID_PARAMETER
1451 * Returned if ppList pointer passed as placeholder for holding
1452 * the proprietary load balance oid list is found to be invalid.
1454 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1455 * Returned if oid does not specify any valid object type.
1457 * @retval MP_STATUS_FAILED
1458 * Returned when the plugin for the specified oid is not found.
1460 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1461 * Returned when memory allocation failure occurs
1463 * @retval MP_STATUS_UNSUPPORTED
1464 * Returned when the API is not supported.
1466 *******************************************************************************
1468 MP_STATUS MP_GetProprietaryLoadBalanceOidList(
1469 MP_OID oid,
1470 MP_OID_LIST **ppList)
1472 MP_GetProprietaryLoadBalanceOidListPluginFn PassFunc;
1473 MP_UINT32 index;
1474 MP_STATUS status;
1476 if (ppList == NULL)
1477 return MP_STATUS_INVALID_PARAMETER;
1479 if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
1480 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1481 return (status);
1484 (void) pthread_mutex_lock(&mp_lib_mutex);
1486 index = oid.ownerId - 1;
1487 if (plugintable[index].hdlPlugin != NULL) {
1488 PassFunc = (MP_GetProprietaryLoadBalanceOidListPluginFn)
1489 dlsym(plugintable[index].hdlPlugin,
1490 "MP_GetProprietaryLoadBalanceOidListPlugin");
1492 if (PassFunc != NULL) {
1493 status = PassFunc(ppList);
1494 } else {
1495 status = MP_STATUS_UNSUPPORTED;
1497 } else {
1498 status = MP_STATUS_FAILED;
1501 (void) pthread_mutex_unlock(&mp_lib_mutex);
1502 return (status);
1506 *******************************************************************************
1508 * Gets the properties of the specified load balance properties structure.
1510 * @param oid
1511 * The object ID of the load balance properties structure.
1513 * @param pProps
1514 * A pointer to an MP_LOAD_BALANCE_PROPRIETARY_TYPE structure
1515 * allocated by the caller. On successful return, this structure
1516 * will contain the properties of the proprietary load balance algorithm
1517 * specified by oid.
1519 * @return An MP_STATUS indicating if the operation was successful or if
1520 * an error occurred.
1522 * @retval MP_STATUS_SUCCESS
1523 * Returned when the operation is successful.
1525 * @retval MP_STATUS_INVALID_PARAMETER
1526 * Returned if pProps is NULL or specifies a memory area to
1527 * which data cannot be written.
1529 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1530 * Returned if oid does not specify any valid object type.
1532 * @retval MP_STATUS_OBJECT_NOT_FOUND
1533 * Returned if oid has an owner that is not currently known to
1534 * the system.
1536 *******************************************************************************
1538 MP_STATUS MP_GetProprietaryLoadBalanceProperties (
1539 MP_OID oid,
1540 MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES *pProps)
1542 MP_GetProprietaryLoadBalancePropertiesFn PassFunc;
1543 MP_UINT32 index;
1544 MP_STATUS status;
1546 if (pProps == NULL)
1547 return MP_STATUS_INVALID_PARAMETER;
1549 if ((status = validate_object(oid, MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE,
1550 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1551 return (status);
1554 (void) pthread_mutex_lock(&mp_lib_mutex);
1556 index = oid.ownerId - 1;
1557 if (plugintable[index].hdlPlugin != NULL) {
1558 PassFunc = (MP_GetProprietaryLoadBalancePropertiesFn)
1559 dlsym(plugintable[index].hdlPlugin,
1560 "MP_GetProprietaryLoadBalanceProperties");
1562 if (PassFunc != NULL) {
1563 status = PassFunc(oid, pProps);
1564 } else {
1565 status = MP_STATUS_UNSUPPORTED;
1567 } else {
1568 status = MP_STATUS_FAILED;
1571 (void) pthread_mutex_unlock(&mp_lib_mutex);
1572 return (status);
1576 *******************************************************************************
1578 * Gets a list of the object IDs of the target ports in the specified target
1579 * port group.
1581 * @param oid
1582 * The object ID of the target port group.
1584 * @param ppList
1585 * A pointer to a pointer to an MP_OID_LIST structure.
1586 * On a successful return, this will contain a pointer to
1587 * an MP_OID_LIST that contains the object IDs of all the target ports
1588 * associated with the specified target port group.
1590 * @return An MP_STATUS indicating if the operation was successful or if
1591 * an error occurred.
1593 * @retval MP_STATUS_SUCCESS
1594 * Returned when the operation is successful.
1596 * @retval MP_STATUS_INVALID_PARAMETER
1597 * Returned if ppList pointer passed as placeholder for holding
1598 * the multipath logical unit list is found to be invalid.
1600 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1601 * Returned if oid does not specify any valid object type.
1603 * @retval MP_STATUS_FAILED
1604 * Returned when the plugin for the specified oid is not found.
1606 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1607 * Returned when memory allocation failure occurs
1609 *******************************************************************************
1611 MP_STATUS MP_GetTargetPortOidList(
1612 MP_OID oid,
1613 MP_OID_LIST **ppList)
1615 MP_GetTargetPortOidListFn PassFunc;
1616 MP_UINT32 index;
1617 MP_STATUS status;
1619 if (ppList == NULL)
1620 return MP_STATUS_INVALID_PARAMETER;
1622 if ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT_GROUP,
1623 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1624 return (status);
1627 (void) pthread_mutex_lock(&mp_lib_mutex);
1629 index = oid.ownerId - 1;
1630 if (plugintable[index].hdlPlugin != NULL) {
1631 PassFunc = (MP_GetTargetPortOidListFn)
1632 dlsym(plugintable[index].hdlPlugin,
1633 "MP_GetTargetPortOidList");
1635 if (PassFunc != NULL) {
1636 status = PassFunc(oid, ppList);
1637 } else {
1638 status = MP_STATUS_UNSUPPORTED;
1640 } else {
1641 status = MP_STATUS_FAILED;
1644 (void) pthread_mutex_unlock(&mp_lib_mutex);
1645 return (status);
1649 *******************************************************************************
1651 * Gets the properties of the specified target port.
1653 * @param oid
1654 * The object ID of the target port.
1656 * @param pProps
1657 * A pointer to an MP_TARGET_PORT_PROPERTIES structure
1658 * allocated by the caller. On successful return, this structure
1659 * will contain the properties of the port specified by oid.
1661 * @return An MP_STATUS indicating if the operation was successful or if
1662 * an error occurred.
1664 * @retval MP_STATUS_SUCCESS
1665 * Returned when the operation is successful.
1667 * @retval MP_STATUS_INVALID_PARAMETER
1668 * Returned if pProps is NULL or specifies a memory area to
1669 * which data cannot be written.
1671 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1672 * Returned if oid does not specify any valid object type.
1674 * @retval MP_STATUS_OBJECT_NOT_FOUND
1675 * Returned if oid has an owner that is not currently known to
1676 * the system.
1678 *******************************************************************************
1680 MP_STATUS MP_GetTargetPortProperties(
1681 MP_OID oid,
1682 MP_TARGET_PORT_PROPERTIES *pProps)
1684 MP_GetTargetPortPropertiesFn PassFunc;
1685 MP_UINT32 index;
1686 MP_STATUS status;
1688 if (pProps == NULL)
1689 return MP_STATUS_INVALID_PARAMETER;
1691 if ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT,
1692 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1693 return (status);
1696 (void) pthread_mutex_lock(&mp_lib_mutex);
1698 index = oid.ownerId - 1;
1699 if (plugintable[index].hdlPlugin != NULL) {
1700 PassFunc = (MP_GetTargetPortPropertiesFn)
1701 dlsym(plugintable[index].hdlPlugin,
1702 "MP_GetTargetPortProperties");
1704 if (PassFunc != NULL) {
1705 status = PassFunc(oid, pProps);
1706 } else {
1707 status = MP_STATUS_UNSUPPORTED;
1709 } else {
1710 status = MP_STATUS_FAILED;
1713 (void) pthread_mutex_unlock(&mp_lib_mutex);
1714 return (status);
1719 *******************************************************************************
1721 * Assign a multipath logical unit to a target port group.
1723 * @param tpgOid
1724 * An MP_TARGET_PORT_GROUP oid. The target port group currently in
1725 * active access state that the administrator would like the LU
1726 * assigned to.
1728 * @param luOid
1729 * An MP_MULTIPATH_LOGICAL_UNIT oid.
1731 * @return An MP_STATUS indicating if the operation was successful or if
1732 * an error occurred.
1734 * @retval MP_STATUS_SUCCESS
1735 * Returned when the operation is successful.
1737 * @retval MP_STATUS_INVALID_PARAMETER
1738 * Returned when luOid is not associated with tpgOid.
1740 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1741 * Returned if oid does not specify any valid object type.
1743 * @retval MP_STATUS_OBJECT_NOT_FOUND
1744 * Returned if oid has an owner that is not currently known to
1745 * the system.
1747 *******************************************************************************
1749 MP_STATUS MP_AssignLogicalUnitToTPG(
1750 MP_OID tpgOid,
1751 MP_OID luOid)
1753 MP_AssignLogicalUnitToTPGFn PassFunc;
1754 MP_UINT32 index;
1755 MP_STATUS status;
1757 if (luOid.ownerId != tpgOid.ownerId) {
1758 return (MP_STATUS_INVALID_PARAMETER);
1761 if ((status = validate_object(tpgOid, MP_OBJECT_TYPE_TARGET_PORT_GROUP,
1762 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1763 return (status);
1766 if ((status = validate_object(luOid, MP_OBJECT_TYPE_MULTIPATH_LU,
1767 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1768 return (status);
1771 (void) pthread_mutex_lock(&mp_lib_mutex);
1773 index = tpgOid.ownerId - 1;
1774 if (plugintable[index].hdlPlugin != NULL) {
1775 PassFunc = (MP_AssignLogicalUnitToTPGFn)
1776 dlsym(plugintable[index].hdlPlugin,
1777 "MP_AssignLogicalUnitToTPG");
1779 if (PassFunc != NULL) {
1780 status = PassFunc(tpgOid, luOid);
1781 } else {
1782 status = MP_STATUS_UNSUPPORTED;
1784 } else {
1785 status = MP_STATUS_FAILED;
1788 (void) pthread_mutex_unlock(&mp_lib_mutex);
1789 return (status);
1793 *******************************************************************************
1795 * Manually override the path for a logical unit. The path exclusively used to
1796 * access the logical unit until cleared.
1798 * @param logicalUnitOid
1799 * The object ID of the multipath logical unit.
1801 * @param pathOid
1802 * The object ID of the path logical unit.
1804 * @return An MP_STATUS indicating if the operation was successful or if
1805 * an error occurred.
1807 * @retval MP_STATUS_SUCCESS
1808 * Returned when the operation is successful.
1810 * @retval MP_STATUS_INVALID_PARAMETER
1811 * Returned if the oid of the object is not valid
1813 * @retval MP_STATUS_UNSUPPORTED
1814 * Returned when the implementation does not support the API
1816 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1817 * Returned if oid does not specify any valid object type.
1819 * @retval MP_STATUS_PATH_NONOPERATIONAL
1820 * Returned when the driver cannot communicate through selected path.
1822 *******************************************************************************
1824 MP_STATUS MP_SetOverridePath(
1825 MP_OID logicalUnitOid,
1826 MP_OID pathOid)
1828 MP_SetOverridePathFn PassFunc;
1829 MP_UINT32 index;
1830 MP_STATUS status;
1832 if ((status = validate_object(logicalUnitOid, MP_OBJECT_TYPE_MULTIPATH_LU,
1833 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1834 return (status);
1836 if ((status = validate_object(pathOid, MP_OBJECT_TYPE_PATH_LU,
1837 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1838 return (status);
1841 (void) pthread_mutex_lock(&mp_lib_mutex);
1843 index = pathOid.ownerId - 1;
1844 if (plugintable[index].hdlPlugin != NULL) {
1845 PassFunc = (MP_SetOverridePathFn)
1846 dlsym(plugintable[index].hdlPlugin,
1847 "MP_SetOverridePath");
1849 if (PassFunc != NULL) {
1850 status = PassFunc(logicalUnitOid, pathOid);
1851 } else {
1852 status = MP_STATUS_UNSUPPORTED;
1854 } else {
1855 status = MP_STATUS_FAILED;
1858 (void) pthread_mutex_unlock(&mp_lib_mutex);
1859 return (status);
1863 *******************************************************************************
1865 * Cancel a path override and re-enable load balancing.
1867 * @param luOid
1868 * An MP_MULTIPATH_LOGICAL_UNIT oid.
1870 * @return An MP_STATUS indicating if the operation was successful or if
1871 * an error occurred.
1873 * @retval MP_STATUS_SUCCESS
1874 * Returned when the operation is successful.
1876 * @retval MP_STATUS_INVALID_PARAMETER
1877 * Returned if MP_MULTIPATH_LOGICAL_UNIT with the luOid is not found.
1879 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1880 * Returned if oid does not specify any valid object type.
1882 * @retval MP_STATUS_OBJECT_NOT_FOUND
1883 * Returned if oid has an owner that is not currently known to
1884 * the system.
1886 *******************************************************************************
1888 MP_STATUS MP_CancelOverridePath(
1889 MP_OID luOid)
1891 MP_CancelOverridePathFn PassFunc;
1892 MP_UINT32 index;
1893 MP_STATUS status;
1895 if ((status = validate_object(luOid, MP_OBJECT_TYPE_MULTIPATH_LU,
1896 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1897 return (status);
1900 (void) pthread_mutex_lock(&mp_lib_mutex);
1902 index = luOid.ownerId - 1;
1903 if (plugintable[index].hdlPlugin != NULL) {
1904 PassFunc = (MP_CancelOverridePathFn)
1905 dlsym(plugintable[index].hdlPlugin,
1906 "MP_CancelOverridePath");
1908 if (PassFunc != NULL) {
1909 status = PassFunc(luOid);
1910 } else {
1911 status = MP_STATUS_UNSUPPORTED;
1913 } else {
1914 status = MP_STATUS_FAILED;
1917 (void) pthread_mutex_unlock(&mp_lib_mutex);
1918 return (status);
1922 *******************************************************************************
1924 * Enables Auto-failback.
1926 * @param oid
1927 * The oid of the plugin.
1929 * @return An MP_STATUS indicating if the operation was successful or if
1930 * an error occurred.
1932 * @retval MP_STATUS_SUCCESS
1933 * Returned when the operation is successful.
1935 * @retval MP_STATUS_INVALID_PARAMETER
1936 * Returned if oid is NULL or specifies a memory area that is not
1937 * a valid plugin oid.
1939 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1940 * Returned if oid does not specify any valid object type.
1942 *******************************************************************************
1944 MP_STATUS MP_EnableAutoFailback(
1945 MP_OID oid)
1947 MP_UINT32 index;
1948 MP_STATUS status;
1950 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
1951 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
1952 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
1953 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
1954 return (status);
1957 (void) pthread_mutex_lock(&mp_lib_mutex);
1959 index = oid.ownerId - 1;
1960 if (plugintable[index].hdlPlugin != NULL) {
1961 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
1962 MP_EnableAutoFailbackPluginFn PassFunc;
1963 PassFunc = (MP_EnableAutoFailbackPluginFn)
1964 dlsym(plugintable[index].hdlPlugin,
1965 "MP_EnableAutoFailbackPlugin");
1967 if (PassFunc != NULL) {
1968 status = PassFunc();
1969 } else {
1970 status = MP_STATUS_UNSUPPORTED;
1972 } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) {
1973 MP_EnableAutoFailbackLuFn PassFunc;
1974 PassFunc = (MP_EnableAutoFailbackLuFn)
1975 dlsym(plugintable[index].hdlPlugin,
1976 "MP_EnableAutoFailbackLu");
1978 if (PassFunc != NULL) {
1979 status = PassFunc(oid);
1980 } else {
1981 status = MP_STATUS_UNSUPPORTED;
1983 } else {
1984 status = MP_STATUS_INVALID_PARAMETER;
1988 (void) pthread_mutex_unlock(&mp_lib_mutex);
1989 return (status);
1993 *******************************************************************************
1995 * Enables Auto-probing.
1997 * @param oid
1998 * The oid of the plugin or the multipath logical unit.
2000 * @return An MP_STATUS indicating if the operation was successful or if
2001 * an error occurred.
2003 * @retval MP_STATUS_SUCCESS
2004 * Returned when the operation is successful.
2006 * @retval MP_STATUS_INVALID_PARAMETER
2007 * Returned if oid is NULL or specifies a memory area that is not
2008 * a valid plugin oid.
2010 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2011 * Returned if oid does not specify any valid object type.
2013 *******************************************************************************
2015 MP_STATUS MP_EnableAutoProbing(
2016 MP_OID oid)
2018 MP_UINT32 index;
2019 MP_STATUS status;
2021 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2022 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2023 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
2024 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
2025 return (status);
2028 (void) pthread_mutex_lock(&mp_lib_mutex);
2030 index = oid.ownerId - 1;
2031 if (plugintable[index].hdlPlugin != NULL) {
2032 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
2033 MP_EnableAutoProbingPluginFn PassFunc;
2034 PassFunc = (MP_EnableAutoProbingPluginFn)
2035 dlsym(plugintable[index].hdlPlugin,
2036 "MP_EnableAutoProbingPlugin");
2038 if (PassFunc != NULL) {
2039 status = PassFunc();
2040 } else {
2041 status = MP_STATUS_UNSUPPORTED;
2043 } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) {
2044 MP_EnableAutoProbingLuFn PassFunc;
2045 PassFunc = (MP_EnableAutoProbingLuFn)
2046 dlsym(plugintable[index].hdlPlugin,
2047 "MP_EnableAutoProbingLu");
2049 if (PassFunc != NULL) {
2050 status = PassFunc(oid);
2051 } else {
2052 status = MP_STATUS_UNSUPPORTED;
2054 } else {
2055 status = MP_STATUS_INVALID_PARAMETER;
2059 (void) pthread_mutex_unlock(&mp_lib_mutex);
2060 return (status);
2064 *******************************************************************************
2066 * Disables Auto-failback.
2068 * @param oid
2069 * The oid of the plugin.
2071 * @return An MP_STATUS indicating if the operation was successful or if
2072 * an error occurred.
2074 * @retval MP_STATUS_SUCCESS
2075 * Returned when the operation is successful.
2077 * @retval MP_STATUS_INVALID_PARAMETER
2078 * Returned if oid is NULL or specifies a memory area that is not
2079 * a valid plugin oid.
2081 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2082 * Returned if oid does not specify any valid object type.
2084 *******************************************************************************
2086 MP_STATUS MP_DisableAutoFailback(
2087 MP_OID oid)
2089 MP_UINT32 index;
2090 MP_STATUS status;
2092 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2093 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2094 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
2095 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
2096 return (status);
2099 (void) pthread_mutex_lock(&mp_lib_mutex);
2101 index = oid.ownerId - 1;
2102 if (plugintable[index].hdlPlugin != NULL) {
2103 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
2104 MP_DisableAutoFailbackPluginFn PassFunc;
2105 PassFunc = (MP_DisableAutoFailbackPluginFn)
2106 dlsym(plugintable[index].hdlPlugin,
2107 "MP_DisableAutoFailbackPlugin");
2109 if (PassFunc != NULL) {
2110 status = PassFunc();
2111 } else {
2112 status = MP_STATUS_UNSUPPORTED;
2114 } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) {
2115 MP_DisableAutoFailbackLuFn PassFunc;
2116 PassFunc = (MP_DisableAutoFailbackLuFn)
2117 dlsym(plugintable[index].hdlPlugin,
2118 "MP_DisableAutoFailbackLu");
2120 if (PassFunc != NULL) {
2121 status = PassFunc(oid);
2122 } else {
2123 status = MP_STATUS_UNSUPPORTED;
2125 } else {
2126 status = MP_STATUS_INVALID_PARAMETER;
2130 (void) pthread_mutex_unlock(&mp_lib_mutex);
2131 return (status);
2135 *******************************************************************************
2137 * Disables Auto-probing.
2139 * @param oid
2140 * The oid of the plugin or the multipath logical unit.
2142 * @return An MP_STATUS indicating if the operation was successful or if
2143 * an error occurred.
2145 * @retval MP_STATUS_SUCCESS
2146 * Returned when the operation is successful.
2148 * @retval MP_STATUS_INVALID_PARAMETER
2149 * Returned if oid is NULL or specifies a memory area that is not
2150 * a valid plugin oid.
2152 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2153 * Returned if oid does not specify any valid object type.
2155 *******************************************************************************
2157 MP_STATUS MP_DisableAutoProbing(
2158 MP_OID oid)
2160 MP_UINT32 index;
2161 MP_STATUS status;
2163 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2164 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2165 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
2166 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
2167 return (status);
2170 (void) pthread_mutex_lock(&mp_lib_mutex);
2172 index = oid.ownerId - 1;
2173 if (plugintable[index].hdlPlugin != NULL) {
2174 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
2175 MP_DisableAutoProbingPluginFn PassFunc;
2176 PassFunc = (MP_DisableAutoProbingPluginFn)
2177 dlsym(plugintable[index].hdlPlugin,
2178 "MP_DisableAutoProbingPlugin");
2180 if (PassFunc != NULL) {
2181 status = PassFunc();
2182 } else {
2183 status = MP_STATUS_UNSUPPORTED;
2185 } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) {
2186 MP_DisableAutoFailbackLuFn PassFunc;
2187 PassFunc = (MP_DisableAutoProbingLuFn)
2188 dlsym(plugintable[index].hdlPlugin,
2189 "MP_DisableAutoProbingLu");
2191 if (PassFunc != NULL) {
2192 status = PassFunc(oid);
2193 } else {
2194 status = MP_STATUS_UNSUPPORTED;
2196 } else {
2197 status = MP_STATUS_INVALID_PARAMETER;
2201 (void) pthread_mutex_unlock(&mp_lib_mutex);
2202 return (status);
2206 *******************************************************************************
2208 * Enables a path. This API may cause failover in a logical unit with
2209 * asymmetric access.
2211 * @param oid
2212 * The oid of the path.
2214 * @return An MP_STATUS indicating if the operation was successful or if
2215 * an error occurred.
2217 * @retval MP_STATUS_SUCCESS
2218 * Returned when the operation is successful.
2220 * @retval MP_STATUS_INVALID_PARAMETER
2221 * Returned if oid is NULL or specifies a memory area that is not
2222 * a valid path oid.
2224 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2225 * Returned if oid does not specify any valid object type.
2227 *******************************************************************************
2229 MP_STATUS MP_EnablePath(
2230 MP_OID oid)
2232 MP_EnablePathFn PassFunc;
2233 MP_UINT32 index;
2234 MP_STATUS status;
2236 if ((status = validate_object(oid, MP_OBJECT_TYPE_PATH_LU,
2237 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2238 return (status);
2241 (void) pthread_mutex_lock(&mp_lib_mutex);
2243 index = oid.ownerId - 1;
2244 if (plugintable[index].hdlPlugin != NULL) {
2245 PassFunc = (MP_EnablePathFn)
2246 dlsym(plugintable[index].hdlPlugin,
2247 "MP_EnablePath");
2249 if (PassFunc != NULL) {
2250 status = PassFunc(oid);
2251 } else {
2252 status = MP_STATUS_UNSUPPORTED;
2254 } else {
2255 status = MP_STATUS_FAILED;
2258 (void) pthread_mutex_unlock(&mp_lib_mutex);
2259 return (status);
2263 *******************************************************************************
2265 * Disables a path. This API may cause failover in a logical unit with
2266 * asymmetric access. This API may cause a logical unit to become unavailable.
2268 * @param oid
2269 * The oid of the path.
2271 * @return An MP_STATUS indicating if the operation was successful or if
2272 * an error occurred.
2274 * @retval MP_STATUS_SUCCESS
2275 * Returned when the operation is successful.
2277 * @retval MP_STATUS_INVALID_PARAMETER
2278 * Returned if oid is NULL or specifies a memory area that is not
2279 * a valid path oid.
2281 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2282 * Returned if oid does not specify any valid object type.
2284 *******************************************************************************
2286 MP_STATUS MP_DisablePath(
2287 MP_OID oid)
2289 MP_DisablePathFn PassFunc;
2290 MP_UINT32 index;
2291 MP_STATUS status;
2293 if ((status = validate_object(oid, MP_OBJECT_TYPE_PATH_LU,
2294 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2295 return (status);
2298 (void) pthread_mutex_lock(&mp_lib_mutex);
2300 index = oid.ownerId - 1;
2301 if (plugintable[index].hdlPlugin != NULL) {
2302 PassFunc = (MP_DisablePathFn)
2303 dlsym(plugintable[index].hdlPlugin,
2304 "MP_DisablePath");
2306 if (PassFunc != NULL) {
2307 status = PassFunc(oid);
2308 } else {
2309 status = MP_STATUS_UNSUPPORTED;
2311 } else {
2312 status = MP_STATUS_FAILED;
2315 (void) pthread_mutex_unlock(&mp_lib_mutex);
2316 return (status);
2320 *******************************************************************************
2322 * Set the multipath logical unit s load balancing policy.
2324 * @param logicalUnitoid
2325 * The object ID of the multipath logical unit.
2327 * @param loadBanlance
2328 * The desired load balance policy for the specified logical unit.
2330 * @return An MP_STATUS indicating if the operation was successful or if
2331 * an error occurred.
2333 * @retval MP_STATUS_SUCCESS
2334 * Returned when the operation is successful.
2336 * @retval MP_STATUS_INVALID_PARAMETER
2337 * Returned if no MP_MULTIPATH_LOGICAL_UNIT associated with
2338 * @ref ligicalUnitrOid is found or invalid MP_LOAD_BALANCE_TYPE is
2339 * specified.
2341 * @retval MP_STATUS_FAILED
2342 * Returned when the specified loadBalance type cannot be handled
2343 * by the plugin.
2345 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2346 * Returned if oid does not specify any valid object type.
2348 *******************************************************************************
2350 MP_STATUS MP_SetLogicalUnitLoadBalanceType(
2351 MP_OID logicalUnitOid,
2352 MP_LOAD_BALANCE_TYPE loadBalance)
2354 MP_SetLogicalUnitLoadBalanceTypeFn PassFunc;
2355 MP_UINT32 index;
2356 MP_STATUS status;
2358 if ((status = validate_object(logicalUnitOid,
2359 MP_OBJECT_TYPE_MULTIPATH_LU,
2360 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2361 return (status);
2364 (void) pthread_mutex_lock(&mp_lib_mutex);
2366 index = logicalUnitOid.ownerId - 1;
2367 if (plugintable[index].hdlPlugin != NULL) {
2368 PassFunc = (MP_SetLogicalUnitLoadBalanceTypeFn)
2369 dlsym(plugintable[index].hdlPlugin,
2370 "MP_SetLogicalUnitLoadBalanceType");
2372 if (PassFunc != NULL) {
2373 status = PassFunc(logicalUnitOid, loadBalance);
2374 } else {
2375 status = MP_STATUS_UNSUPPORTED;
2377 } else {
2378 status = MP_STATUS_FAILED;
2381 (void) pthread_mutex_unlock(&mp_lib_mutex);
2382 return (status);
2386 *******************************************************************************
2388 * Set the weight to be assigned to a particular path.
2390 * @param pathOid
2391 * The object ID of the path logical unit.
2393 * @param weight
2394 * weight that will be assigned to the path logical unit.
2396 * @return An MP_STATUS indicating if the operation was successful or if
2397 * an error occurred.
2399 * @retval MP_STATUS_SUCCESS
2400 * Returned when the operation is successful.
2402 * @retval MP_STATUS_OBJECT_NOT_FOUND
2403 * Returned when the MP Path specified by the PathOid could not be
2404 * found.
2406 * @retval MP_STATUS_UNSUPPORTED
2407 * Returned when the implementation does not support the API
2409 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2410 * Returned if oid does not specify any valid object type.
2412 * @retval MP_STATUS_FAILED
2413 * Returned when the operation failed.
2415 * @retval MP_STATUS_PATH_NONOPERATIONAL
2416 * Returned when the driver cannot communicate through selected path.
2418 * @retval MP_STATUS_INVALID_WEIGHT
2419 * Returned when the weight parameter is greater than the plugin's
2420 * maxWeight property.
2422 *******************************************************************************
2424 MP_STATUS MP_SetPathWeight(
2425 MP_OID pathOid,
2426 MP_UINT32 weight)
2428 MP_SetPathWeightFn PassFunc;
2429 MP_UINT32 index;
2430 MP_STATUS status;
2432 if ((status = validate_object(pathOid, MP_OBJECT_TYPE_PATH_LU,
2433 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2434 return (status);
2437 (void) pthread_mutex_lock(&mp_lib_mutex);
2439 index = pathOid.ownerId - 1;
2440 if (plugintable[index].hdlPlugin != NULL) {
2441 PassFunc = (MP_SetPathWeightFn)
2442 dlsym(plugintable[index].hdlPlugin,
2443 "MP_SetPathWeight");
2445 if (PassFunc != NULL) {
2446 status = PassFunc(pathOid, weight);
2447 } else {
2448 status = MP_STATUS_UNSUPPORTED;
2450 } else {
2451 status = MP_STATUS_FAILED;
2454 (void) pthread_mutex_unlock(&mp_lib_mutex);
2455 return (status);
2459 *******************************************************************************
2461 * Set the default load balance policy for the plugin.
2463 * @param oid
2464 * The object ID of the plugin
2466 * @param loadBalance
2467 * The desired default load balance policy for the specified plugin.
2469 * @return An MP_STATUS indicating if the operation was successful or if
2470 * an error occurred.
2472 * @retval MP_STATUS_SUCCESS
2473 * Returned when the operation is successful.
2475 * @retval MP_STATUS_OBJECT_NOT_FOUND
2476 * Returned when the the plugin specified by @ref oid could not be
2477 * found.
2479 * @retval MP_STATUS_INVALID_PARAMETER
2480 * Returned if the oid of the object is not valid.
2482 * @retval MP_STATUS_UNSUPPORTED
2483 * Returned when the implementation does not support the API
2485 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2486 * Returned if oid does not specify any valid object type.
2488 * @retval MP_STATUS_FAILED
2489 * Returned when the specified loadBalance type cannot be handled
2490 * by the plugin.
2492 *******************************************************************************
2494 MP_STATUS MP_SetPluginLoadBalanceType(
2495 MP_OID oid,
2496 MP_LOAD_BALANCE_TYPE loadBalance)
2498 MP_SetPluginLoadBalanceTypePluginFn PassFunc;
2499 MP_UINT32 index;
2500 MP_STATUS status;
2502 if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2503 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2504 return (status);
2507 (void) pthread_mutex_lock(&mp_lib_mutex);
2509 index = oid.ownerId - 1;
2510 if (plugintable[index].hdlPlugin != NULL) {
2511 PassFunc = (MP_SetPluginLoadBalanceTypePluginFn)
2512 dlsym(plugintable[index].hdlPlugin,
2513 "MP_SetPluginLoadBalanceTypePlugin");
2515 if (PassFunc != NULL) {
2516 status = PassFunc(loadBalance);
2517 } else {
2518 status = MP_STATUS_UNSUPPORTED;
2520 } else {
2521 status = MP_STATUS_FAILED;
2524 (void) pthread_mutex_unlock(&mp_lib_mutex);
2525 return (status);
2529 *******************************************************************************
2531 * Set the failback polling rates. Setting both rates to zero disables polling.
2533 * @param pluginOid
2534 * The object ID of the plugin or multipath lu.
2536 * @param pollingRate
2537 * The value to be set in MP_PLUGIN_PROPERTIES currentPollingRate.or
2538 * MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES pollingRate.
2540 * @return An MP_STATUS indicating if the operation was successful or if
2541 * an error occurred.
2543 * @retval MP_STATUS_SUCCESS
2544 * Returned when the operation is successful.
2546 * @retval MP_STATUS_OBJECT_NOT_FOUND
2547 * Returned when the the plugin specified by @ref oid could not be
2548 * found.
2550 * @retval MP_STATUS_INVALID_PARAMETER
2551 * Returned if one of the polling values is outside the range
2552 * supported by the driver.
2554 * @retval MP_STATUS_UNSUPPORTED
2555 * Returned when the implementation does not support the API
2557 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2558 * Returned if oid does not specify any valid object type.
2560 *******************************************************************************
2562 MP_STATUS MP_SetFailbackPollingRate(
2563 MP_OID oid,
2564 MP_UINT32 pollingRate)
2566 MP_UINT32 index;
2567 MP_STATUS status;
2569 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2570 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2571 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
2572 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
2573 return (status);
2576 (void) pthread_mutex_lock(&mp_lib_mutex);
2578 index = oid.ownerId - 1;
2579 if (plugintable[index].hdlPlugin != NULL) {
2580 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
2581 MP_SetFailbackPollingRatePluginFn PassFunc;
2582 PassFunc = (MP_SetFailbackPollingRatePluginFn)
2583 dlsym(plugintable[index].hdlPlugin,
2584 "MP_SetFailbackPollingRatePlugin");
2586 if (PassFunc != NULL) {
2587 status = PassFunc(pollingRate);
2588 } else {
2589 status = MP_STATUS_UNSUPPORTED;
2591 } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) {
2592 MP_SetFailbackPollingRateLuFn PassFunc;
2593 PassFunc = (MP_SetFailbackPollingRateLuFn)
2594 dlsym(plugintable[index].hdlPlugin,
2595 "MP_SetFailbackPollingRateLu");
2597 if (PassFunc != NULL) {
2598 status = PassFunc(oid, pollingRate);
2599 } else {
2600 status = MP_STATUS_UNSUPPORTED;
2602 } else {
2603 status = MP_STATUS_INVALID_PARAMETER;
2607 (void) pthread_mutex_unlock(&mp_lib_mutex);
2608 return (status);
2612 *******************************************************************************
2614 * Set the probing polling rates. Setting both rates to zero disables polling.
2616 * @param pluginOid
2617 * The object ID of either the plugin or a multipath logical unit.
2619 * @param pollingRate
2620 * The value to be set in MP_PLUGIN_PROPERTIES current pollingRate or
2621 * MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES pollingRate.
2623 * @return An MP_STATUS indicating if the operation was successful or if
2624 * an error occurred.
2626 * @retval MP_STATUS_SUCCESS
2627 * Returned when the operation is successful.
2629 * @retval MP_STATUS_OBJECT_NOT_FOUND
2630 * Returned when the the plugin specified by @ref oid could not be
2631 * found.
2633 * @retval MP_STATUS_INVALID_PARAMETER
2634 * Returned if one of the polling values is outside the range
2635 * supported by the driver.
2637 * @retval MP_STATUS_UNSUPPORTED
2638 * Returned when the implementation does not support the API
2640 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2641 * Returned if oid does not specify any valid object type.
2643 *******************************************************************************
2645 MP_STATUS MP_SetProbingPollingRate(
2646 MP_OID oid,
2647 MP_UINT32 pollingRate)
2649 MP_UINT32 index;
2650 MP_STATUS status;
2652 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2653 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2654 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
2655 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
2656 return (status);
2659 (void) pthread_mutex_lock(&mp_lib_mutex);
2661 index = oid.ownerId - 1;
2662 if (plugintable[index].hdlPlugin != NULL) {
2663 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
2664 MP_SetProbingPollingRatePluginFn PassFunc;
2665 PassFunc = (MP_SetProbingPollingRatePluginFn)
2666 dlsym(plugintable[index].hdlPlugin,
2667 "MP_SetProbingPollingRatePlugin");
2669 if (PassFunc != NULL) {
2670 status = PassFunc(pollingRate);
2671 } else {
2672 status = MP_STATUS_UNSUPPORTED;
2674 } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) {
2675 MP_SetProbingPollingRateLuFn PassFunc;
2676 PassFunc = (MP_SetProbingPollingRateLuFn)
2677 dlsym(plugintable[index].hdlPlugin,
2678 "MP_SetProbingPollingRateLu");
2680 if (PassFunc != NULL) {
2681 status = PassFunc(oid, pollingRate);
2682 } else {
2683 status = MP_STATUS_UNSUPPORTED;
2685 } else {
2686 status = MP_STATUS_INVALID_PARAMETER;
2690 (void) pthread_mutex_unlock(&mp_lib_mutex);
2691 return (status);
2695 *******************************************************************************
2697 * Set proprietary properties in supported object instances.
2699 * @param pluginOid
2700 * The object ID of MP_LOAD_BALANCE_PROPRIETARY_TYPE, MP_PLUGIN_PROPERTIES
2701 * or MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES.
2703 * @param count
2704 * The number of valid items in pPropertyList.
2706 * @param pPropertyList
2707 * A pointer to an array of property name/value pairs. This array must
2708 * contain the same number of elements as count.
2710 * @return An MP_STATUS indicating if the operation was successful or if
2711 * an error occurred.
2713 * @retval MP_STATUS_SUCCESS
2714 * Returned when the operation is successful.
2716 * @retval MP_STATUS_OBJECT_NOT_FOUND
2717 * Returned when the the plugin specified by @ref oid could not be
2718 * found.
2720 * @retval MP_STATUS_INVALID_PARAMETER
2721 * Returned if one of the polling values is outside the range
2722 * supported by the driver.
2724 * @retval MP_STATUS_UNSUPPORTED
2725 * Returned when the implementation does not support the API
2727 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2728 * Returned if oid does not specify any valid object type.
2730 *******************************************************************************
2732 MP_STATUS MP_SetProprietaryProperties(
2733 MP_OID oid,
2734 MP_UINT32 count,
2735 MP_PROPRIETARY_PROPERTY *pPropertyList)
2737 MP_SetProprietaryPropertiesFn PassFunc;
2738 MP_UINT32 index;
2739 MP_STATUS status;
2741 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2742 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2743 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
2744 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2745 ((status = validate_object(oid, MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE,
2746 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
2747 return (status);
2750 (void) pthread_mutex_lock(&mp_lib_mutex);
2752 index = oid.ownerId - 1;
2753 if (plugintable[index].hdlPlugin != NULL) {
2754 PassFunc = (MP_SetProprietaryPropertiesFn)
2755 dlsym(plugintable[index].hdlPlugin,
2756 "MP_SetProprietaryProperties");
2758 if (PassFunc != NULL) {
2759 status = PassFunc(oid, count, pPropertyList);
2760 } else {
2761 status = MP_STATUS_UNSUPPORTED;
2763 } else {
2764 status = MP_STATUS_FAILED;
2767 (void) pthread_mutex_unlock(&mp_lib_mutex);
2768 return (status);
2772 *******************************************************************************
2774 * Set the access state for a list of target port groups. This allows
2775 * a client to force a failover or failback to a desired set of target port
2776 * groups.
2778 * @param luOid
2779 * The object ID of the logical unit where the command is sent.
2781 * @param count
2782 * The number of valid items in the pTpgStateList.
2784 * @param pTpgStateList
2785 * A pointer to an array of TPG/access-state values. This array must
2786 * contain the same number of elements as @ref count.
2788 * @return An MP_STATUS indicating if the operation was successful or if
2789 * an error occurred.
2791 * @retval MP_STATUS_SUCCESS
2792 * Returned when the operation is successful.
2794 * @retval MP_STATUS_OBJECT_NOT_FOUND
2795 * Returned when the MP_MULTIPATH_LOGICAL_UNIT associated with @ref
2796 * oid could not be found.
2798 * @retval MP_STATUS_INVALID_PARAMETER
2799 * Returned if pTpgStateList is null or if one of the TPGs referenced
2800 * in the list is not associated with the specified MP logical unit.
2802 * @retval MP_STATUS_UNSUPPORTED
2803 * Returned when the implementation does not support the API
2805 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2806 * Returned if oid does not specify any valid object type.
2808 * @retval MP_STATUS_ACCESS_STATE_INVALID
2809 * Returned if the target device returns a status indicating the caller
2810 * is attempting to establish an illegal combination of access states.
2812 * @retval MP_STATUS_FAILED
2813 * Returned if the underlying interface failed the commend for some
2814 * reason other than MP_STATUS_ACCESS_STATE_INVALID
2816 *******************************************************************************
2818 MP_STATUS MP_SetTPGAccess(
2819 MP_OID luOid,
2820 MP_UINT32 count,
2821 MP_TPG_STATE_PAIR *pTpgStateList)
2823 MP_SetTPGAccessFn PassFunc;
2824 MP_UINT32 index;
2825 MP_STATUS status;
2827 if ((status = validate_object(luOid, MP_OBJECT_TYPE_MULTIPATH_LU,
2828 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2829 return (status);
2832 (void) pthread_mutex_lock(&mp_lib_mutex);
2834 index = luOid.ownerId - 1;
2835 if (plugintable[index].hdlPlugin != NULL) {
2836 PassFunc = (MP_SetTPGAccessFn)
2837 dlsym(plugintable[index].hdlPlugin,
2838 "MP_SetTPGAccess");
2840 if (PassFunc != NULL) {
2841 status = PassFunc(luOid, count, pTpgStateList);
2842 } else {
2843 status = MP_STATUS_UNSUPPORTED;
2845 } else {
2846 status = MP_STATUS_FAILED;
2849 (void) pthread_mutex_unlock(&mp_lib_mutex);
2850 return (status);
2854 *******************************************************************************
2856 * Registers a client function that is to be called
2857 * whenever the property of an an object changes.
2859 * @param pClientFn,
2860 * A pointer to an MP_OBJECT_PROPERTY_FN function defined by the
2861 * client. On successful return this function will be called to
2862 * inform the client of objects that have had one or more properties
2863 * change.
2865 * @param objectType
2866 * The type of object the client wishes to deregister for
2867 * property change callbacks. If null, then all objects types are
2868 * deregistered.
2870 * @param pCallerData
2871 * A pointer that is passed to the callback routine with each event.
2872 * This may be used by the caller to correlate the event to source of
2873 * the registration.
2875 * @return An MP_STATUS indicating if the operation was successful or if
2876 * an error occurred.
2878 * @retval MP_STATUS_SUCCESS
2879 * Returned when the operation is successful.
2881 * @retval MP_STATUS_INVALID_PARAMETER
2882 * Returned if pClientFn is NULL or specifies a memory area
2883 * that is not executable.
2885 * @retval MP_STATUS_FN_REPLACED
2886 * Returned when an existing client function is replaced with the one
2887 * specified in pClientFn.
2889 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2890 * Returned if oid does not specify any valid object type.
2892 *******************************************************************************
2894 MP_STATUS MP_RegisterForObjectPropertyChanges(
2895 MP_OBJECT_PROPERTY_FN pClientFn,
2896 MP_OBJECT_TYPE objectType,
2897 void *pCallerData,
2898 MP_OID pluginOid)
2900 MP_RegisterForObjectPropertyChangesPluginFn PassFunc;
2901 MP_UINT32 i;
2902 MP_UINT32 index;
2903 MP_STATUS status;
2905 if (pClientFn == NULL) {
2906 return (MP_STATUS_INVALID_PARAMETER);
2909 if (objectType > MP_OBJECT_TYPE_MAX) {
2910 return (MP_STATUS_INVALID_OBJECT_TYPE);
2913 if (!(is_zero_oid(pluginOid))) {
2914 if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN,
2915 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2916 return (status);
2920 (void) pthread_mutex_lock(&mp_lib_mutex);
2922 if (is_zero_oid(pluginOid)) {
2923 for (i = 0; i < number_of_plugins; i++) {
2924 if (plugintable[i].hdlPlugin != NULL) {
2925 PassFunc = (MP_RegisterForObjectPropertyChangesPluginFn)
2926 dlsym(plugintable[i].hdlPlugin,
2927 "MP_RegisterForObjectPropertyChangesPlugin");
2930 if (PassFunc != NULL) {
2931 status =
2932 PassFunc(pClientFn, objectType, pCallerData);
2933 /* ignore an error and continue */
2936 } else {
2937 index = pluginOid.ownerId - 1;
2938 if (plugintable[index].hdlPlugin != NULL) {
2939 PassFunc = (MP_RegisterForObjectPropertyChangesPluginFn)
2940 dlsym(plugintable[index].hdlPlugin,
2941 "MP_RegisterForObjectPropertyChangesPlugin");
2944 if (PassFunc != NULL) {
2945 status = PassFunc(pClientFn, objectType, pCallerData);
2948 (void) pthread_mutex_unlock(&mp_lib_mutex);
2949 return (status);
2953 *******************************************************************************
2955 * Deregisters a previously registered client function that is to be invoked
2956 * whenever an object's property changes.
2958 * @param pClientFn,
2959 * A pointer to an MP_OBJECT_PROPERTY_FN function defined by the
2960 * client that was previously registered using
2961 * the MP_RegisterForObjectPropertyChanges API. On successful return
2962 * this function will no longer be called to inform the client of
2963 * object property changes.
2965 * @param objectType
2966 * The type of object the client wishes to deregister for
2967 * property change callbacks. If null, then all objects types are
2968 * deregistered.
2970 * @return An MP_STATUS indicating if the operation was successful or if
2971 * an error occurred.
2973 * @retval MP_STATUS_SUCCESS
2974 * Returned when the operation is successful.
2976 * @retval MP_STATUS_INVALID_PARAMETER
2977 * Returned if pClientFn is NULL or specifies a memory area
2978 * that is not executable.
2980 * @retval MP_STATUS_UNKNOWN_FN
2981 * Returned if pClientFn is not the same as the previously registered
2982 * function.
2984 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2985 * Returned if oid does not specify any valid object type.
2987 * @retval MP_STATUS_FAILED
2988 * Returned if pClientFn deregistration is not possible at this time.
2990 *******************************************************************************
2992 MP_STATUS MP_DeregisterForObjectPropertyChanges(
2993 MP_OBJECT_PROPERTY_FN pClientFn,
2994 MP_OBJECT_TYPE objectType,
2995 MP_OID pluginOid)
2997 MP_DeregisterForObjectPropertyChangesPluginFn PassFunc;
2998 MP_UINT32 i;
2999 MP_UINT32 index;
3000 MP_STATUS status;
3002 if (pClientFn == NULL) {
3003 return (MP_STATUS_INVALID_PARAMETER);
3006 if (objectType > MP_OBJECT_TYPE_MAX) {
3007 return (MP_STATUS_INVALID_OBJECT_TYPE);
3010 if (!(is_zero_oid(pluginOid))) {
3011 if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN,
3012 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
3013 return (status);
3017 (void) pthread_mutex_lock(&mp_lib_mutex);
3019 if (is_zero_oid(pluginOid)) {
3020 for (i = 0; i < number_of_plugins; i++) {
3021 if (plugintable[i].hdlPlugin != NULL) {
3022 PassFunc = (MP_DeregisterForObjectPropertyChangesPluginFn)
3023 dlsym(plugintable[i].hdlPlugin,
3024 "MP_DeregisterForObjectPropertyChangesPlugin");
3027 if (PassFunc != NULL) {
3028 status = PassFunc(pClientFn, objectType);
3031 } else {
3032 index = pluginOid.ownerId - 1;
3033 if (plugintable[index].hdlPlugin != NULL) {
3034 PassFunc = (MP_DeregisterForObjectPropertyChangesPluginFn)
3035 dlsym(plugintable[index].hdlPlugin,
3036 "MP_DeregisterForObjectPropertyChangesPlugin");
3039 if (PassFunc != NULL) {
3040 status = PassFunc(pClientFn, objectType);
3043 (void) pthread_mutex_unlock(&mp_lib_mutex);
3044 return (status);
3048 *******************************************************************************
3050 * Registers a client function that is to be called
3051 * whenever a high level object appears or disappears.
3053 * @param pClientFn,
3054 * A pointer to an MP_OBJECT_VISIBILITY_FN function defined by the
3055 * client. On successful return this function will be called to
3056 * inform the client of objects whose visibility has changed.
3058 * @param objectType
3059 * The type of object the client wishes to deregister for
3060 * property change callbacks. If null, then all objects types are
3061 * deregistered.
3063 * @param pCallerData
3064 * A pointer that is passed to the callback routine with each event.
3065 * This may be used by the caller to correlate the event to source of
3066 * the registration.
3068 * @return An MP_STATUS indicating if the operation was successful or if
3069 * an error occurred.
3071 * @retval MP_STATUS_SUCCESS
3072 * Returned when the operation is successful.
3074 * @retval MP_STATUS_INVALID_PARAMETER
3075 * Returned if pClientFn is NULL or specifies a memory area
3076 * that is not executable.
3078 * @retval MP_STATUS_FN_REPLACED
3079 * Returned when an existing client function is replaced with the one
3080 * specified in pClientFn.
3082 * @retval MP_STATUS_INVALID_OBJECT_TYPE
3083 * Returned if objectType does not specify any valid object type.
3085 *******************************************************************************
3087 MP_STATUS MP_RegisterForObjectVisibilityChanges(
3088 MP_OBJECT_VISIBILITY_FN pClientFn,
3089 MP_OBJECT_TYPE objectType,
3090 void *pCallerData,
3091 MP_OID pluginOid)
3093 MP_RegisterForObjectVisibilityChangesPluginFn PassFunc;
3094 MP_UINT32 i;
3095 MP_UINT32 index;
3096 MP_STATUS status;
3098 if (pClientFn == NULL) {
3099 return (MP_STATUS_INVALID_PARAMETER);
3102 if (objectType > MP_OBJECT_TYPE_MAX) {
3103 return (MP_STATUS_INVALID_OBJECT_TYPE);
3106 if (!(is_zero_oid(pluginOid))) {
3107 if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN,
3108 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
3109 return (status);
3113 (void) pthread_mutex_lock(&mp_lib_mutex);
3115 if (is_zero_oid(pluginOid)) {
3116 for (i = 0; i < number_of_plugins; i++) {
3117 if (plugintable[i].hdlPlugin != NULL) {
3118 PassFunc = (MP_RegisterForObjectVisibilityChangesPluginFn)
3119 dlsym(plugintable[i].hdlPlugin,
3120 "MP_RegisterForObjectVisibilityChangesPlugin");
3123 if (PassFunc != NULL) {
3124 status = PassFunc(pClientFn, objectType, pCallerData);
3125 /* ignore an error and continue. */
3128 } else {
3129 index = pluginOid.ownerId - 1;
3130 if (plugintable[index].hdlPlugin != NULL) {
3131 PassFunc = (MP_RegisterForObjectVisibilityChangesPluginFn)
3132 dlsym(plugintable[index].hdlPlugin,
3133 "MP_RegisterForObjectVisibilityChangesPlugin");
3136 if (PassFunc != NULL) {
3137 status = PassFunc(pClientFn, objectType, pCallerData);
3140 (void) pthread_mutex_unlock(&mp_lib_mutex);
3141 return (status);
3146 *******************************************************************************
3148 * Deregisters a previously registered client function that is to be invoked
3149 * whenever a high level object appears or disappears.
3151 * @param pClientFn,
3152 * A pointer to an MP_OBJECT_VISIBILITY_FN function defined by the
3153 * client that was previously registered using
3154 * the MP_RegisterForObjectVisibilityChanges API. On successful return
3155 * this function will no longer be called to inform the client of
3156 * object property changes.
3158 * @param objectType
3159 * The type of object the client wishes to deregister for visibility
3160 * change callbacks. If null, then all objects types are
3161 * deregistered.
3163 * @return An MP_STATUS indicating if the operation was successful or if
3164 * an error occurred.
3166 * @retval MP_STATUS_SUCCESS
3167 * Returned when the operation is successful.
3169 * @retval MP_STATUS_INVALID_PARAMETER
3170 * Returned if pClientFn is NULL or specifies a memory area
3171 * that is not executable.
3173 * @retval MP_STATUS_UNKNOWN_FN
3174 * Returned if pClientFn is not the same as the previously registered
3175 * function.
3177 * @retval MP_STATUS_INVALID_OBJECT_TYPE
3178 * Returned if objectType does not specify any valid object type.
3180 * @retval MP_STATUS_FAILED
3181 * Returned if pClientFn deregistration is not possible at this time.
3183 *******************************************************************************
3185 MP_STATUS MP_DeregisterForObjectVisibilityChanges(
3186 MP_OBJECT_VISIBILITY_FN pClientFn,
3187 MP_OBJECT_TYPE objectType,
3188 MP_OID pluginOid)
3190 MP_DeregisterForObjectVisibilityChangesPluginFn PassFunc;
3191 MP_UINT32 i;
3192 MP_UINT32 index;
3193 MP_STATUS status;
3195 if (pClientFn == NULL) {
3196 return (MP_STATUS_INVALID_PARAMETER);
3199 if (objectType > MP_OBJECT_TYPE_MAX) {
3200 return (MP_STATUS_INVALID_OBJECT_TYPE);
3203 if (!(is_zero_oid(pluginOid))) {
3204 if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN,
3205 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
3206 return (status);
3210 (void) pthread_mutex_lock(&mp_lib_mutex);
3212 if (is_zero_oid(pluginOid)) {
3213 for (i = 0; i < number_of_plugins; i++) {
3214 if (plugintable[i].hdlPlugin != NULL) {
3215 PassFunc = (MP_DeregisterForObjectVisibilityChangesPluginFn)
3216 dlsym(plugintable[i].hdlPlugin,
3217 "MP_DeregisterForObjectVisibilityChangesPlugin");
3218 if (PassFunc != NULL) {
3219 status = PassFunc(pClientFn, objectType);
3223 } else {
3224 index = pluginOid.ownerId - 1;
3225 if (plugintable[index].hdlPlugin != NULL) {
3226 PassFunc = (MP_DeregisterForObjectVisibilityChangesPluginFn)
3227 dlsym(plugintable[index].hdlPlugin,
3228 "MP_DeregisterForObjectVisibilityChangesPlugin");
3229 if (PassFunc != NULL) {
3230 status = PassFunc(pClientFn, objectType);
3235 (void) pthread_mutex_unlock(&mp_lib_mutex);
3236 return (status);
3240 *******************************************************************************
3242 * Compare two Oids for equality to see whether they refer to the same object.
3244 * @param oid1
3245 * Oid to compare.
3247 * @param oid2
3248 * Oid to compare.
3250 * @return An MP_STATUS indicating if the operation was successful or if
3251 * an error occurred.
3253 * @retval MP_STATUS_SUCCESS
3254 * Returned when the two Oids do refer to the same object.
3256 * @retval MP_STATUS_FAILED
3257 * Returned if the Oids don't compare.
3259 *******************************************************************************
3261 MP_STATUS MP_CompareOIDs(
3262 MP_OID oid1,
3263 MP_OID oid2)
3265 if ((oid1.objectType == oid2.objectType) && (oid1.ownerId == oid2.ownerId)
3266 && (oid1.objectSequenceNumber == oid2.objectSequenceNumber)) {
3267 return (MP_STATUS_SUCCESS);
3268 } else {
3269 return (MP_STATUS_FAILED);
3274 *******************************************************************************
3276 * Frees memory returned by an MP API.
3278 * @param pOidList
3279 * A pointer to the memory returned by an MP API. On successful
3280 return, the allocated memory is freed.
3282 * @return An MP_STATUS indicating if the operation was successful or if
3283 * an error occurred.
3285 * @retval MP_STATUS_SUCCESS
3286 * Returned when pPluginId is deregistered successfully.
3288 * @retval MP_STATUS_INVALID_PARAMETER
3289 * Returned if pMemory is NULL or specifies a memory area to which
3290 * data cannot be written.
3292 *******************************************************************************
3294 MP_STATUS MP_FreeOidList(MP_OID_LIST *pOidList)
3296 if (pOidList == NULL) {
3297 return (MP_STATUS_INVALID_PARAMETER);
3300 free(pOidList);
3302 return (MP_STATUS_SUCCESS);
3305 static MP_CHAR *HDR =
3306 "#\n"
3307 "# This file contains names and references to MP API plugin libraries\n"
3308 "#\n"
3309 "# Do NOT manually edit this file\n"
3310 "#\n"
3311 "# Format:\n"
3312 "#\n"
3313 "# <library ID> <library pathname>\n"
3314 "#\n";
3316 #define CLEANUP_N_RET(fd, ret) \
3317 if (lock_register(fd, F_SETLK, F_UNLCK, 0, SEEK_SET, 0) < 0) { \
3318 close(fd); \
3319 return (MP_STATUS_FAILED); \
3321 close(fd); \
3322 return (ret)
3325 * This function sets an advisory lock on the file pointed to by the argument
3326 * fd, which is a file descriptor. The lock is set using fcntl() which uses
3327 * flock structure.
3329 static int
3330 lock_register(int fd, int cmd, int type, off_t offset, int whence, off_t len)
3332 struct flock lock;
3334 lock.l_type = type;
3335 lock.l_start = offset;
3336 lock.l_whence = whence;
3337 lock.l_len = len;
3339 return (fcntl(fd, cmd, &lock));
3343 * This function searches for "srch_str" (of length "slen") in "buf" (of length
3344 * "buflen"). If it is not found, "write_offset" has the offset in "buf" where
3345 * "srch_str" would have to be added in "buf". If "srch_str" is found in "buf",
3346 * "write_offset" has its offset in "buf"
3348 * ARGUMENTS :
3349 * buf - buffer to search in
3350 * buflen - length of buffer
3351 * srch_id - id to search
3352 * id_len - length of srch_id
3353 * write_offset - Set in function on exit
3354 * - It is the offset in buf where srch_str is or should be
3355 * bytes_left - Set in function on exit
3356 * - It is the # of bytes left beyond write_offset in buf
3357 * RETURN VALUES :
3358 * Zero - "srch_id" found in "buf"... "write_offset" has offset in "buf"
3359 * != 0 - "srch_str" NOT found in "buf" ... "write_offset" points to the end of
3360 * "buf".
3362 static int
3363 search_line(MP_CHAR *buf, size_t buflen, MP_CHAR *srch_id, size_t id_len,
3364 int *write_offset, int *bytes_left)
3366 int retval, sizeof_conf_hdr = strlen(HDR);
3367 MP_CHAR *sol; /* Pointer to Start-Of-Line */
3368 MP_CHAR *cur_pos; /* current position */
3370 *bytes_left = buflen;
3371 *write_offset = 0;
3373 if (buf == NULL || buflen <= 0)
3374 return (-1);
3376 if (srch_id == NULL || id_len <= 0)
3377 return (0);
3379 sol = cur_pos = buf;
3382 * mp conf file should not be edited but takes care of
3383 * any extra white space when parsing the line.
3385 * The line should have id + delimiter + name + newline.
3387 while (*bytes_left >= (id_len + 3)) {
3388 /* skip leading blank or space. */
3389 while ((*cur_pos == ' ') || (*cur_pos == '\t')) {
3390 cur_pos++;
3393 if (strncmp(cur_pos, srch_id, id_len) == 0) {
3394 /* id matched. */
3395 cur_pos += id_len;
3397 while (*cur_pos != '\n') {
3398 cur_pos++;
3400 *write_offset = (sol - buf);
3401 *bytes_left = buflen - ((cur_pos + 1) - buf);
3402 return (0);
3403 } else {
3404 /* move to the next line */
3405 while (*cur_pos != '\n') {
3406 cur_pos++;
3408 *bytes_left = buflen - ((cur_pos + 1) - buf);
3410 sol = cur_pos = cur_pos + 1;
3413 /* Given strings are not found. */
3414 *write_offset = buflen;
3415 return (-1);
3419 *******************************************************************************
3421 * Registers a plugin with common library. The implementation of this routine
3422 * is based on configuration file /etc/mpapi.conf that contains a list of
3423 * plugin libraries.
3425 * @param pPluginId
3426 * A pointer to the key name shall be the reversed domain name of
3427 * the vendor followed by followed by the vendor specific name for
3428 * the plugin that uniquely identifies the plugin. Should be NULL
3429 * terminated.
3431 * @param pFileName
3432 * The full path to the plugin library.
3433 * Should be NULL terminated.
3435 * @return An MP_STATUS indicating if the operation was successful or if
3436 * an error occurred.
3438 * @retval MP_STATUS_SUCCESS
3439 * Returned when pPluginId is deregistered successfully.
3441 * @retval MP_STATUS_INVALID_PARAMETER
3442 * Returned if pPluginId is NULL or specifies a memory area that
3443 * is not executable.
3445 * @retval MP_STATUS_FAILED
3446 * Returned if pClientFn deregistration is not possible at this time.
3448 *******************************************************************************
3450 MP_STATUS MP_RegisterPlugin(
3451 MP_WCHAR *pPluginId,
3452 char *pFileName)
3454 int mpconf, bytes_left, write_offset;
3455 MP_CHAR fullline[MAX_LINE_SIZE]; /* Full line to add to mpapi.conf */
3456 MP_CHAR *mpconf_buf;
3457 MP_CHAR pluginid[MAX_NAME_SIZE];
3458 char systemPath[MAX_NAME_SIZE], mpConfFilePath[MAX_NAME_SIZE];
3459 MP_UINT32 new_file_flag = 0;
3460 MP_UINT32 sizeof_conf_hdr = strlen(HDR);
3461 struct stat stbuf;
3463 if ((pPluginId == NULL) || (pFileName == NULL)) {
3464 return (MP_STATUS_INVALID_PARAMETER);
3467 if (stat(pFileName, &stbuf) != 0) {
3468 return (MP_STATUS_INVALID_PARAMETER);
3471 if (wcstombs(pluginid, pPluginId, MAX_NAME_SIZE) != wcslen(pPluginId)) {
3472 return (MP_STATUS_INVALID_PARAMETER);
3475 *fullline = '\0';
3476 strncpy(fullline, pluginid, MAX_NAME_SIZE);
3477 /* add tab */
3478 strncat(fullline, "\t", MAX_LINE_SIZE - strlen(pluginid));
3479 strncat(fullline, pFileName, MAX_LINE_SIZE - strlen(pluginid) - 1);
3480 /* add a new line. */
3481 strncat(fullline, "\n",
3482 MAX_LINE_SIZE - strlen(pluginid) - strlen(pFileName) -1);
3484 /* Open configuration file from known location */
3485 strncpy(mpConfFilePath, "/etc/mpapi.conf", MAX_NAME_SIZE);
3487 if ((chmod(mpConfFilePath, S_IRUSR|S_IRGRP|S_IROTH) == -1) &&
3488 (errno == ENOENT)) {
3489 new_file_flag = 1;
3492 if ((mpconf = open(mpConfFilePath, O_RDWR | O_CREAT)) == -1) {
3493 return (MP_STATUS_FAILED);
3496 if (fchmod(mpconf, S_IRUSR | S_IRGRP | S_IROTH) < 0) {
3497 close(mpconf);
3498 return (MP_STATUS_FAILED);
3501 if (lock_register(mpconf, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0) < 0) {
3502 close(mpconf);
3503 return (MP_STATUS_FAILED);
3506 if (fstat(mpconf, &stbuf) == -1) {
3507 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3510 if ((new_file_flag) || (stbuf.st_size == 0)) {
3511 if (write(mpconf, HDR, sizeof_conf_hdr) !=
3512 sizeof_conf_hdr) {
3513 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3516 if (pwrite(mpconf, fullline, strlen(fullline),
3517 sizeof_conf_hdr) !=
3518 strlen(fullline)) {
3519 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3521 CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS);
3524 if ((mpconf_buf = (MP_CHAR *)mmap(0, stbuf.st_size,
3525 PROT_READ | PROT_WRITE,
3526 MAP_SHARED, mpconf, 0)) == MAP_FAILED) {
3527 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3530 if (search_line(mpconf_buf, stbuf.st_size,
3531 pluginid, strlen(pluginid), &write_offset, &bytes_left) == 0) {
3532 /* found a match. */
3533 munmap((void *)mpconf_buf, stbuf.st_size);
3534 CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS);
3535 } else {
3536 munmap((void *)mpconf_buf, stbuf.st_size);
3537 /* append the fullline to the mpconf. */
3538 if (pwrite(mpconf, fullline, strlen(fullline),
3539 write_offset) !=
3540 strlen(fullline)) {
3541 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3542 } else {
3543 CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS);
3549 *******************************************************************************
3551 * Deregisters a plugin from the common library. This routine is based on
3552 * configuration file /etc/mpapi.conf that contains a list of plugin libraries.
3554 * @param pPluginId
3555 * A pointer to a Plugin ID previously registered using
3556 * the MP_RegisterPlugin API..
3558 * @return An MP_STATUS indicating if the operation was successful or if
3559 * an error occurred.
3561 * @retval MP_STATUS_SUCCESS
3562 * Returned when pPluginId is deregistered successfully.
3564 * @retval MP_STATUS_INVALID_PARAMETER
3565 * Returned if pPluginId is NULL or specifies a memory area that
3566 * is not executable.
3568 * @retval MP_STATUS_FAILED
3569 * Returned if pClientFn deregistration is not possible at this time.
3571 *******************************************************************************
3573 MP_STATUS MP_DeregisterPlugin(
3574 MP_WCHAR *pPluginId)
3576 int mpconf, tmp_mpconf, bytes_left, write_offset;
3577 char systemPath[MAX_NAME_SIZE], mpConfFilePath[MAX_NAME_SIZE],
3578 tmp_mpConfFilePath[MAX_NAME_SIZE + sizeof(pid_t)];
3579 MP_CHAR pluginid[MAX_NAME_SIZE];
3580 MP_CHAR *mpconf_buf;
3581 MP_UINT32 sizeof_conf_hdr = strlen(HDR);
3582 struct stat stbuf;
3584 if (pPluginId == NULL) {
3585 return (MP_STATUS_INVALID_PARAMETER);
3588 if (wcstombs(pluginid, pPluginId, MAX_NAME_SIZE) != wcslen(pPluginId)) {
3589 return (MP_STATUS_INVALID_PARAMETER);
3592 /* Open configuration file from known location */
3593 strncpy(mpConfFilePath, "/etc/mpapi.conf", MAX_NAME_SIZE);
3595 if ((chmod(mpConfFilePath, S_IRUSR|S_IRGRP|S_IROTH) == -1) &&
3596 (errno == ENOENT)) {
3597 /* no file found */
3598 return (MP_STATUS_UNKNOWN_FN);
3601 if ((mpconf = open(mpConfFilePath, O_RDWR)) == -1) {
3602 return (MP_STATUS_FAILED);
3605 if (fchmod(mpconf, S_IRUSR | S_IRGRP | S_IROTH) < 0) {
3606 close(mpconf);
3607 return (MP_STATUS_FAILED);
3610 if (lock_register(mpconf, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0) < 0) {
3611 close(mpconf);
3612 return (MP_STATUS_FAILED);
3615 if (fstat(mpconf, &stbuf) == -1) {
3616 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3619 if (stbuf.st_size == 0) {
3620 CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS);
3623 if ((mpconf_buf = (MP_CHAR *)mmap(0, stbuf.st_size,
3624 PROT_READ | PROT_WRITE,
3625 MAP_SHARED, mpconf, 0)) == MAP_FAILED) {
3626 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3629 if (search_line(mpconf_buf, stbuf.st_size, pluginid, strlen(pluginid),
3630 &write_offset, &bytes_left) != 0) {
3631 munmap((void *)mpconf_buf, stbuf.st_size);
3632 CLEANUP_N_RET(mpconf, MP_STATUS_UNKNOWN_FN);
3633 } else {
3635 * found a match.
3636 * construct temp file name using pid.
3638 (void) snprintf(tmp_mpConfFilePath, MAX_NAME_SIZE,
3639 "%s%ld", "/etc/mpapi.conf", getpid());
3641 if ((tmp_mpconf = open(tmp_mpConfFilePath,
3642 O_RDWR|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR)) < 0) {
3643 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3646 if (write(tmp_mpconf, mpconf_buf, write_offset) != write_offset) {
3647 close(tmp_mpconf);
3648 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3651 if (pwrite(tmp_mpconf, mpconf_buf + (stbuf.st_size - bytes_left),
3652 bytes_left, write_offset) != bytes_left) {
3653 close(tmp_mpconf);
3654 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3657 close(tmp_mpconf);
3658 munmap((void *)mpconf_buf, stbuf.st_size);
3660 /* rename temp file to mpConfFile before unlock and close. */
3661 if (rename(tmp_mpConfFilePath, mpConfFilePath) != 0) {
3662 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3663 } else {
3664 CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS);