1 /******************************************************************************
2 *
3 * Description
4 * mpapi.c - Implements Multipath Management API Version 1.0
5 *
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
10 *
11 * http://mp-mgmt-api.sourceforge.net
12 *
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.
17 *
18 * The Original Code is SNIA iSCSI Management API and Multipath Management
19 * API header files.
20 *
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)
26 *
27 * Contributor(s):
28 * Paul von Behren Sun Microsystems(paul.vonbehren@sun.com)
29 *
30 ******************************************************************************
31 *
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 ******************************************************************************
55 */
56
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"
72
73 #define LIBRARY_SUPPORTED_MP_VERSION 1
74 #define LIBRARY_IMPLEMENTATION_VERSION L"1.0.0"
75 #define LIBRARY_VENDOR L"Sun Microsystems Inc."
76
77 #define LIBRARY_FILE_NAME "libMPAPI.so"
78
79
80 MPPLUGININFO_T plugintable[MP_MAX_NUM_PLUGINS];
81 pthread_mutex_t mp_lib_mutex = PTHREAD_MUTEX_INITIALIZER;
82
83 static int number_of_plugins = -1;
84
85
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);
93
94 /**
95 ******************************************************************************
96 *
97 * Validate the oid.
98 *
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.
108 *
109 ******************************************************************************
110 */
validate_object(MP_OID obj,MP_OBJECT_TYPE objType,MP_UINT32 flag)111 MP_STATUS validate_object(MP_OID obj, MP_OBJECT_TYPE objType,
112 MP_UINT32 flag)
113 {
114
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);
123 }
124 }
125
126 if (flag == MP_OBJECT_TYPE_MATCH) {
127 if (obj.objectType != objType) {
128 return (MP_STATUS_INVALID_PARAMETER);
129 }
130 }
131 return (MP_STATUS_SUCCESS);
132 }
133
134 /**
135 ******************************************************************************
136 *
137 * Check if an oid is ZERO_OID or not.
138 *
139 * - Return 1 if the input OID is ZERO_OID
140 *
141 * - Return 0 if not.
142 *
143 ******************************************************************************
144 */
is_zero_oid(MP_OID oid)145 static int is_zero_oid(MP_OID oid)
146 {
147
148 if ((oid.objectType != MP_OBJECT_TYPE_UNKNOWN) || (oid.ownerId != 0) ||
149 (oid.objectSequenceNumber != 0)) {
150 return (0);
151 }
152
153 return (1);
154 }
155
156 /**
157 ******************************************************************************
158 *
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.
162 *
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.
166 *
167 ******************************************************************************
168 */
InitLibrary()169 void InitLibrary()
170 {
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;
180
181 MP_UINT32 i = 0; /* index for plugin table */
182
183 if(number_of_plugins != -1) {
184 return;
185 }
186
187 (void) pthread_mutex_lock(&mp_lib_mutex);
188
189 number_of_plugins = 0;
190
191 /* Open configuration file from known location */
192 strncpy(mpConfFilePath, "/etc/mpapi.conf", MAX_NAME_SIZE);
193
194 if ((fd_mpconf = open(mpConfFilePath, O_RDONLY)) < 0) {
195 (void) pthread_mutex_unlock(&mp_lib_mutex);
196 return;
197 }
198
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;
203 }
204
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;
210 }
211
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';
219
220 charPtr = fullline;
221 /* remove leading blank or taps. */
222 while ((fullline[0] == L' ') || (fullline[0] == L'\t'))
223 charPtr++;
224
225 sol = charPtr;
226
227 /*
228 * look for first tab or space.
229 */
230 if ((charPtr = wcschr(fullline, L'\t')) == NULL)
231 charPtr = wcschr(fullline, L' ');
232
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 */
242 }
243
244 /* Copy library name and path */
245 wcstombs(path, charPtr, MAX_NAME_SIZE);
246
247 /*
248 * Continue to the next line if library name or path is
249 * invalid
250 */
251 if ((wcslen(name) == 0) ||
252 (strlen(path) == 0))
253 continue;
254
255 /* Load the plugin now */
256 if (stat(path, &stat_buf) != -1) {
257 plugintable[i].hdlPlugin = dlopen(path, RTLD_LAZY);
258 } else {
259 continue;
260 }
261
262 if (plugintable[i].hdlPlugin != NULL) {
263 InitializeFn PassFunc;
264 MP_STATUS status;
265
266 wcsncpy(plugintable[i].pluginName,
267 name, MAX_NAME_SIZE);
268 strncpy(plugintable[i].pluginPath,
269 path, MAX_NAME_SIZE);
270
271 plugintable[i].ownerId = i + 1;
272
273 PassFunc = (InitializeFn)
274 dlsym(plugintable[i].hdlPlugin, "Initialize");
275 if (PassFunc != NULL) {
276 status = PassFunc(plugintable[i].ownerId);
277 }
278
279 i++;
280 }
281 }
282 }
283
284 if (lock_register(fd_mpconf, F_SETLK, F_UNLCK, 0, SEEK_SET, 0) < 0) {
285 fclose(mpconf);
286 close(fd_mpconf);
287 (void) pthread_mutex_unlock(&mp_lib_mutex);
288 return;
289 }
290 fclose(mpconf);
291 close(fd_mpconf);
292
293 number_of_plugins = i;
294 (void) pthread_mutex_unlock(&mp_lib_mutex);
295 }
296
297 /**
298 ******************************************************************************
299 *
300 * Exit by calling Terminate routine of plugin libraries.
301 *
302 * Note: The build of libMPAPI.so should include a linker option to make this
303 * routine executed when it is unloaded.
304 *
305 ******************************************************************************
306 */
ExitLibrary()307 void ExitLibrary()
308 {
309 MP_UINT32 i, j;
310
311 if(number_of_plugins == -1)
312 return;
313
314 (void) pthread_mutex_lock(&mp_lib_mutex);
315 for (i = 0; i < number_of_plugins; i++) {
316 if (plugintable[i].hdlPlugin != NULL) {
317 TerminateFn ExitPassFunc;
318
319 ExitPassFunc = (TerminateFn)
320 dlsym(plugintable[i].hdlPlugin, "Terminate");
321
322 if (ExitPassFunc != NULL) {
323 ExitPassFunc();
324 }
325
326 /* Unload plugin from memory */
327 dlclose(plugintable[i].hdlPlugin);
328 }
329 }
330
331 number_of_plugins = -1;
332
333 (void) pthread_mutex_unlock(&mp_lib_mutex);
334 (void) pthread_mutex_destroy(&mp_lib_mutex);
335 }
336
337 /**
338 ******************************************************************************
339 *
340 * Gets the properties of the MP API library that is being used.
341 *
342 * @param pProps
343 * A pointer to an @ref MP_LIBRARY_PROPERTIES structure allocated by
344 * the caller. On successful return this structure will contain the
345 * properties of the MP library.
346 *
347 * @return An MP_STATUS indicating if the operation was successful or
348 * if an error occurred.
349 *
350 * @retval MP_STATUS_SUCCESS
351 * Returned if the library properties were successfully returned.
352 *
353 * @retval MP_STATUS_INVALID_PARAMETER Returned if @a pProps is NULL or
354 * specifies a memory area to which data cannot be written.
355 *
356 ******************************************************************************
357 */
MP_GetLibraryProperties(MP_LIBRARY_PROPERTIES * pProps)358 MP_STATUS MP_GetLibraryProperties(
359 MP_LIBRARY_PROPERTIES *pProps)
360 {
361 char mpPath[MAX_NAME_SIZE];
362
363 if(pProps == NULL) {
364 return MP_STATUS_INVALID_PARAMETER;
365 }
366
367 /* Fill in properties */
368 if (mbstowcs(pProps->buildTime, BUILD_TIME, 256) !=
369 strlen(BUILD_TIME)) {
370 return (MP_STATUS_INVALID_PARAMETER);
371 }
372 pProps->supportedMpVersion = LIBRARY_SUPPORTED_MP_VERSION;
373
374 wcsncpy(pProps->implementationVersion,
375 LIBRARY_IMPLEMENTATION_VERSION, MAX_NAME_SIZE);
376 wcsncpy(pProps->vendor, LIBRARY_VENDOR, MAX_NAME_SIZE);
377
378 snprintf(pProps->fileName, MAX_NAME_SIZE, "%s",
379 LIBRARY_FILE_NAME);
380
381 return MP_STATUS_SUCCESS;
382 }
383
384
385 /**
386 ******************************************************************************
387 *
388 * Gets a list of the object IDs of all currently loaded plugins.
389 *
390 * @param ppList A pointer to a pointer to an @ref MP_OID_LIST. On successful
391 * return this will contain a pointer to an @ref MP_OID_LIST
392 * which contains the object IDs of all of the plugins currently loaded
393 * by the library.
394 * @return An MP_STATUS indicating if the operation was successful or if
395 * an error
396 * occurred.
397 * @retval MP_SUCCESS Returned if the plugin ID list was successfully returned.
398 * @retval MP_STATUS_INVALID_PARAMETER Returned if @a ppList is NULL or
399 * specifies a memory area to which data cannot be written.
400 *
401 ******************************************************************************
402 */
MP_GetPluginOidList(MP_OID_LIST ** ppList)403 MP_STATUS MP_GetPluginOidList(
404 MP_OID_LIST **ppList)
405 {
406 MP_UINT32 i;
407
408 if (ppList == NULL)
409 return (MP_STATUS_INVALID_PARAMETER);
410
411 (void) pthread_mutex_lock(&mp_lib_mutex);
412
413 if (number_of_plugins == 0) {
414 *ppList = (MP_OID_LIST*)calloc(1, sizeof(MP_OID_LIST));
415 } else {
416 *ppList = (MP_OID_LIST*)calloc(1,
417 sizeof(MP_OID_LIST) + (number_of_plugins - 1)* sizeof(MP_OID) );
418 }
419
420 if ((*ppList) == NULL) {
421 (void) pthread_mutex_unlock(&mp_lib_mutex);
422 return (MP_STATUS_INSUFFICIENT_MEMORY);
423 }
424
425 (*ppList)->oidCount = number_of_plugins;
426
427 if (number_of_plugins != 0) {
428 for (i = 0; i < number_of_plugins; i++) {
429 (*ppList)->oids[i].objectType = MP_OBJECT_TYPE_PLUGIN;
430 (*ppList)->oids[i].ownerId = plugintable[i].ownerId;
431 (*ppList)->oids[i].objectSequenceNumber = 0;
432 }
433 }
434
435 (void) pthread_mutex_unlock(&mp_lib_mutex);
436 return MP_STATUS_SUCCESS;
437 }
438
439 /**
440 *******************************************************************************
441 *
442 * Gets the properties of the specified vendor plugin.
443 *
444 * @param oid
445 * The ID of the plugin whose properties are being retrieved.
446 *
447 * @param pProps
448 * A pointer to an @ref MP_PLUGIN_PROPERTIES structure allocated by
449 * the caller. On successful return this will contain the properties
450 * of the plugin specified by pluginOid.
451 *
452 * @return An MP_STATUS indicating if the operation was successful or if an
453 * error occurred.
454 *
455 * @retval MP_STATUS_SUCCESS
456 * Returned if the plugin properties were successfully returned.
457 *
458 * @retval MP_STATUS_INVALID_OBJECT_TYPE
459 * Returned if oid does not specify any valid object type.
460 *
461 * @retval MP_STATUS_OBJECT_NOT_FOUND
462 * Returned if oid has an owner that is not currently known to
463 * the system.
464 *
465 * @retval MP_STATUS_INVALID_PARAMETER
466 * Returned if 'pProps' is NULL or specifies a memory area to
467 * which data cannot be written.
468 *
469 *******************************************************************************
470 */
MP_GetPluginProperties(MP_OID pluginOid,MP_PLUGIN_PROPERTIES * pProps)471 MP_STATUS MP_GetPluginProperties(
472 MP_OID pluginOid,
473 MP_PLUGIN_PROPERTIES *pProps)
474 {
475 MP_GetPluginPropertiesPluginFn PassFunc;
476 MP_UINT32 index;
477 MP_STATUS status;
478
479 if(pProps == NULL)
480 return (MP_STATUS_INVALID_PARAMETER);
481
482 if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN,
483 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
484 return (status);
485 }
486
487 (void) pthread_mutex_lock(&mp_lib_mutex);
488
489 index = pluginOid.ownerId - 1;
490 if (plugintable[index].hdlPlugin != NULL) {
491 PassFunc = (MP_GetPluginPropertiesPluginFn)
492 dlsym(plugintable[index].hdlPlugin, "MP_GetPluginPropertiesPlugin");
493
494 if (PassFunc != NULL) {
495 status = PassFunc(pProps);
496 } else {
497 status = MP_STATUS_UNSUPPORTED;
498 }
499 } else {
500 status = MP_STATUS_FAILED;
501 }
502
503 (void) pthread_mutex_unlock(&mp_lib_mutex);
504 return status;
505 }
506
507 /**
508 *******************************************************************************
509 *
510 * Gets the object ID for the plugin associated with the specified object ID.
511 *
512 * @param oid
513 * The object ID of an object that has been received from a previous
514 * library call.
515 *
516 * @param pPluginOid
517 * A pointer to an MP_OID structure allocated by the caller. On
518 * successful return this will contain the object ID of the plugin
519 * associated with the object specified by @a objectId.
520 *
521 * @return An MP_STATUS indicating if the operation was successful or if
522 * an error occurred.
523 *
524 * @retval MP_STATUS_SUCCESS
525 * Returned if the associated plugin ID was successfully returned.
526 *
527 * @retval MP_STATUS_OBJECT_NOT_FOUND
528 * Returned if oid does not specify a plugin that is currently known to
529 * the system.
530 *
531 * @retval MP_STATUS_INVALID_PARAMETER
532 * Returned if 'oid' specifies an object not owned by a plugin or
533 * if pPluginOid is NULL or specifies a memory area to which data
534 * cannot be written.
535 *
536 * @retval MP_STATUS_INVALID_OBJECT_TYPE
537 * Returned if 'oid' specifies an object with an invalid type.
538 *
539 *******************************************************************************
540 */
MP_GetAssociatedPluginOid(MP_OID objectId,MP_OID * pPluginId)541 MP_STATUS MP_GetAssociatedPluginOid(
542 MP_OID objectId,
543 MP_OID *pPluginId)
544 {
545 MP_UINT32 i;
546 MP_STATUS status;
547
548 if (pPluginId == NULL)
549 return (MP_STATUS_INVALID_PARAMETER);
550
551 if ((status = validate_object(objectId, 0, MP_OBJECT_TYPE_ANY)) !=
552 MP_STATUS_SUCCESS) {
553 return (status);
554 }
555
556 pPluginId->objectType = MP_OBJECT_TYPE_PLUGIN;
557 pPluginId->ownerId = objectId.ownerId;
558 pPluginId->objectSequenceNumber = 0;
559
560 return (MP_STATUS_SUCCESS);
561 }
562
563 /**
564 *******************************************************************************
565 *
566 * Gets the object type of an initialized object ID.
567 *
568 * @param oid
569 * The object ID of an object that has been received from a previous
570 * library call.
571 *
572 * @param pObjectType
573 * A pointer to an MP_OBJECT_TYPE variable allocated by the caller.
574 * On successful return this will contain the object type of oid.
575 *
576 * @return An MP_STATUS indicating if the operation was successful or
577 * if an error occurred.
578 *
579 * @retval MP_STATUS_OBJECT_NOT_FOUND
580 * Returned if oid has an owner that is not currently known to
581 * the system.
582 *
583 * @retval MP_STATUS_INVALID_PARAMETER
584 * Returned if oid does not specify any valid object type.
585 *
586 * @retval MP_STATUS_SUCCESS
587 * Returned when the operation is successful.
588 *
589 *******************************************************************************
590 */
MP_GetObjectType(MP_OID oid,MP_OBJECT_TYPE * pObjectType)591 MP_STATUS MP_GetObjectType(
592 MP_OID oid,
593 MP_OBJECT_TYPE *pObjectType)
594 {
595 MP_STATUS status;
596
597 if (pObjectType == NULL)
598 return MP_STATUS_INVALID_PARAMETER;
599
600 if ((status = validate_object(oid, 0, MP_OBJECT_TYPE_ANY))
601 != MP_STATUS_SUCCESS) {
602 return (status);
603 }
604
605 *pObjectType = oid.objectType;
606 return MP_STATUS_SUCCESS;
607 }
608
609 /**
610 *******************************************************************************
611 *
612 * Gets a list of the object IDs of all the device product properties
613 * associated with this plugin.
614 *
615 * @param oid
616 * The object ID of plugin.
617 *
618 * @param ppList
619 * A pointer to a pointer to an MP_OID_LIST structure.
620 * On a successful return, this will contain a pointer to
621 * an MP_OID_LIST that contains the object IDs of all the device
622 * product descriptors associated with the specified plugin.
623 *
624 * @return An MP_STATUS indicating if the operation was successful or if
625 * an error occurred.
626 *
627 * @retval MP_STATUS_SUCCESS
628 * Returned when the operation is successful.
629 *
630 * @retval MP_STATUS_INVALID_PARAMETER
631 * Returned if ppList pointer passed as placeholder for holding
632 * the device product list is found to be invalid.
633 *
634 * @retval MP_STATUS_INVALID_OBJECT_TYPE
635 * Returned if oid does not specify any valid object type.
636 *
637 * @retval MP_STATUS_FAILED
638 * Returned when the plugin for the specified oid is not found.
639 *
640 * @retval MP_STATUS_INSUFFICIENT_MEMORY
641 * Returned when memory allocation failure occurs
642 *
643 * @retval MP_STATUS_UNSUPPORTED
644 * Returned when the API is not supported.
645 *
646 *******************************************************************************
647 */
MP_GetDeviceProductOidList(MP_OID oid,MP_OID_LIST ** ppList)648 MP_STATUS MP_GetDeviceProductOidList(
649 MP_OID oid,
650 MP_OID_LIST **ppList)
651 {
652 MP_GetDeviceProductOidListPluginFn PassFunc;
653 MP_UINT32 index;
654 MP_STATUS status;
655
656 if (ppList == NULL)
657 return MP_STATUS_INVALID_PARAMETER;
658
659 if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
660 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
661 return (status);
662 }
663
664 (void) pthread_mutex_lock(&mp_lib_mutex);
665
666 index = oid.ownerId - 1;
667 if (plugintable[index].hdlPlugin != NULL) {
668 PassFunc = (MP_GetDeviceProductOidListPluginFn)
669 dlsym(plugintable[index].hdlPlugin,
670 "MP_GetDeviceProductOidListPlugin");
671 if (PassFunc != NULL) {
672 status = PassFunc(ppList);
673 } else {
674 status = MP_STATUS_UNSUPPORTED;
675 }
676 } else {
677 status = MP_STATUS_FAILED;
678 }
679
680 (void) pthread_mutex_unlock(&mp_lib_mutex);
681 return status;
682 }
683
684 /**
685 *******************************************************************************
686 *
687 * Gets the device product properties of the specified plugin oid.
688 *
689 * @param oid
690 * The object ID of the plugin.
691 *
692 * @param ppProps
693 * A pointer to a pointer to an MP_DEVICE_PRODUCT_PROPERTIES structure
694 * allocated by the caller. On successful return it will contain
695 * a pointer to an MP_DEVICE_PRODUCT_PROPERTIES structure allocated
696 * by the library.
697 *
698 * @return An MP_STATUS indicating if the operation was successful or if
699 * an error occurred.
700 *
701 * @retval MP_STATUS_SUCCESS
702 * Returned when the operation is successful.
703 *
704 * @retval MP_STATUS_INVALID_PARAMETER
705 * Returned if ppProps pointer passed as placeholder for holding
706 * the device product properties is found to be invalid.
707 *
708 * @retval MP_STATUS_INVALID_OBJECT_TYPE
709 * Returned if oid does not specify any valid object type.
710 *
711 * @retval MP_STATUS_FAILED
712 * Returned when the plugin for the specified oid is not found.
713 *
714 * @retval MP_STATUS_INSUFFICIENT_MEMORY
715 * Returned when memory allocation failure occurs
716 *
717 * @retval MP_STATUS_UNSUPPORTED
718 * Returned when the API is not supported.
719 *
720 *******************************************************************************
721 */
MP_GetDeviceProductProperties(MP_OID oid,MP_DEVICE_PRODUCT_PROPERTIES * pProps)722 MP_STATUS MP_GetDeviceProductProperties(
723 MP_OID oid,
724 MP_DEVICE_PRODUCT_PROPERTIES *pProps)
725 {
726 MP_GetDeviceProductPropertiesFn PassFunc;
727 MP_UINT32 index;
728 MP_STATUS status;
729
730 if (pProps == NULL)
731 return MP_STATUS_INVALID_PARAMETER;
732
733 if ((status = validate_object(oid, MP_OBJECT_TYPE_DEVICE_PRODUCT,
734 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
735 return (status);
736 }
737
738 (void) pthread_mutex_lock(&mp_lib_mutex);
739
740 index = oid.ownerId - 1;
741 if (plugintable[index].hdlPlugin != NULL) {
742 PassFunc = (MP_GetDeviceProductPropertiesFn)
743 dlsym(plugintable[index].hdlPlugin,
744 "MP_GetDeviceProductProperties");
745
746 if (PassFunc != NULL) {
747 status = PassFunc(oid, pProps);
748 } else {
749 status = MP_STATUS_UNSUPPORTED;
750 }
751 } else {
752 status = MP_STATUS_FAILED;
753 }
754
755 (void) pthread_mutex_unlock(&mp_lib_mutex);
756 return status;
757 }
758
759 /**
760 *******************************************************************************
761 *
762 * Gets a list of the object IDs of all the initiator ports associated
763 * with this plugin.
764 *
765 * @param oid
766 * The object ID of plugin.
767 *
768 * @param ppList
769 * A pointer to a pointer to an MP_OID_LIST structure.
770 * On a successful return, this will contain a pointer to
771 * an MP_OID_LIST that contains the object IDs of all the initiator
772 * ports associated with the specified plugin.
773 *
774 * @return An MP_STATUS indicating if the operation was successful or if
775 * an error occurred.
776 *
777 * @retval MP_STATUS_SUCCESS
778 * Returned when the operation is successful.
779 *
780 * @retval MP_STATUS_INVALID_PARAMETER
781 * Returned if ppList pointer passed as placeholder for holding
782 * the initiator port list is found to be invalid.
783 *
784 * @retval MP_STATUS_INVALID_OBJECT_TYPE
785 * Returned if oid does not specify any valid object type.
786 *
787 * @retval MP_STATUS_FAILED
788 * Returned when the plugin for the specified oid is not found.
789 *
790 * @retval MP_STATUS_INSUFFICIENT_MEMORY
791 * Returned when memory allocation failure occurs
792 *
793 * @retval MP_STATUS_UNSUPPORTED
794 * Returned when the API is not supported.
795 *
796 *******************************************************************************
797 */
MP_GetInitiatorPortOidList(MP_OID oid,MP_OID_LIST ** ppList)798 MP_STATUS MP_GetInitiatorPortOidList(
799 MP_OID oid,
800 MP_OID_LIST **ppList)
801 {
802 MP_GetInitiatorPortOidListPluginFn PassFunc;
803 MP_UINT32 index;
804 MP_STATUS status;
805
806 if (ppList == NULL)
807 return MP_STATUS_INVALID_PARAMETER;
808
809 if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
810 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
811 return (status);
812 }
813
814 (void) pthread_mutex_lock(&mp_lib_mutex);
815
816 index = oid.ownerId - 1;
817 if (plugintable[index].hdlPlugin != NULL) {
818 PassFunc = (MP_GetDeviceProductOidListPluginFn)
819 dlsym(plugintable[index].hdlPlugin, "MP_GetInitiatorPortOidListPlugin");
820
821 if (PassFunc != NULL) {
822 status = PassFunc(ppList);
823 } else {
824 status = MP_STATUS_UNSUPPORTED;
825 }
826 } else {
827 status = MP_STATUS_FAILED;
828 }
829
830 (void) pthread_mutex_unlock(&mp_lib_mutex);
831 return (status);
832 }
833
834 /**
835 *******************************************************************************
836 *
837 * Gets the properties of the specified initiator port.
838 *
839 * @param oid
840 * The object ID of the initiator port.
841 *
842 * @param pProps
843 * A pointer to an MP_INITIATOR_PORT_PROPERTIES structure
844 * allocated by the caller. On successful return, this structure
845 * will contain the properties of the port specified by oid.
846 *
847 * @return An MP_STATUS indicating if the operation was successful or if
848 * an error occurred.
849 *
850 * @retval MP_STATUS_SUCCESS
851 * Returned when the operation is successful.
852 *
853 * @retval MP_STATUS_INVALID_PARAMETER
854 * Returned if pProps is NULL or specifies a memory area to
855 * which data cannot be written.
856 *
857 * @retval MP_STATUS_INVALID_OBJECT_TYPE
858 * Returned if oid does not specify any valid object type.
859 *
860 * @retval MP_STATUS_OBJECT_NOT_FOUND
861 * Returned if oid has an owner that is not currently known to
862 * the system.
863 *
864 *******************************************************************************
865 */
MP_GetInitiatorPortProperties(MP_OID oid,MP_INITIATOR_PORT_PROPERTIES * pProps)866 MP_STATUS MP_GetInitiatorPortProperties(
867 MP_OID oid,
868 MP_INITIATOR_PORT_PROPERTIES *pProps)
869 {
870 MP_GetInitiatorPortPropertiesFn PassFunc;
871 MP_UINT32 index;
872 MP_STATUS status;
873
874 if (pProps == NULL)
875 return MP_STATUS_INVALID_PARAMETER;
876
877 if ((status = validate_object(oid, MP_OBJECT_TYPE_INITIATOR_PORT,
878 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
879 return (status);
880 }
881
882 (void) pthread_mutex_lock(&mp_lib_mutex);
883
884 index = oid.ownerId - 1;
885 if (plugintable[index].hdlPlugin != NULL) {
886 PassFunc = (MP_GetInitiatorPortPropertiesFn)
887 dlsym(plugintable[index].hdlPlugin,
888 "MP_GetInitiatorPortProperties");
889
890 if (PassFunc != NULL) {
891 status = PassFunc(oid, pProps);
892 } else {
893 status = MP_STATUS_UNSUPPORTED;
894 }
895 } else {
896 status = MP_STATUS_FAILED;
897 }
898
899 (void) pthread_mutex_unlock(&mp_lib_mutex);
900 return status;
901 }
902
903 /**
904 *******************************************************************************
905 *
906 * Gets a list of multipath logical units associated to a plugin.
907 *
908 * @param oid
909 * The object ID of plugin.
910 *
911 * @param ppList
912 * A pointer to a pointer to an MP_OID_LIST structure.
913 * On a successful return, this will contain a pointer to
914 * an MP_OID_LIST that contains the object IDs of all the multipath
915 * logical units associated with the specified plugin.
916 *
917 * @return An MP_STATUS indicating if the operation was successful or if
918 * an error occurred.
919 *
920 * @retval MP_STATUS_SUCCESS
921 * Returned when the operation is successful.
922 *
923 * @retval MP_STATUS_INVALID_PARAMETER
924 * Returned if ppList pointer passed as placeholder for holding
925 * the multipath logical unit list is found to be invalid.
926 *
927 * @retval MP_STATUS_INVALID_OBJECT_TYPE
928 * Returned if oid does not specify any valid object type.
929 *
930 * @retval MP_STATUS_FAILED
931 * Returned when the plugin for the specified oid is not found.
932 *
933 * @retval MP_STATUS_INSUFFICIENT_MEMORY
934 * Returned when memory allocation failure occurs
935 *
936 * @retval MP_STATUS_UNSUPPORTED
937 * Returned when the API is not supported.
938 *
939 *******************************************************************************
940 */
MP_GetMultipathLus(MP_OID oid,MP_OID_LIST ** ppList)941 MP_STATUS MP_GetMultipathLus(
942 MP_OID oid,
943 MP_OID_LIST **ppList)
944 {
945 MP_UINT32 index;
946 MP_STATUS status;
947
948 if (ppList == NULL)
949 return MP_STATUS_INVALID_PARAMETER;
950
951 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
952 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
953 ((status = validate_object(oid, MP_OBJECT_TYPE_DEVICE_PRODUCT,
954 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
955 return (status);
956 }
957
958 (void) pthread_mutex_lock(&mp_lib_mutex);
959
960 index = oid.ownerId - 1;
961 if (plugintable[index].hdlPlugin != NULL) {
962 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
963 MP_GetMultipathLusPluginFn PassFunc;
964 PassFunc = (MP_GetMultipathLusPluginFn)
965 dlsym(plugintable[index].hdlPlugin,
966 "MP_GetMultipathLusPlugin");
967
968 if (PassFunc != NULL) {
969 status = PassFunc(ppList);
970 } else {
971 status = MP_STATUS_UNSUPPORTED;
972 }
973 } else if (oid.objectType == MP_OBJECT_TYPE_DEVICE_PRODUCT) {
974 MP_GetMultipathLusDevProdFn PassFunc;
975 PassFunc = (MP_GetMultipathLusDevProdFn)
976 dlsym(plugintable[index].hdlPlugin,
977 "MP_GetMultipathLusDevProd");
978
979 if (PassFunc != NULL) {
980 status = PassFunc(oid, ppList);
981 } else {
982 status = MP_STATUS_UNSUPPORTED;
983 }
984 } else {
985 status = MP_STATUS_INVALID_PARAMETER;
986 }
987 }
988
989 (void) pthread_mutex_unlock(&mp_lib_mutex);
990 return (status);
991 }
992
993
994 /**
995 *******************************************************************************
996 *
997 * Gets the properties of the specified logical unit.
998 *
999 * @param oid
1000 * The object ID of the multipath logical unit.
1001 *
1002 * @param pProps
1003 * A pointer to an MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES structure
1004 * allocated by the caller. On successful return, this structure
1005 * will contain the properties of the port specified by oid.
1006 *
1007 * @return An MP_STATUS indicating if the operation was successful or if
1008 * an error occurred.
1009 *
1010 * @retval MP_STATUS_SUCCESS
1011 * Returned when the operation is successful.
1012 *
1013 * @retval MP_STATUS_INVALID_PARAMETER
1014 * Returned if pProps is NULL or specifies a memory area to
1015 * which data cannot be written.
1016 *
1017 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1018 * Returned if oid does not specify any valid object type.
1019 *
1020 * @retval MP_STATUS_OBJECT_NOT_FOUND
1021 * Returned if oid has an owner that is not currently known to
1022 * the system.
1023 *
1024 *******************************************************************************
1025 */
MP_GetMPLogicalUnitProperties(MP_OID oid,MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES * pProps)1026 MP_STATUS MP_GetMPLogicalUnitProperties(
1027 MP_OID oid,
1028 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES *pProps)
1029 {
1030 MP_GetMPLogicalUnitPropertiesFn PassFunc;
1031 MP_UINT32 index;
1032 MP_STATUS status;
1033
1034 if (pProps == NULL)
1035 return MP_STATUS_INVALID_PARAMETER;
1036
1037 if ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
1038 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1039 return (status);
1040 }
1041
1042 (void) pthread_mutex_lock(&mp_lib_mutex);
1043
1044 index = oid.ownerId - 1;
1045 if (plugintable[index].hdlPlugin != NULL) {
1046 PassFunc = (MP_GetMPLogicalUnitPropertiesFn)
1047 dlsym(plugintable[index].hdlPlugin,
1048 "MP_GetMPLogicalUnitProperties");
1049
1050 if (PassFunc != NULL) {
1051 status = PassFunc(oid, pProps);
1052 } else {
1053 status = MP_STATUS_UNSUPPORTED;
1054 }
1055 } else {
1056 status = MP_STATUS_FAILED;
1057 }
1058
1059 (void) pthread_mutex_unlock(&mp_lib_mutex);
1060 return (status);
1061 }
1062
1063 /**
1064 *******************************************************************************
1065 *
1066 * Gets a list of the object IDs of all the path logical units associated
1067 * with the specified multipath logical unit, initiator port, or target port.
1068 *
1069 * @param oid
1070 * The object ID of multipath logical unit, initiator port, or
1071 * target port.
1072 *
1073 * @param ppList
1074 * A pointer to a pointer to an MP_OID_LIST structure.
1075 * On a successful return, this will contain a pointer to
1076 * an MP_OID_LIST that contains the object IDs of all the mp path
1077 * logical units associated with the specified OID.
1078 *
1079 * @return An MP_STATUS indicating if the operation was successful or if
1080 * an error occurred.
1081 *
1082 * @retval MP_STATUS_SUCCESS
1083 * Returned when the operation is successful.
1084 *
1085 * @retval MP_STATUS_INVALID_PARAMETER
1086 * Returned if ppList pointer passed as placeholder for holding
1087 * the device product list is found to be invalid.
1088 *
1089 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1090 * Returned if oid does not specify any valid object type.
1091 *
1092 * @retval MP_STATUS_FAILED
1093 * Returned when the plugin for the specified oid is not found.
1094 *
1095 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1096 * Returned when memory allocation failure occurs
1097 *
1098 * @retval MP_STATUS_OBJECT_NOT_FOUND
1099 * Returned if oid has an owner that is not currently known to
1100 * the system.
1101 *
1102 *******************************************************************************
1103 */
MP_GetAssociatedPathOidList(MP_OID oid,MP_OID_LIST ** ppList)1104 MP_STATUS MP_GetAssociatedPathOidList(
1105 MP_OID oid,
1106 MP_OID_LIST **ppList)
1107 {
1108 MP_GetAssociatedPathOidListFn PassFunc;
1109 MP_UINT32 index;
1110 MP_STATUS status;
1111
1112 if (ppList == NULL)
1113 return MP_STATUS_INVALID_PARAMETER;
1114
1115 if (((status = validate_object(oid, MP_OBJECT_TYPE_INITIATOR_PORT,
1116 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
1117 ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT,
1118 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
1119 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
1120 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
1121 return (status);
1122 }
1123
1124 (void) pthread_mutex_lock(&mp_lib_mutex);
1125
1126 index = oid.ownerId - 1;
1127 if (plugintable[index].hdlPlugin != NULL) {
1128 PassFunc = (MP_GetAssociatedPathOidListFn)
1129 dlsym(plugintable[index].hdlPlugin,
1130 "MP_GetAssociatedPathOidList");
1131
1132 if (PassFunc != NULL) {
1133 status = PassFunc(oid, ppList);
1134 } else {
1135 status = MP_STATUS_UNSUPPORTED;
1136 }
1137 } else {
1138 status = MP_STATUS_FAILED;
1139 }
1140
1141 (void) pthread_mutex_unlock(&mp_lib_mutex);
1142 return (status);
1143 }
1144
1145 /**
1146 *******************************************************************************
1147 *
1148 * Gets the properties of the specified path logical unit.
1149 *
1150 * @param oid
1151 * The object ID of the path logical unit.
1152 *
1153 * @param pProps
1154 * A pointer to an MP_PATH_LOGICAL_UNIT_PROPERTIES structure
1155 * allocated by the caller. On successful return, this structure
1156 * will contain the properties of the port specified by oid.
1157 *
1158 * @return An MP_STATUS indicating if the operation was successful or if
1159 * an error occurred.
1160 *
1161 * @retval MP_STATUS_SUCCESS
1162 * Returned when the operation is successful.
1163 *
1164 * @retval MP_STATUS_INVALID_PARAMETER
1165 * Returned if pProps is NULL or specifies a memory area to
1166 * which data cannot be written.
1167 *
1168 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1169 * Returned if oid does not specify any valid object type.
1170 *
1171 * @retval MP_STATUS_OBJECT_NOT_FOUND
1172 * Returned if oid has an owner that is not currently known to
1173 * the system.
1174 *
1175 *******************************************************************************
1176 */
MP_GetPathLogicalUnitProperties(MP_OID oid,MP_PATH_LOGICAL_UNIT_PROPERTIES * pProps)1177 MP_STATUS MP_GetPathLogicalUnitProperties(
1178 MP_OID oid,
1179 MP_PATH_LOGICAL_UNIT_PROPERTIES *pProps)
1180 {
1181 MP_GetPathLogicalUnitPropertiesFn PassFunc;
1182 MP_UINT32 index;
1183 MP_STATUS status;
1184
1185 if (pProps == NULL)
1186 return MP_STATUS_INVALID_PARAMETER;
1187
1188 if ((status = validate_object(oid, MP_OBJECT_TYPE_PATH_LU,
1189 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1190 return (status);
1191 }
1192
1193 (void) pthread_mutex_lock(&mp_lib_mutex);
1194
1195 index = oid.ownerId - 1;
1196 if (plugintable[index].hdlPlugin != NULL) {
1197 PassFunc = (MP_GetPathLogicalUnitPropertiesFn)
1198 dlsym(plugintable[index].hdlPlugin,
1199 "MP_GetPathLogicalUnitProperties");
1200
1201 if (PassFunc != NULL) {
1202 status = PassFunc(oid, pProps);
1203 } else {
1204 status = MP_STATUS_UNSUPPORTED;
1205 }
1206 } else {
1207 status = MP_STATUS_FAILED;
1208 }
1209
1210 (void) pthread_mutex_unlock(&mp_lib_mutex);
1211 return (status);
1212 }
1213
1214 /**
1215 *******************************************************************************
1216 *
1217 * Gets a list of the object IDs of all the target port group associated
1218 * with the specified multipath logical unit.
1219 *
1220 * @param oid
1221 * The object ID of the multiple logical unit.
1222 *
1223 * @param ppList
1224 * A pointer to a pointer to an MP_OID_LIST structure.
1225 * On a successful return, this will contain a pointer to
1226 * an MP_OID_LIST that contains the object IDs of all the target
1227 * port group associated with the specified multipath logical unit.
1228 *
1229 * @return An MP_STATUS indicating if the operation was successful or if
1230 * an error occurred.
1231 *
1232 * @retval MP_STATUS_SUCCESS
1233 * Returned when the operation is successful.
1234 *
1235 * @retval MP_STATUS_INVALID_PARAMETER
1236 * Returned if ppList pointer passed as placeholder for holding
1237 * the target port group list is found to be invalid.
1238 *
1239 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1240 * Returned if oid does not specify any valid object type.
1241 *
1242 * @retval MP_STATUS_FAILED
1243 * Returned when the plugin for the specified oid is not found.
1244 *
1245 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1246 * Returned when memory allocation failure occurs
1247 *
1248 *
1249 *******************************************************************************
1250 */
MP_GetAssociatedTPGOidList(MP_OID oid,MP_OID_LIST ** ppList)1251 MP_STATUS MP_GetAssociatedTPGOidList(
1252 MP_OID oid,
1253 MP_OID_LIST **ppList)
1254 {
1255 MP_GetAssociatedTPGOidListFn PassFunc;
1256 MP_UINT32 index;
1257 MP_STATUS status;
1258
1259 if (ppList == NULL)
1260 return MP_STATUS_INVALID_PARAMETER;
1261
1262 if ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
1263 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1264 return (status);
1265 }
1266
1267 (void) pthread_mutex_lock(&mp_lib_mutex);
1268
1269 index = oid.ownerId - 1;
1270 if (plugintable[index].hdlPlugin != NULL) {
1271 PassFunc = (MP_GetAssociatedTPGOidListFn)
1272 dlsym(plugintable[index].hdlPlugin,
1273 "MP_GetAssociatedTPGOidList");
1274
1275 if (PassFunc != NULL) {
1276 status = PassFunc(oid, ppList);
1277 } else {
1278 status = MP_STATUS_UNSUPPORTED;
1279 }
1280 } else {
1281 status = MP_STATUS_FAILED;
1282 }
1283
1284 (void) pthread_mutex_unlock(&mp_lib_mutex);
1285 return (status);
1286 }
1287
1288 /**
1289 *******************************************************************************
1290 *
1291 * Gets the properties of the specified target port group.
1292 *
1293 * @param oid
1294 * The object ID of the target port group.
1295 *
1296 * @param pProps
1297 * A pointer to an MP_TARGET_PORT_GROUP_PROPERTIES structure
1298 * allocated by the caller. On successful return, this structure
1299 * will contain the properties of the port specified by oid.
1300 *
1301 * @return An MP_STATUS indicating if the operation was successful or if
1302 * an error occurred.
1303 *
1304 * @retval MP_STATUS_SUCCESS
1305 * Returned when the operation is successful.
1306 *
1307 * @retval MP_STATUS_INVALID_PARAMETER
1308 * Returned if pProps is NULL or specifies a memory area to
1309 * which data cannot be written.
1310 *
1311 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1312 * Returned if oid does not specify any valid object type.
1313 *
1314 * @retval MP_STATUS_OBJECT_NOT_FOUND
1315 * Returned if oid has an owner that is not currently known to
1316 * the system.
1317 *
1318 *******************************************************************************
1319 */
MP_GetTargetPortGroupProperties(MP_OID oid,MP_TARGET_PORT_GROUP_PROPERTIES * pProps)1320 MP_STATUS MP_GetTargetPortGroupProperties(
1321 MP_OID oid,
1322 MP_TARGET_PORT_GROUP_PROPERTIES *pProps)
1323 {
1324 MP_GetTargetPortGroupPropertiesFn PassFunc;
1325 MP_UINT32 index;
1326 MP_STATUS status;
1327
1328 if (pProps == NULL)
1329 return MP_STATUS_INVALID_PARAMETER;
1330
1331 if ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT_GROUP,
1332 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1333 return (status);
1334 }
1335
1336 (void) pthread_mutex_lock(&mp_lib_mutex);
1337
1338 index = oid.ownerId - 1;
1339 if (plugintable[index].hdlPlugin != NULL) {
1340 PassFunc = (MP_GetTargetPortGroupPropertiesFn)
1341 dlsym(plugintable[index].hdlPlugin,
1342 "MP_GetTargetPortGroupProperties");
1343
1344 if (PassFunc != NULL) {
1345 status = PassFunc(oid, pProps);
1346 } else {
1347 status = MP_STATUS_UNSUPPORTED;
1348 }
1349 } else {
1350 status = MP_STATUS_FAILED;
1351 }
1352
1353 (void) pthread_mutex_unlock(&mp_lib_mutex);
1354 return (status);
1355 }
1356
1357 /**
1358 *******************************************************************************
1359 *
1360 * Gets a list of multipath logical units associated with the specific target
1361 * port group.
1362 *
1363 * @param oid
1364 * The object ID of the target port group.
1365 *
1366 * @param ppList
1367 * A pointer to a pointer to an MP_OID_LIST structure.
1368 * On a successful return, this will contain a pointer to
1369 * an MP_OID_LIST that contains the object IDs of all the multipath
1370 * logical units associated with the specified target port group.
1371 *
1372 * @return An MP_STATUS indicating if the operation was successful or if
1373 * an error occurred.
1374 *
1375 * @retval MP_STATUS_SUCCESS
1376 * Returned when the operation is successful.
1377 *
1378 * @retval MP_STATUS_INVALID_PARAMETER
1379 * Returned if ppList pointer passed as placeholder for holding
1380 * the multipath logical unit list is found to be invalid.
1381 *
1382 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1383 * Returned if oid does not specify any valid object type.
1384 *
1385 * @retval MP_STATUS_FAILED
1386 * Returned when the plugin for the specified oid is not found.
1387 *
1388 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1389 * Returned when memory allocation failure occurs
1390 *
1391 *******************************************************************************
1392 */
MP_GetMPLuOidListFromTPG(MP_OID oid,MP_OID_LIST ** ppList)1393 MP_STATUS MP_GetMPLuOidListFromTPG(
1394 MP_OID oid,
1395 MP_OID_LIST **ppList)
1396 {
1397 MP_GetMPLuOidListFromTPGFn PassFunc;
1398 MP_UINT32 index;
1399 MP_STATUS status;
1400
1401 if (ppList == NULL)
1402 return MP_STATUS_INVALID_PARAMETER;
1403
1404 if ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT_GROUP,
1405 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1406 return (status);
1407 }
1408
1409 (void) pthread_mutex_lock(&mp_lib_mutex);
1410
1411 index = oid.ownerId - 1;
1412 if (plugintable[index].hdlPlugin != NULL) {
1413 PassFunc = (MP_GetMPLuOidListFromTPGFn)
1414 dlsym(plugintable[index].hdlPlugin,
1415 "MP_GetMPLuOidListFromTPG");
1416
1417 if (PassFunc != NULL) {
1418 status = PassFunc(oid, ppList);
1419 } else {
1420 status = MP_STATUS_UNSUPPORTED;
1421 }
1422 } else {
1423 status = MP_STATUS_FAILED;
1424 }
1425
1426 (void) pthread_mutex_unlock(&mp_lib_mutex);
1427 return (status);
1428 }
1429
1430 /**
1431 *******************************************************************************
1432 *
1433 * Gets a list of the object IDs of all the proprietary load balance
1434 * algorithms associated with this plugin.
1435 *
1436 * @param oid
1437 * The object ID of the plugin.
1438 *
1439 * @param ppList
1440 * A pointer to a pointer to an MP_OID_LIST structure.
1441 * On a successful return, this will contain a pointer to
1442 * an MP_OID_LIST that contains the object IDs of all the proprietary
1443 * load balance algorithms associated with the specified plugin.
1444 *
1445 * @return An MP_STATUS indicating if the operation was successful or if
1446 * an error occurred.
1447 *
1448 * @retval MP_STATUS_SUCCESS
1449 * Returned when the operation is successful.
1450 *
1451 * @retval MP_STATUS_INVALID_PARAMETER
1452 * Returned if ppList pointer passed as placeholder for holding
1453 * the proprietary load balance oid list is found to be invalid.
1454 *
1455 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1456 * Returned if oid does not specify any valid object type.
1457 *
1458 * @retval MP_STATUS_FAILED
1459 * Returned when the plugin for the specified oid is not found.
1460 *
1461 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1462 * Returned when memory allocation failure occurs
1463 *
1464 * @retval MP_STATUS_UNSUPPORTED
1465 * Returned when the API is not supported.
1466 *
1467 *******************************************************************************
1468 */
MP_GetProprietaryLoadBalanceOidList(MP_OID oid,MP_OID_LIST ** ppList)1469 MP_STATUS MP_GetProprietaryLoadBalanceOidList(
1470 MP_OID oid,
1471 MP_OID_LIST **ppList)
1472 {
1473 MP_GetProprietaryLoadBalanceOidListPluginFn PassFunc;
1474 MP_UINT32 index;
1475 MP_STATUS status;
1476
1477 if (ppList == NULL)
1478 return MP_STATUS_INVALID_PARAMETER;
1479
1480 if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
1481 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1482 return (status);
1483 }
1484
1485 (void) pthread_mutex_lock(&mp_lib_mutex);
1486
1487 index = oid.ownerId - 1;
1488 if (plugintable[index].hdlPlugin != NULL) {
1489 PassFunc = (MP_GetProprietaryLoadBalanceOidListPluginFn)
1490 dlsym(plugintable[index].hdlPlugin,
1491 "MP_GetProprietaryLoadBalanceOidListPlugin");
1492
1493 if (PassFunc != NULL) {
1494 status = PassFunc(ppList);
1495 } else {
1496 status = MP_STATUS_UNSUPPORTED;
1497 }
1498 } else {
1499 status = MP_STATUS_FAILED;
1500 }
1501
1502 (void) pthread_mutex_unlock(&mp_lib_mutex);
1503 return (status);
1504 }
1505
1506 /**
1507 *******************************************************************************
1508 *
1509 * Gets the properties of the specified load balance properties structure.
1510 *
1511 * @param oid
1512 * The object ID of the load balance properties structure.
1513 *
1514 * @param pProps
1515 * A pointer to an MP_LOAD_BALANCE_PROPRIETARY_TYPE structure
1516 * allocated by the caller. On successful return, this structure
1517 * will contain the properties of the proprietary load balance algorithm
1518 * specified by oid.
1519 *
1520 * @return An MP_STATUS indicating if the operation was successful or if
1521 * an error occurred.
1522 *
1523 * @retval MP_STATUS_SUCCESS
1524 * Returned when the operation is successful.
1525 *
1526 * @retval MP_STATUS_INVALID_PARAMETER
1527 * Returned if pProps is NULL or specifies a memory area to
1528 * which data cannot be written.
1529 *
1530 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1531 * Returned if oid does not specify any valid object type.
1532 *
1533 * @retval MP_STATUS_OBJECT_NOT_FOUND
1534 * Returned if oid has an owner that is not currently known to
1535 * the system.
1536 *
1537 *******************************************************************************
1538 */
MP_GetProprietaryLoadBalanceProperties(MP_OID oid,MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES * pProps)1539 MP_STATUS MP_GetProprietaryLoadBalanceProperties (
1540 MP_OID oid,
1541 MP_PROPRIETARY_LOAD_BALANCE_PROPERTIES *pProps)
1542 {
1543 MP_GetProprietaryLoadBalancePropertiesFn PassFunc;
1544 MP_UINT32 index;
1545 MP_STATUS status;
1546
1547 if (pProps == NULL)
1548 return MP_STATUS_INVALID_PARAMETER;
1549
1550 if ((status = validate_object(oid, MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE,
1551 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1552 return (status);
1553 }
1554
1555 (void) pthread_mutex_lock(&mp_lib_mutex);
1556
1557 index = oid.ownerId - 1;
1558 if (plugintable[index].hdlPlugin != NULL) {
1559 PassFunc = (MP_GetProprietaryLoadBalancePropertiesFn)
1560 dlsym(plugintable[index].hdlPlugin,
1561 "MP_GetProprietaryLoadBalanceProperties");
1562
1563 if (PassFunc != NULL) {
1564 status = PassFunc(oid, pProps);
1565 } else {
1566 status = MP_STATUS_UNSUPPORTED;
1567 }
1568 } else {
1569 status = MP_STATUS_FAILED;
1570 }
1571
1572 (void) pthread_mutex_unlock(&mp_lib_mutex);
1573 return (status);
1574 }
1575
1576 /**
1577 *******************************************************************************
1578 *
1579 * Gets a list of the object IDs of the target ports in the specified target
1580 * port group.
1581 *
1582 * @param oid
1583 * The object ID of the target port group.
1584 *
1585 * @param ppList
1586 * A pointer to a pointer to an MP_OID_LIST structure.
1587 * On a successful return, this will contain a pointer to
1588 * an MP_OID_LIST that contains the object IDs of all the target ports
1589 * associated with the specified target port group.
1590 *
1591 * @return An MP_STATUS indicating if the operation was successful or if
1592 * an error occurred.
1593 *
1594 * @retval MP_STATUS_SUCCESS
1595 * Returned when the operation is successful.
1596 *
1597 * @retval MP_STATUS_INVALID_PARAMETER
1598 * Returned if ppList pointer passed as placeholder for holding
1599 * the multipath logical unit list is found to be invalid.
1600 *
1601 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1602 * Returned if oid does not specify any valid object type.
1603 *
1604 * @retval MP_STATUS_FAILED
1605 * Returned when the plugin for the specified oid is not found.
1606 *
1607 * @retval MP_STATUS_INSUFFICIENT_MEMORY
1608 * Returned when memory allocation failure occurs
1609 *
1610 *******************************************************************************
1611 */
MP_GetTargetPortOidList(MP_OID oid,MP_OID_LIST ** ppList)1612 MP_STATUS MP_GetTargetPortOidList(
1613 MP_OID oid,
1614 MP_OID_LIST **ppList)
1615 {
1616 MP_GetTargetPortOidListFn PassFunc;
1617 MP_UINT32 index;
1618 MP_STATUS status;
1619
1620 if (ppList == NULL)
1621 return MP_STATUS_INVALID_PARAMETER;
1622
1623 if ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT_GROUP,
1624 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1625 return (status);
1626 }
1627
1628 (void) pthread_mutex_lock(&mp_lib_mutex);
1629
1630 index = oid.ownerId - 1;
1631 if (plugintable[index].hdlPlugin != NULL) {
1632 PassFunc = (MP_GetTargetPortOidListFn)
1633 dlsym(plugintable[index].hdlPlugin,
1634 "MP_GetTargetPortOidList");
1635
1636 if (PassFunc != NULL) {
1637 status = PassFunc(oid, ppList);
1638 } else {
1639 status = MP_STATUS_UNSUPPORTED;
1640 }
1641 } else {
1642 status = MP_STATUS_FAILED;
1643 }
1644
1645 (void) pthread_mutex_unlock(&mp_lib_mutex);
1646 return (status);
1647 }
1648
1649 /**
1650 *******************************************************************************
1651 *
1652 * Gets the properties of the specified target port.
1653 *
1654 * @param oid
1655 * The object ID of the target port.
1656 *
1657 * @param pProps
1658 * A pointer to an MP_TARGET_PORT_PROPERTIES structure
1659 * allocated by the caller. On successful return, this structure
1660 * will contain the properties of the port specified by oid.
1661 *
1662 * @return An MP_STATUS indicating if the operation was successful or if
1663 * an error occurred.
1664 *
1665 * @retval MP_STATUS_SUCCESS
1666 * Returned when the operation is successful.
1667 *
1668 * @retval MP_STATUS_INVALID_PARAMETER
1669 * Returned if pProps is NULL or specifies a memory area to
1670 * which data cannot be written.
1671 *
1672 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1673 * Returned if oid does not specify any valid object type.
1674 *
1675 * @retval MP_STATUS_OBJECT_NOT_FOUND
1676 * Returned if oid has an owner that is not currently known to
1677 * the system.
1678 *
1679 *******************************************************************************
1680 */
MP_GetTargetPortProperties(MP_OID oid,MP_TARGET_PORT_PROPERTIES * pProps)1681 MP_STATUS MP_GetTargetPortProperties(
1682 MP_OID oid,
1683 MP_TARGET_PORT_PROPERTIES *pProps)
1684 {
1685 MP_GetTargetPortPropertiesFn PassFunc;
1686 MP_UINT32 index;
1687 MP_STATUS status;
1688
1689 if (pProps == NULL)
1690 return MP_STATUS_INVALID_PARAMETER;
1691
1692 if ((status = validate_object(oid, MP_OBJECT_TYPE_TARGET_PORT,
1693 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1694 return (status);
1695 }
1696
1697 (void) pthread_mutex_lock(&mp_lib_mutex);
1698
1699 index = oid.ownerId - 1;
1700 if (plugintable[index].hdlPlugin != NULL) {
1701 PassFunc = (MP_GetTargetPortPropertiesFn)
1702 dlsym(plugintable[index].hdlPlugin,
1703 "MP_GetTargetPortProperties");
1704
1705 if (PassFunc != NULL) {
1706 status = PassFunc(oid, pProps);
1707 } else {
1708 status = MP_STATUS_UNSUPPORTED;
1709 }
1710 } else {
1711 status = MP_STATUS_FAILED;
1712 }
1713
1714 (void) pthread_mutex_unlock(&mp_lib_mutex);
1715 return (status);
1716 }
1717
1718
1719 /**
1720 *******************************************************************************
1721 *
1722 * Assign a multipath logical unit to a target port group.
1723 *
1724 * @param tpgOid
1725 * An MP_TARGET_PORT_GROUP oid. The target port group currently in
1726 * active access state that the administrator would like the LU
1727 * assigned to.
1728 *
1729 * @param luOid
1730 * An MP_MULTIPATH_LOGICAL_UNIT oid.
1731 *
1732 * @return An MP_STATUS indicating if the operation was successful or if
1733 * an error occurred.
1734 *
1735 * @retval MP_STATUS_SUCCESS
1736 * Returned when the operation is successful.
1737 *
1738 * @retval MP_STATUS_INVALID_PARAMETER
1739 * Returned when luOid is not associated with tpgOid.
1740 *
1741 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1742 * Returned if oid does not specify any valid object type.
1743 *
1744 * @retval MP_STATUS_OBJECT_NOT_FOUND
1745 * Returned if oid has an owner that is not currently known to
1746 * the system.
1747 *
1748 *******************************************************************************
1749 */
MP_AssignLogicalUnitToTPG(MP_OID tpgOid,MP_OID luOid)1750 MP_STATUS MP_AssignLogicalUnitToTPG(
1751 MP_OID tpgOid,
1752 MP_OID luOid)
1753 {
1754 MP_AssignLogicalUnitToTPGFn PassFunc;
1755 MP_UINT32 index;
1756 MP_STATUS status;
1757
1758 if (luOid.ownerId != tpgOid.ownerId) {
1759 return (MP_STATUS_INVALID_PARAMETER);
1760 }
1761
1762 if ((status = validate_object(tpgOid, MP_OBJECT_TYPE_TARGET_PORT_GROUP,
1763 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1764 return (status);
1765 }
1766
1767 if ((status = validate_object(luOid, MP_OBJECT_TYPE_MULTIPATH_LU,
1768 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1769 return (status);
1770 }
1771
1772 (void) pthread_mutex_lock(&mp_lib_mutex);
1773
1774 index = tpgOid.ownerId - 1;
1775 if (plugintable[index].hdlPlugin != NULL) {
1776 PassFunc = (MP_AssignLogicalUnitToTPGFn)
1777 dlsym(plugintable[index].hdlPlugin,
1778 "MP_AssignLogicalUnitToTPG");
1779
1780 if (PassFunc != NULL) {
1781 status = PassFunc(tpgOid, luOid);
1782 } else {
1783 status = MP_STATUS_UNSUPPORTED;
1784 }
1785 } else {
1786 status = MP_STATUS_FAILED;
1787 }
1788
1789 (void) pthread_mutex_unlock(&mp_lib_mutex);
1790 return (status);
1791 }
1792
1793 /**
1794 *******************************************************************************
1795 *
1796 * Manually override the path for a logical unit. The path exclusively used to
1797 * access the logical unit until cleared.
1798 *
1799 * @param logicalUnitOid
1800 * The object ID of the multipath logical unit.
1801 *
1802 * @param pathOid
1803 * The object ID of the path logical unit.
1804 *
1805 * @return An MP_STATUS indicating if the operation was successful or if
1806 * an error occurred.
1807 *
1808 * @retval MP_STATUS_SUCCESS
1809 * Returned when the operation is successful.
1810 *
1811 * @retval MP_STATUS_INVALID_PARAMETER
1812 * Returned if the oid of the object is not valid
1813 *
1814 * @retval MP_STATUS_UNSUPPORTED
1815 * Returned when the implementation does not support the API
1816 *
1817 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1818 * Returned if oid does not specify any valid object type.
1819 *
1820 * @retval MP_STATUS_PATH_NONOPERATIONAL
1821 * Returned when the driver cannot communicate through selected path.
1822 *
1823 *******************************************************************************
1824 */
MP_SetOverridePath(MP_OID logicalUnitOid,MP_OID pathOid)1825 MP_STATUS MP_SetOverridePath(
1826 MP_OID logicalUnitOid,
1827 MP_OID pathOid)
1828 {
1829 MP_SetOverridePathFn PassFunc;
1830 MP_UINT32 index;
1831 MP_STATUS status;
1832
1833 if ((status = validate_object(logicalUnitOid, MP_OBJECT_TYPE_MULTIPATH_LU,
1834 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1835 return (status);
1836 }
1837 if ((status = validate_object(pathOid, MP_OBJECT_TYPE_PATH_LU,
1838 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1839 return (status);
1840 }
1841
1842 (void) pthread_mutex_lock(&mp_lib_mutex);
1843
1844 index = pathOid.ownerId - 1;
1845 if (plugintable[index].hdlPlugin != NULL) {
1846 PassFunc = (MP_SetOverridePathFn)
1847 dlsym(plugintable[index].hdlPlugin,
1848 "MP_SetOverridePath");
1849
1850 if (PassFunc != NULL) {
1851 status = PassFunc(logicalUnitOid, pathOid);
1852 } else {
1853 status = MP_STATUS_UNSUPPORTED;
1854 }
1855 } else {
1856 status = MP_STATUS_FAILED;
1857 }
1858
1859 (void) pthread_mutex_unlock(&mp_lib_mutex);
1860 return (status);
1861 }
1862
1863 /**
1864 *******************************************************************************
1865 *
1866 * Cancel a path override and re-enable load balancing.
1867 *
1868 * @param luOid
1869 * An MP_MULTIPATH_LOGICAL_UNIT oid.
1870 *
1871 * @return An MP_STATUS indicating if the operation was successful or if
1872 * an error occurred.
1873 *
1874 * @retval MP_STATUS_SUCCESS
1875 * Returned when the operation is successful.
1876 *
1877 * @retval MP_STATUS_INVALID_PARAMETER
1878 * Returned if MP_MULTIPATH_LOGICAL_UNIT with the luOid is not found.
1879 *
1880 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1881 * Returned if oid does not specify any valid object type.
1882 *
1883 * @retval MP_STATUS_OBJECT_NOT_FOUND
1884 * Returned if oid has an owner that is not currently known to
1885 * the system.
1886 *
1887 *******************************************************************************
1888 */
MP_CancelOverridePath(MP_OID luOid)1889 MP_STATUS MP_CancelOverridePath(
1890 MP_OID luOid)
1891 {
1892 MP_CancelOverridePathFn PassFunc;
1893 MP_UINT32 index;
1894 MP_STATUS status;
1895
1896 if ((status = validate_object(luOid, MP_OBJECT_TYPE_MULTIPATH_LU,
1897 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
1898 return (status);
1899 }
1900
1901 (void) pthread_mutex_lock(&mp_lib_mutex);
1902
1903 index = luOid.ownerId - 1;
1904 if (plugintable[index].hdlPlugin != NULL) {
1905 PassFunc = (MP_CancelOverridePathFn)
1906 dlsym(plugintable[index].hdlPlugin,
1907 "MP_CancelOverridePath");
1908
1909 if (PassFunc != NULL) {
1910 status = PassFunc(luOid);
1911 } else {
1912 status = MP_STATUS_UNSUPPORTED;
1913 }
1914 } else {
1915 status = MP_STATUS_FAILED;
1916 }
1917
1918 (void) pthread_mutex_unlock(&mp_lib_mutex);
1919 return (status);
1920 }
1921
1922 /**
1923 *******************************************************************************
1924 *
1925 * Enables Auto-failback.
1926 *
1927 * @param oid
1928 * The oid of the plugin.
1929 *
1930 * @return An MP_STATUS indicating if the operation was successful or if
1931 * an error occurred.
1932 *
1933 * @retval MP_STATUS_SUCCESS
1934 * Returned when the operation is successful.
1935 *
1936 * @retval MP_STATUS_INVALID_PARAMETER
1937 * Returned if oid is NULL or specifies a memory area that is not
1938 * a valid plugin oid.
1939 *
1940 * @retval MP_STATUS_INVALID_OBJECT_TYPE
1941 * Returned if oid does not specify any valid object type.
1942 *
1943 *******************************************************************************
1944 */
MP_EnableAutoFailback(MP_OID oid)1945 MP_STATUS MP_EnableAutoFailback(
1946 MP_OID oid)
1947 {
1948 MP_UINT32 index;
1949 MP_STATUS status;
1950
1951 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
1952 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
1953 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
1954 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
1955 return (status);
1956 }
1957
1958 (void) pthread_mutex_lock(&mp_lib_mutex);
1959
1960 index = oid.ownerId - 1;
1961 if (plugintable[index].hdlPlugin != NULL) {
1962 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
1963 MP_EnableAutoFailbackPluginFn PassFunc;
1964 PassFunc = (MP_EnableAutoFailbackPluginFn)
1965 dlsym(plugintable[index].hdlPlugin,
1966 "MP_EnableAutoFailbackPlugin");
1967
1968 if (PassFunc != NULL) {
1969 status = PassFunc();
1970 } else {
1971 status = MP_STATUS_UNSUPPORTED;
1972 }
1973 } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) {
1974 MP_EnableAutoFailbackLuFn PassFunc;
1975 PassFunc = (MP_EnableAutoFailbackLuFn)
1976 dlsym(plugintable[index].hdlPlugin,
1977 "MP_EnableAutoFailbackLu");
1978
1979 if (PassFunc != NULL) {
1980 status = PassFunc(oid);
1981 } else {
1982 status = MP_STATUS_UNSUPPORTED;
1983 }
1984 } else {
1985 status = MP_STATUS_INVALID_PARAMETER;
1986 }
1987 }
1988
1989 (void) pthread_mutex_unlock(&mp_lib_mutex);
1990 return (status);
1991 }
1992
1993 /**
1994 *******************************************************************************
1995 *
1996 * Enables Auto-probing.
1997 *
1998 * @param oid
1999 * The oid of the plugin or the multipath logical unit.
2000 *
2001 * @return An MP_STATUS indicating if the operation was successful or if
2002 * an error occurred.
2003 *
2004 * @retval MP_STATUS_SUCCESS
2005 * Returned when the operation is successful.
2006 *
2007 * @retval MP_STATUS_INVALID_PARAMETER
2008 * Returned if oid is NULL or specifies a memory area that is not
2009 * a valid plugin oid.
2010 *
2011 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2012 * Returned if oid does not specify any valid object type.
2013 *
2014 *******************************************************************************
2015 */
MP_EnableAutoProbing(MP_OID oid)2016 MP_STATUS MP_EnableAutoProbing(
2017 MP_OID oid)
2018 {
2019 MP_UINT32 index;
2020 MP_STATUS status;
2021
2022 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2023 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2024 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
2025 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
2026 return (status);
2027 }
2028
2029 (void) pthread_mutex_lock(&mp_lib_mutex);
2030
2031 index = oid.ownerId - 1;
2032 if (plugintable[index].hdlPlugin != NULL) {
2033 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
2034 MP_EnableAutoProbingPluginFn PassFunc;
2035 PassFunc = (MP_EnableAutoProbingPluginFn)
2036 dlsym(plugintable[index].hdlPlugin,
2037 "MP_EnableAutoProbingPlugin");
2038
2039 if (PassFunc != NULL) {
2040 status = PassFunc();
2041 } else {
2042 status = MP_STATUS_UNSUPPORTED;
2043 }
2044 } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) {
2045 MP_EnableAutoProbingLuFn PassFunc;
2046 PassFunc = (MP_EnableAutoProbingLuFn)
2047 dlsym(plugintable[index].hdlPlugin,
2048 "MP_EnableAutoProbingLu");
2049
2050 if (PassFunc != NULL) {
2051 status = PassFunc(oid);
2052 } else {
2053 status = MP_STATUS_UNSUPPORTED;
2054 }
2055 } else {
2056 status = MP_STATUS_INVALID_PARAMETER;
2057 }
2058 }
2059
2060 (void) pthread_mutex_unlock(&mp_lib_mutex);
2061 return (status);
2062 }
2063
2064 /**
2065 *******************************************************************************
2066 *
2067 * Disables Auto-failback.
2068 *
2069 * @param oid
2070 * The oid of the plugin.
2071 *
2072 * @return An MP_STATUS indicating if the operation was successful or if
2073 * an error occurred.
2074 *
2075 * @retval MP_STATUS_SUCCESS
2076 * Returned when the operation is successful.
2077 *
2078 * @retval MP_STATUS_INVALID_PARAMETER
2079 * Returned if oid is NULL or specifies a memory area that is not
2080 * a valid plugin oid.
2081 *
2082 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2083 * Returned if oid does not specify any valid object type.
2084 *
2085 *******************************************************************************
2086 */
MP_DisableAutoFailback(MP_OID oid)2087 MP_STATUS MP_DisableAutoFailback(
2088 MP_OID oid)
2089 {
2090 MP_UINT32 index;
2091 MP_STATUS status;
2092
2093 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2094 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2095 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
2096 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
2097 return (status);
2098 }
2099
2100 (void) pthread_mutex_lock(&mp_lib_mutex);
2101
2102 index = oid.ownerId - 1;
2103 if (plugintable[index].hdlPlugin != NULL) {
2104 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
2105 MP_DisableAutoFailbackPluginFn PassFunc;
2106 PassFunc = (MP_DisableAutoFailbackPluginFn)
2107 dlsym(plugintable[index].hdlPlugin,
2108 "MP_DisableAutoFailbackPlugin");
2109
2110 if (PassFunc != NULL) {
2111 status = PassFunc();
2112 } else {
2113 status = MP_STATUS_UNSUPPORTED;
2114 }
2115 } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) {
2116 MP_DisableAutoFailbackLuFn PassFunc;
2117 PassFunc = (MP_DisableAutoFailbackLuFn)
2118 dlsym(plugintable[index].hdlPlugin,
2119 "MP_DisableAutoFailbackLu");
2120
2121 if (PassFunc != NULL) {
2122 status = PassFunc(oid);
2123 } else {
2124 status = MP_STATUS_UNSUPPORTED;
2125 }
2126 } else {
2127 status = MP_STATUS_INVALID_PARAMETER;
2128 }
2129 }
2130
2131 (void) pthread_mutex_unlock(&mp_lib_mutex);
2132 return (status);
2133 }
2134
2135 /**
2136 *******************************************************************************
2137 *
2138 * Disables Auto-probing.
2139 *
2140 * @param oid
2141 * The oid of the plugin or the multipath logical unit.
2142 *
2143 * @return An MP_STATUS indicating if the operation was successful or if
2144 * an error occurred.
2145 *
2146 * @retval MP_STATUS_SUCCESS
2147 * Returned when the operation is successful.
2148 *
2149 * @retval MP_STATUS_INVALID_PARAMETER
2150 * Returned if oid is NULL or specifies a memory area that is not
2151 * a valid plugin oid.
2152 *
2153 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2154 * Returned if oid does not specify any valid object type.
2155 *
2156 *******************************************************************************
2157 */
MP_DisableAutoProbing(MP_OID oid)2158 MP_STATUS MP_DisableAutoProbing(
2159 MP_OID oid)
2160 {
2161 MP_UINT32 index;
2162 MP_STATUS status;
2163
2164 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2165 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2166 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
2167 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
2168 return (status);
2169 }
2170
2171 (void) pthread_mutex_lock(&mp_lib_mutex);
2172
2173 index = oid.ownerId - 1;
2174 if (plugintable[index].hdlPlugin != NULL) {
2175 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
2176 MP_DisableAutoProbingPluginFn PassFunc;
2177 PassFunc = (MP_DisableAutoProbingPluginFn)
2178 dlsym(plugintable[index].hdlPlugin,
2179 "MP_DisableAutoProbingPlugin");
2180
2181 if (PassFunc != NULL) {
2182 status = PassFunc();
2183 } else {
2184 status = MP_STATUS_UNSUPPORTED;
2185 }
2186 } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) {
2187 MP_DisableAutoFailbackLuFn PassFunc;
2188 PassFunc = (MP_DisableAutoProbingLuFn)
2189 dlsym(plugintable[index].hdlPlugin,
2190 "MP_DisableAutoProbingLu");
2191
2192 if (PassFunc != NULL) {
2193 status = PassFunc(oid);
2194 } else {
2195 status = MP_STATUS_UNSUPPORTED;
2196 }
2197 } else {
2198 status = MP_STATUS_INVALID_PARAMETER;
2199 }
2200 }
2201
2202 (void) pthread_mutex_unlock(&mp_lib_mutex);
2203 return (status);
2204 }
2205
2206 /**
2207 *******************************************************************************
2208 *
2209 * Enables a path. This API may cause failover in a logical unit with
2210 * asymmetric access.
2211 *
2212 * @param oid
2213 * The oid of the path.
2214 *
2215 * @return An MP_STATUS indicating if the operation was successful or if
2216 * an error occurred.
2217 *
2218 * @retval MP_STATUS_SUCCESS
2219 * Returned when the operation is successful.
2220 *
2221 * @retval MP_STATUS_INVALID_PARAMETER
2222 * Returned if oid is NULL or specifies a memory area that is not
2223 * a valid path oid.
2224 *
2225 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2226 * Returned if oid does not specify any valid object type.
2227 *
2228 *******************************************************************************
2229 */
MP_EnablePath(MP_OID oid)2230 MP_STATUS MP_EnablePath(
2231 MP_OID oid)
2232 {
2233 MP_EnablePathFn PassFunc;
2234 MP_UINT32 index;
2235 MP_STATUS status;
2236
2237 if ((status = validate_object(oid, MP_OBJECT_TYPE_PATH_LU,
2238 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2239 return (status);
2240 }
2241
2242 (void) pthread_mutex_lock(&mp_lib_mutex);
2243
2244 index = oid.ownerId - 1;
2245 if (plugintable[index].hdlPlugin != NULL) {
2246 PassFunc = (MP_EnablePathFn)
2247 dlsym(plugintable[index].hdlPlugin,
2248 "MP_EnablePath");
2249
2250 if (PassFunc != NULL) {
2251 status = PassFunc(oid);
2252 } else {
2253 status = MP_STATUS_UNSUPPORTED;
2254 }
2255 } else {
2256 status = MP_STATUS_FAILED;
2257 }
2258
2259 (void) pthread_mutex_unlock(&mp_lib_mutex);
2260 return (status);
2261 }
2262
2263 /**
2264 *******************************************************************************
2265 *
2266 * Disables a path. This API may cause failover in a logical unit with
2267 * asymmetric access. This API may cause a logical unit to become unavailable.
2268 *
2269 * @param oid
2270 * The oid of the path.
2271 *
2272 * @return An MP_STATUS indicating if the operation was successful or if
2273 * an error occurred.
2274 *
2275 * @retval MP_STATUS_SUCCESS
2276 * Returned when the operation is successful.
2277 *
2278 * @retval MP_STATUS_INVALID_PARAMETER
2279 * Returned if oid is NULL or specifies a memory area that is not
2280 * a valid path oid.
2281 *
2282 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2283 * Returned if oid does not specify any valid object type.
2284 *
2285 *******************************************************************************
2286 */
MP_DisablePath(MP_OID oid)2287 MP_STATUS MP_DisablePath(
2288 MP_OID oid)
2289 {
2290 MP_DisablePathFn PassFunc;
2291 MP_UINT32 index;
2292 MP_STATUS status;
2293
2294 if ((status = validate_object(oid, MP_OBJECT_TYPE_PATH_LU,
2295 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2296 return (status);
2297 }
2298
2299 (void) pthread_mutex_lock(&mp_lib_mutex);
2300
2301 index = oid.ownerId - 1;
2302 if (plugintable[index].hdlPlugin != NULL) {
2303 PassFunc = (MP_DisablePathFn)
2304 dlsym(plugintable[index].hdlPlugin,
2305 "MP_DisablePath");
2306
2307 if (PassFunc != NULL) {
2308 status = PassFunc(oid);
2309 } else {
2310 status = MP_STATUS_UNSUPPORTED;
2311 }
2312 } else {
2313 status = MP_STATUS_FAILED;
2314 }
2315
2316 (void) pthread_mutex_unlock(&mp_lib_mutex);
2317 return (status);
2318 }
2319
2320 /**
2321 *******************************************************************************
2322 *
2323 * Set the multipath logical unit s load balancing policy.
2324 *
2325 * @param logicalUnitoid
2326 * The object ID of the multipath logical unit.
2327 *
2328 * @param loadBanlance
2329 * The desired load balance policy for the specified logical unit.
2330 *
2331 * @return An MP_STATUS indicating if the operation was successful or if
2332 * an error occurred.
2333 *
2334 * @retval MP_STATUS_SUCCESS
2335 * Returned when the operation is successful.
2336 *
2337 * @retval MP_STATUS_INVALID_PARAMETER
2338 * Returned if no MP_MULTIPATH_LOGICAL_UNIT associated with
2339 * @ref ligicalUnitrOid is found or invalid MP_LOAD_BALANCE_TYPE is
2340 * specified.
2341 *
2342 * @retval MP_STATUS_FAILED
2343 * Returned when the specified loadBalance type cannot be handled
2344 * by the plugin.
2345 *
2346 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2347 * Returned if oid does not specify any valid object type.
2348 *
2349 *******************************************************************************
2350 */
MP_SetLogicalUnitLoadBalanceType(MP_OID logicalUnitOid,MP_LOAD_BALANCE_TYPE loadBalance)2351 MP_STATUS MP_SetLogicalUnitLoadBalanceType(
2352 MP_OID logicalUnitOid,
2353 MP_LOAD_BALANCE_TYPE loadBalance)
2354 {
2355 MP_SetLogicalUnitLoadBalanceTypeFn PassFunc;
2356 MP_UINT32 index;
2357 MP_STATUS status;
2358
2359 if ((status = validate_object(logicalUnitOid,
2360 MP_OBJECT_TYPE_MULTIPATH_LU,
2361 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2362 return (status);
2363 }
2364
2365 (void) pthread_mutex_lock(&mp_lib_mutex);
2366
2367 index = logicalUnitOid.ownerId - 1;
2368 if (plugintable[index].hdlPlugin != NULL) {
2369 PassFunc = (MP_SetLogicalUnitLoadBalanceTypeFn)
2370 dlsym(plugintable[index].hdlPlugin,
2371 "MP_SetLogicalUnitLoadBalanceType");
2372
2373 if (PassFunc != NULL) {
2374 status = PassFunc(logicalUnitOid, loadBalance);
2375 } else {
2376 status = MP_STATUS_UNSUPPORTED;
2377 }
2378 } else {
2379 status = MP_STATUS_FAILED;
2380 }
2381
2382 (void) pthread_mutex_unlock(&mp_lib_mutex);
2383 return (status);
2384 }
2385
2386 /**
2387 *******************************************************************************
2388 *
2389 * Set the weight to be assigned to a particular path.
2390 *
2391 * @param pathOid
2392 * The object ID of the path logical unit.
2393 *
2394 * @param weight
2395 * weight that will be assigned to the path logical unit.
2396 *
2397 * @return An MP_STATUS indicating if the operation was successful or if
2398 * an error occurred.
2399 *
2400 * @retval MP_STATUS_SUCCESS
2401 * Returned when the operation is successful.
2402 *
2403 * @retval MP_STATUS_OBJECT_NOT_FOUND
2404 * Returned when the MP Path specified by the PathOid could not be
2405 * found.
2406 *
2407 * @retval MP_STATUS_UNSUPPORTED
2408 * Returned when the implementation does not support the API
2409 *
2410 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2411 * Returned if oid does not specify any valid object type.
2412 *
2413 * @retval MP_STATUS_FAILED
2414 * Returned when the operation failed.
2415 *
2416 * @retval MP_STATUS_PATH_NONOPERATIONAL
2417 * Returned when the driver cannot communicate through selected path.
2418 *
2419 * @retval MP_STATUS_INVALID_WEIGHT
2420 * Returned when the weight parameter is greater than the plugin's
2421 * maxWeight property.
2422 *
2423 *******************************************************************************
2424 */
MP_SetPathWeight(MP_OID pathOid,MP_UINT32 weight)2425 MP_STATUS MP_SetPathWeight(
2426 MP_OID pathOid,
2427 MP_UINT32 weight)
2428 {
2429 MP_SetPathWeightFn PassFunc;
2430 MP_UINT32 index;
2431 MP_STATUS status;
2432
2433 if ((status = validate_object(pathOid, MP_OBJECT_TYPE_PATH_LU,
2434 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2435 return (status);
2436 }
2437
2438 (void) pthread_mutex_lock(&mp_lib_mutex);
2439
2440 index = pathOid.ownerId - 1;
2441 if (plugintable[index].hdlPlugin != NULL) {
2442 PassFunc = (MP_SetPathWeightFn)
2443 dlsym(plugintable[index].hdlPlugin,
2444 "MP_SetPathWeight");
2445
2446 if (PassFunc != NULL) {
2447 status = PassFunc(pathOid, weight);
2448 } else {
2449 status = MP_STATUS_UNSUPPORTED;
2450 }
2451 } else {
2452 status = MP_STATUS_FAILED;
2453 }
2454
2455 (void) pthread_mutex_unlock(&mp_lib_mutex);
2456 return (status);
2457 }
2458
2459 /**
2460 *******************************************************************************
2461 *
2462 * Set the default load balance policy for the plugin.
2463 *
2464 * @param oid
2465 * The object ID of the plugin
2466 *
2467 * @param loadBalance
2468 * The desired default load balance policy for the specified plugin.
2469 *
2470 * @return An MP_STATUS indicating if the operation was successful or if
2471 * an error occurred.
2472 *
2473 * @retval MP_STATUS_SUCCESS
2474 * Returned when the operation is successful.
2475 *
2476 * @retval MP_STATUS_OBJECT_NOT_FOUND
2477 * Returned when the the plugin specified by @ref oid could not be
2478 * found.
2479 *
2480 * @retval MP_STATUS_INVALID_PARAMETER
2481 * Returned if the oid of the object is not valid.
2482 *
2483 * @retval MP_STATUS_UNSUPPORTED
2484 * Returned when the implementation does not support the API
2485 *
2486 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2487 * Returned if oid does not specify any valid object type.
2488 *
2489 * @retval MP_STATUS_FAILED
2490 * Returned when the specified loadBalance type cannot be handled
2491 * by the plugin.
2492 *
2493 *******************************************************************************
2494 */
MP_SetPluginLoadBalanceType(MP_OID oid,MP_LOAD_BALANCE_TYPE loadBalance)2495 MP_STATUS MP_SetPluginLoadBalanceType(
2496 MP_OID oid,
2497 MP_LOAD_BALANCE_TYPE loadBalance)
2498 {
2499 MP_SetPluginLoadBalanceTypePluginFn PassFunc;
2500 MP_UINT32 index;
2501 MP_STATUS status;
2502
2503 if ((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2504 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2505 return (status);
2506 }
2507
2508 (void) pthread_mutex_lock(&mp_lib_mutex);
2509
2510 index = oid.ownerId - 1;
2511 if (plugintable[index].hdlPlugin != NULL) {
2512 PassFunc = (MP_SetPluginLoadBalanceTypePluginFn)
2513 dlsym(plugintable[index].hdlPlugin,
2514 "MP_SetPluginLoadBalanceTypePlugin");
2515
2516 if (PassFunc != NULL) {
2517 status = PassFunc(loadBalance);
2518 } else {
2519 status = MP_STATUS_UNSUPPORTED;
2520 }
2521 } else {
2522 status = MP_STATUS_FAILED;
2523 }
2524
2525 (void) pthread_mutex_unlock(&mp_lib_mutex);
2526 return (status);
2527 }
2528
2529 /**
2530 *******************************************************************************
2531 *
2532 * Set the failback polling rates. Setting both rates to zero disables polling.
2533 *
2534 * @param pluginOid
2535 * The object ID of the plugin or multipath lu.
2536 *
2537 * @param pollingRate
2538 * The value to be set in MP_PLUGIN_PROPERTIES currentPollingRate.or
2539 * MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES pollingRate.
2540 *
2541 * @return An MP_STATUS indicating if the operation was successful or if
2542 * an error occurred.
2543 *
2544 * @retval MP_STATUS_SUCCESS
2545 * Returned when the operation is successful.
2546 *
2547 * @retval MP_STATUS_OBJECT_NOT_FOUND
2548 * Returned when the the plugin specified by @ref oid could not be
2549 * found.
2550 *
2551 * @retval MP_STATUS_INVALID_PARAMETER
2552 * Returned if one of the polling values is outside the range
2553 * supported by the driver.
2554 *
2555 * @retval MP_STATUS_UNSUPPORTED
2556 * Returned when the implementation does not support the API
2557 *
2558 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2559 * Returned if oid does not specify any valid object type.
2560 *
2561 *******************************************************************************
2562 */
MP_SetFailbackPollingRate(MP_OID oid,MP_UINT32 pollingRate)2563 MP_STATUS MP_SetFailbackPollingRate(
2564 MP_OID oid,
2565 MP_UINT32 pollingRate)
2566 {
2567 MP_UINT32 index;
2568 MP_STATUS status;
2569
2570 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2571 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2572 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
2573 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
2574 return (status);
2575 }
2576
2577 (void) pthread_mutex_lock(&mp_lib_mutex);
2578
2579 index = oid.ownerId - 1;
2580 if (plugintable[index].hdlPlugin != NULL) {
2581 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
2582 MP_SetFailbackPollingRatePluginFn PassFunc;
2583 PassFunc = (MP_SetFailbackPollingRatePluginFn)
2584 dlsym(plugintable[index].hdlPlugin,
2585 "MP_SetFailbackPollingRatePlugin");
2586
2587 if (PassFunc != NULL) {
2588 status = PassFunc(pollingRate);
2589 } else {
2590 status = MP_STATUS_UNSUPPORTED;
2591 }
2592 } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) {
2593 MP_SetFailbackPollingRateLuFn PassFunc;
2594 PassFunc = (MP_SetFailbackPollingRateLuFn)
2595 dlsym(plugintable[index].hdlPlugin,
2596 "MP_SetFailbackPollingRateLu");
2597
2598 if (PassFunc != NULL) {
2599 status = PassFunc(oid, pollingRate);
2600 } else {
2601 status = MP_STATUS_UNSUPPORTED;
2602 }
2603 } else {
2604 status = MP_STATUS_INVALID_PARAMETER;
2605 }
2606 }
2607
2608 (void) pthread_mutex_unlock(&mp_lib_mutex);
2609 return (status);
2610 }
2611
2612 /**
2613 *******************************************************************************
2614 *
2615 * Set the probing polling rates. Setting both rates to zero disables polling.
2616 *
2617 * @param pluginOid
2618 * The object ID of either the plugin or a multipath logical unit.
2619 *
2620 * @param pollingRate
2621 * The value to be set in MP_PLUGIN_PROPERTIES current pollingRate or
2622 * MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES pollingRate.
2623 *
2624 * @return An MP_STATUS indicating if the operation was successful or if
2625 * an error occurred.
2626 *
2627 * @retval MP_STATUS_SUCCESS
2628 * Returned when the operation is successful.
2629 *
2630 * @retval MP_STATUS_OBJECT_NOT_FOUND
2631 * Returned when the the plugin specified by @ref oid could not be
2632 * found.
2633 *
2634 * @retval MP_STATUS_INVALID_PARAMETER
2635 * Returned if one of the polling values is outside the range
2636 * supported by the driver.
2637 *
2638 * @retval MP_STATUS_UNSUPPORTED
2639 * Returned when the implementation does not support the API
2640 *
2641 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2642 * Returned if oid does not specify any valid object type.
2643 *
2644 *******************************************************************************
2645 */
MP_SetProbingPollingRate(MP_OID oid,MP_UINT32 pollingRate)2646 MP_STATUS MP_SetProbingPollingRate(
2647 MP_OID oid,
2648 MP_UINT32 pollingRate)
2649 {
2650 MP_UINT32 index;
2651 MP_STATUS status;
2652
2653 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2654 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2655 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
2656 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
2657 return (status);
2658 }
2659
2660 (void) pthread_mutex_lock(&mp_lib_mutex);
2661
2662 index = oid.ownerId - 1;
2663 if (plugintable[index].hdlPlugin != NULL) {
2664 if (oid.objectType == MP_OBJECT_TYPE_PLUGIN) {
2665 MP_SetProbingPollingRatePluginFn PassFunc;
2666 PassFunc = (MP_SetProbingPollingRatePluginFn)
2667 dlsym(plugintable[index].hdlPlugin,
2668 "MP_SetProbingPollingRatePlugin");
2669
2670 if (PassFunc != NULL) {
2671 status = PassFunc(pollingRate);
2672 } else {
2673 status = MP_STATUS_UNSUPPORTED;
2674 }
2675 } else if (oid.objectType == MP_OBJECT_TYPE_MULTIPATH_LU) {
2676 MP_SetProbingPollingRateLuFn PassFunc;
2677 PassFunc = (MP_SetProbingPollingRateLuFn)
2678 dlsym(plugintable[index].hdlPlugin,
2679 "MP_SetProbingPollingRateLu");
2680
2681 if (PassFunc != NULL) {
2682 status = PassFunc(oid, pollingRate);
2683 } else {
2684 status = MP_STATUS_UNSUPPORTED;
2685 }
2686 } else {
2687 status = MP_STATUS_INVALID_PARAMETER;
2688 }
2689 }
2690
2691 (void) pthread_mutex_unlock(&mp_lib_mutex);
2692 return (status);
2693 }
2694
2695 /**
2696 *******************************************************************************
2697 *
2698 * Set proprietary properties in supported object instances.
2699 *
2700 * @param pluginOid
2701 * The object ID of MP_LOAD_BALANCE_PROPRIETARY_TYPE, MP_PLUGIN_PROPERTIES
2702 * or MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES.
2703 *
2704 * @param count
2705 * The number of valid items in pPropertyList.
2706 *
2707 * @param pPropertyList
2708 * A pointer to an array of property name/value pairs. This array must
2709 * contain the same number of elements as count.
2710 *
2711 * @return An MP_STATUS indicating if the operation was successful or if
2712 * an error occurred.
2713 *
2714 * @retval MP_STATUS_SUCCESS
2715 * Returned when the operation is successful.
2716 *
2717 * @retval MP_STATUS_OBJECT_NOT_FOUND
2718 * Returned when the the plugin specified by @ref oid could not be
2719 * found.
2720 *
2721 * @retval MP_STATUS_INVALID_PARAMETER
2722 * Returned if one of the polling values is outside the range
2723 * supported by the driver.
2724 *
2725 * @retval MP_STATUS_UNSUPPORTED
2726 * Returned when the implementation does not support the API
2727 *
2728 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2729 * Returned if oid does not specify any valid object type.
2730 *
2731 *******************************************************************************
2732 */
MP_SetProprietaryProperties(MP_OID oid,MP_UINT32 count,MP_PROPRIETARY_PROPERTY * pPropertyList)2733 MP_STATUS MP_SetProprietaryProperties(
2734 MP_OID oid,
2735 MP_UINT32 count,
2736 MP_PROPRIETARY_PROPERTY *pPropertyList)
2737 {
2738 MP_SetProprietaryPropertiesFn PassFunc;
2739 MP_UINT32 index;
2740 MP_STATUS status;
2741
2742 if (((status = validate_object(oid, MP_OBJECT_TYPE_PLUGIN,
2743 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2744 ((status = validate_object(oid, MP_OBJECT_TYPE_MULTIPATH_LU,
2745 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) &&
2746 ((status = validate_object(oid, MP_OBJECT_TYPE_PROPRIETARY_LOAD_BALANCE,
2747 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS)) {
2748 return (status);
2749 }
2750
2751 (void) pthread_mutex_lock(&mp_lib_mutex);
2752
2753 index = oid.ownerId - 1;
2754 if (plugintable[index].hdlPlugin != NULL) {
2755 PassFunc = (MP_SetProprietaryPropertiesFn)
2756 dlsym(plugintable[index].hdlPlugin,
2757 "MP_SetProprietaryProperties");
2758
2759 if (PassFunc != NULL) {
2760 status = PassFunc(oid, count, pPropertyList);
2761 } else {
2762 status = MP_STATUS_UNSUPPORTED;
2763 }
2764 } else {
2765 status = MP_STATUS_FAILED;
2766 }
2767
2768 (void) pthread_mutex_unlock(&mp_lib_mutex);
2769 return (status);
2770 }
2771
2772 /**
2773 *******************************************************************************
2774 *
2775 * Set the access state for a list of target port groups. This allows
2776 * a client to force a failover or failback to a desired set of target port
2777 * groups.
2778 *
2779 * @param luOid
2780 * The object ID of the logical unit where the command is sent.
2781 *
2782 * @param count
2783 * The number of valid items in the pTpgStateList.
2784 *
2785 * @param pTpgStateList
2786 * A pointer to an array of TPG/access-state values. This array must
2787 * contain the same number of elements as @ref count.
2788 *
2789 * @return An MP_STATUS indicating if the operation was successful or if
2790 * an error occurred.
2791 *
2792 * @retval MP_STATUS_SUCCESS
2793 * Returned when the operation is successful.
2794 *
2795 * @retval MP_STATUS_OBJECT_NOT_FOUND
2796 * Returned when the MP_MULTIPATH_LOGICAL_UNIT associated with @ref
2797 * oid could not be found.
2798 *
2799 * @retval MP_STATUS_INVALID_PARAMETER
2800 * Returned if pTpgStateList is null or if one of the TPGs referenced
2801 * in the list is not associated with the specified MP logical unit.
2802 *
2803 * @retval MP_STATUS_UNSUPPORTED
2804 * Returned when the implementation does not support the API
2805 *
2806 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2807 * Returned if oid does not specify any valid object type.
2808 *
2809 * @retval MP_STATUS_ACCESS_STATE_INVALID
2810 * Returned if the target device returns a status indicating the caller
2811 * is attempting to establish an illegal combination of access states.
2812 *
2813 * @retval MP_STATUS_FAILED
2814 * Returned if the underlying interface failed the commend for some
2815 * reason other than MP_STATUS_ACCESS_STATE_INVALID
2816 *
2817 *******************************************************************************
2818 */
MP_SetTPGAccess(MP_OID luOid,MP_UINT32 count,MP_TPG_STATE_PAIR * pTpgStateList)2819 MP_STATUS MP_SetTPGAccess(
2820 MP_OID luOid,
2821 MP_UINT32 count,
2822 MP_TPG_STATE_PAIR *pTpgStateList)
2823 {
2824 MP_SetTPGAccessFn PassFunc;
2825 MP_UINT32 index;
2826 MP_STATUS status;
2827
2828 if ((status = validate_object(luOid, MP_OBJECT_TYPE_MULTIPATH_LU,
2829 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2830 return (status);
2831 }
2832
2833 (void) pthread_mutex_lock(&mp_lib_mutex);
2834
2835 index = luOid.ownerId - 1;
2836 if (plugintable[index].hdlPlugin != NULL) {
2837 PassFunc = (MP_SetTPGAccessFn)
2838 dlsym(plugintable[index].hdlPlugin,
2839 "MP_SetTPGAccess");
2840
2841 if (PassFunc != NULL) {
2842 status = PassFunc(luOid, count, pTpgStateList);
2843 } else {
2844 status = MP_STATUS_UNSUPPORTED;
2845 }
2846 } else {
2847 status = MP_STATUS_FAILED;
2848 }
2849
2850 (void) pthread_mutex_unlock(&mp_lib_mutex);
2851 return (status);
2852 }
2853
2854 /**
2855 *******************************************************************************
2856 *
2857 * Registers a client function that is to be called
2858 * whenever the property of an an object changes.
2859 *
2860 * @param pClientFn,
2861 * A pointer to an MP_OBJECT_PROPERTY_FN function defined by the
2862 * client. On successful return this function will be called to
2863 * inform the client of objects that have had one or more properties
2864 * change.
2865 *
2866 * @param objectType
2867 * The type of object the client wishes to deregister for
2868 * property change callbacks. If null, then all objects types are
2869 * deregistered.
2870 *
2871 * @param pCallerData
2872 * A pointer that is passed to the callback routine with each event.
2873 * This may be used by the caller to correlate the event to source of
2874 * the registration.
2875 *
2876 * @return An MP_STATUS indicating if the operation was successful or if
2877 * an error occurred.
2878 *
2879 * @retval MP_STATUS_SUCCESS
2880 * Returned when the operation is successful.
2881 *
2882 * @retval MP_STATUS_INVALID_PARAMETER
2883 * Returned if pClientFn is NULL or specifies a memory area
2884 * that is not executable.
2885 *
2886 * @retval MP_STATUS_FN_REPLACED
2887 * Returned when an existing client function is replaced with the one
2888 * specified in pClientFn.
2889 *
2890 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2891 * Returned if oid does not specify any valid object type.
2892 *
2893 *******************************************************************************
2894 */
MP_RegisterForObjectPropertyChanges(MP_OBJECT_PROPERTY_FN pClientFn,MP_OBJECT_TYPE objectType,void * pCallerData,MP_OID pluginOid)2895 MP_STATUS MP_RegisterForObjectPropertyChanges(
2896 MP_OBJECT_PROPERTY_FN pClientFn,
2897 MP_OBJECT_TYPE objectType,
2898 void *pCallerData,
2899 MP_OID pluginOid)
2900 {
2901 MP_RegisterForObjectPropertyChangesPluginFn PassFunc;
2902 MP_UINT32 i;
2903 MP_UINT32 index;
2904 MP_STATUS status;
2905
2906 if (pClientFn == NULL) {
2907 return (MP_STATUS_INVALID_PARAMETER);
2908 }
2909
2910 if (objectType > MP_OBJECT_TYPE_MAX) {
2911 return (MP_STATUS_INVALID_OBJECT_TYPE);
2912 }
2913
2914 if (!(is_zero_oid(pluginOid))) {
2915 if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN,
2916 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
2917 return (status);
2918 }
2919 }
2920
2921 (void) pthread_mutex_lock(&mp_lib_mutex);
2922
2923 if (is_zero_oid(pluginOid)) {
2924 for (i = 0; i < number_of_plugins; i++) {
2925 if (plugintable[i].hdlPlugin != NULL) {
2926 PassFunc = (MP_RegisterForObjectPropertyChangesPluginFn)
2927 dlsym(plugintable[i].hdlPlugin,
2928 "MP_RegisterForObjectPropertyChangesPlugin");
2929 }
2930
2931 if (PassFunc != NULL) {
2932 status =
2933 PassFunc(pClientFn, objectType, pCallerData);
2934 /* ignore an error and continue */
2935 }
2936 }
2937 } else {
2938 index = pluginOid.ownerId - 1;
2939 if (plugintable[index].hdlPlugin != NULL) {
2940 PassFunc = (MP_RegisterForObjectPropertyChangesPluginFn)
2941 dlsym(plugintable[index].hdlPlugin,
2942 "MP_RegisterForObjectPropertyChangesPlugin");
2943 }
2944
2945 if (PassFunc != NULL) {
2946 status = PassFunc(pClientFn, objectType, pCallerData);
2947 }
2948 }
2949 (void) pthread_mutex_unlock(&mp_lib_mutex);
2950 return (status);
2951 }
2952
2953 /**
2954 *******************************************************************************
2955 *
2956 * Deregisters a previously registered client function that is to be invoked
2957 * whenever an object's property changes.
2958 *
2959 * @param pClientFn,
2960 * A pointer to an MP_OBJECT_PROPERTY_FN function defined by the
2961 * client that was previously registered using
2962 * the MP_RegisterForObjectPropertyChanges API. On successful return
2963 * this function will no longer be called to inform the client of
2964 * object property changes.
2965 *
2966 * @param objectType
2967 * The type of object the client wishes to deregister for
2968 * property change callbacks. If null, then all objects types are
2969 * deregistered.
2970 *
2971 * @return An MP_STATUS indicating if the operation was successful or if
2972 * an error occurred.
2973 *
2974 * @retval MP_STATUS_SUCCESS
2975 * Returned when the operation is successful.
2976 *
2977 * @retval MP_STATUS_INVALID_PARAMETER
2978 * Returned if pClientFn is NULL or specifies a memory area
2979 * that is not executable.
2980 *
2981 * @retval MP_STATUS_UNKNOWN_FN
2982 * Returned if pClientFn is not the same as the previously registered
2983 * function.
2984 *
2985 * @retval MP_STATUS_INVALID_OBJECT_TYPE
2986 * Returned if oid does not specify any valid object type.
2987 *
2988 * @retval MP_STATUS_FAILED
2989 * Returned if pClientFn deregistration is not possible at this time.
2990 *
2991 *******************************************************************************
2992 */
MP_DeregisterForObjectPropertyChanges(MP_OBJECT_PROPERTY_FN pClientFn,MP_OBJECT_TYPE objectType,MP_OID pluginOid)2993 MP_STATUS MP_DeregisterForObjectPropertyChanges(
2994 MP_OBJECT_PROPERTY_FN pClientFn,
2995 MP_OBJECT_TYPE objectType,
2996 MP_OID pluginOid)
2997 {
2998 MP_DeregisterForObjectPropertyChangesPluginFn PassFunc;
2999 MP_UINT32 i;
3000 MP_UINT32 index;
3001 MP_STATUS status;
3002
3003 if (pClientFn == NULL) {
3004 return (MP_STATUS_INVALID_PARAMETER);
3005 }
3006
3007 if (objectType > MP_OBJECT_TYPE_MAX) {
3008 return (MP_STATUS_INVALID_OBJECT_TYPE);
3009 }
3010
3011 if (!(is_zero_oid(pluginOid))) {
3012 if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN,
3013 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
3014 return (status);
3015 }
3016 }
3017
3018 (void) pthread_mutex_lock(&mp_lib_mutex);
3019
3020 if (is_zero_oid(pluginOid)) {
3021 for (i = 0; i < number_of_plugins; i++) {
3022 if (plugintable[i].hdlPlugin != NULL) {
3023 PassFunc = (MP_DeregisterForObjectPropertyChangesPluginFn)
3024 dlsym(plugintable[i].hdlPlugin,
3025 "MP_DeregisterForObjectPropertyChangesPlugin");
3026 }
3027
3028 if (PassFunc != NULL) {
3029 status = PassFunc(pClientFn, objectType);
3030 }
3031 }
3032 } else {
3033 index = pluginOid.ownerId - 1;
3034 if (plugintable[index].hdlPlugin != NULL) {
3035 PassFunc = (MP_DeregisterForObjectPropertyChangesPluginFn)
3036 dlsym(plugintable[index].hdlPlugin,
3037 "MP_DeregisterForObjectPropertyChangesPlugin");
3038 }
3039
3040 if (PassFunc != NULL) {
3041 status = PassFunc(pClientFn, objectType);
3042 }
3043 }
3044 (void) pthread_mutex_unlock(&mp_lib_mutex);
3045 return (status);
3046 }
3047
3048 /**
3049 *******************************************************************************
3050 *
3051 * Registers a client function that is to be called
3052 * whenever a high level object appears or disappears.
3053 *
3054 * @param pClientFn,
3055 * A pointer to an MP_OBJECT_VISIBILITY_FN function defined by the
3056 * client. On successful return this function will be called to
3057 * inform the client of objects whose visibility has changed.
3058 *
3059 * @param objectType
3060 * The type of object the client wishes to deregister for
3061 * property change callbacks. If null, then all objects types are
3062 * deregistered.
3063 *
3064 * @param pCallerData
3065 * A pointer that is passed to the callback routine with each event.
3066 * This may be used by the caller to correlate the event to source of
3067 * the registration.
3068 *
3069 * @return An MP_STATUS indicating if the operation was successful or if
3070 * an error occurred.
3071 *
3072 * @retval MP_STATUS_SUCCESS
3073 * Returned when the operation is successful.
3074 *
3075 * @retval MP_STATUS_INVALID_PARAMETER
3076 * Returned if pClientFn is NULL or specifies a memory area
3077 * that is not executable.
3078 *
3079 * @retval MP_STATUS_FN_REPLACED
3080 * Returned when an existing client function is replaced with the one
3081 * specified in pClientFn.
3082 *
3083 * @retval MP_STATUS_INVALID_OBJECT_TYPE
3084 * Returned if objectType does not specify any valid object type.
3085 *
3086 *******************************************************************************
3087 */
MP_RegisterForObjectVisibilityChanges(MP_OBJECT_VISIBILITY_FN pClientFn,MP_OBJECT_TYPE objectType,void * pCallerData,MP_OID pluginOid)3088 MP_STATUS MP_RegisterForObjectVisibilityChanges(
3089 MP_OBJECT_VISIBILITY_FN pClientFn,
3090 MP_OBJECT_TYPE objectType,
3091 void *pCallerData,
3092 MP_OID pluginOid)
3093 {
3094 MP_RegisterForObjectVisibilityChangesPluginFn PassFunc;
3095 MP_UINT32 i;
3096 MP_UINT32 index;
3097 MP_STATUS status;
3098
3099 if (pClientFn == NULL) {
3100 return (MP_STATUS_INVALID_PARAMETER);
3101 }
3102
3103 if (objectType > MP_OBJECT_TYPE_MAX) {
3104 return (MP_STATUS_INVALID_OBJECT_TYPE);
3105 }
3106
3107 if (!(is_zero_oid(pluginOid))) {
3108 if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN,
3109 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
3110 return (status);
3111 }
3112 }
3113
3114 (void) pthread_mutex_lock(&mp_lib_mutex);
3115
3116 if (is_zero_oid(pluginOid)) {
3117 for (i = 0; i < number_of_plugins; i++) {
3118 if (plugintable[i].hdlPlugin != NULL) {
3119 PassFunc = (MP_RegisterForObjectVisibilityChangesPluginFn)
3120 dlsym(plugintable[i].hdlPlugin,
3121 "MP_RegisterForObjectVisibilityChangesPlugin");
3122 }
3123
3124 if (PassFunc != NULL) {
3125 status = PassFunc(pClientFn, objectType, pCallerData);
3126 /* ignore an error and continue. */
3127 }
3128 }
3129 } else {
3130 index = pluginOid.ownerId - 1;
3131 if (plugintable[index].hdlPlugin != NULL) {
3132 PassFunc = (MP_RegisterForObjectVisibilityChangesPluginFn)
3133 dlsym(plugintable[index].hdlPlugin,
3134 "MP_RegisterForObjectVisibilityChangesPlugin");
3135 }
3136
3137 if (PassFunc != NULL) {
3138 status = PassFunc(pClientFn, objectType, pCallerData);
3139 }
3140 }
3141 (void) pthread_mutex_unlock(&mp_lib_mutex);
3142 return (status);
3143
3144 }
3145
3146 /**
3147 *******************************************************************************
3148 *
3149 * Deregisters a previously registered client function that is to be invoked
3150 * whenever a high level object appears or disappears.
3151 *
3152 * @param pClientFn,
3153 * A pointer to an MP_OBJECT_VISIBILITY_FN function defined by the
3154 * client that was previously registered using
3155 * the MP_RegisterForObjectVisibilityChanges API. On successful return
3156 * this function will no longer be called to inform the client of
3157 * object property changes.
3158 *
3159 * @param objectType
3160 * The type of object the client wishes to deregister for visibility
3161 * change callbacks. If null, then all objects types are
3162 * deregistered.
3163 *
3164 * @return An MP_STATUS indicating if the operation was successful or if
3165 * an error occurred.
3166 *
3167 * @retval MP_STATUS_SUCCESS
3168 * Returned when the operation is successful.
3169 *
3170 * @retval MP_STATUS_INVALID_PARAMETER
3171 * Returned if pClientFn is NULL or specifies a memory area
3172 * that is not executable.
3173 *
3174 * @retval MP_STATUS_UNKNOWN_FN
3175 * Returned if pClientFn is not the same as the previously registered
3176 * function.
3177 *
3178 * @retval MP_STATUS_INVALID_OBJECT_TYPE
3179 * Returned if objectType does not specify any valid object type.
3180 *
3181 * @retval MP_STATUS_FAILED
3182 * Returned if pClientFn deregistration is not possible at this time.
3183 *
3184 *******************************************************************************
3185 */
MP_DeregisterForObjectVisibilityChanges(MP_OBJECT_VISIBILITY_FN pClientFn,MP_OBJECT_TYPE objectType,MP_OID pluginOid)3186 MP_STATUS MP_DeregisterForObjectVisibilityChanges(
3187 MP_OBJECT_VISIBILITY_FN pClientFn,
3188 MP_OBJECT_TYPE objectType,
3189 MP_OID pluginOid)
3190 {
3191 MP_DeregisterForObjectVisibilityChangesPluginFn PassFunc;
3192 MP_UINT32 i;
3193 MP_UINT32 index;
3194 MP_STATUS status;
3195
3196 if (pClientFn == NULL) {
3197 return (MP_STATUS_INVALID_PARAMETER);
3198 }
3199
3200 if (objectType > MP_OBJECT_TYPE_MAX) {
3201 return (MP_STATUS_INVALID_OBJECT_TYPE);
3202 }
3203
3204 if (!(is_zero_oid(pluginOid))) {
3205 if ((status = validate_object(pluginOid, MP_OBJECT_TYPE_PLUGIN,
3206 MP_OBJECT_TYPE_MATCH)) != MP_STATUS_SUCCESS) {
3207 return (status);
3208 }
3209 }
3210
3211 (void) pthread_mutex_lock(&mp_lib_mutex);
3212
3213 if (is_zero_oid(pluginOid)) {
3214 for (i = 0; i < number_of_plugins; i++) {
3215 if (plugintable[i].hdlPlugin != NULL) {
3216 PassFunc = (MP_DeregisterForObjectVisibilityChangesPluginFn)
3217 dlsym(plugintable[i].hdlPlugin,
3218 "MP_DeregisterForObjectVisibilityChangesPlugin");
3219 if (PassFunc != NULL) {
3220 status = PassFunc(pClientFn, objectType);
3221 }
3222 }
3223 }
3224 } else {
3225 index = pluginOid.ownerId - 1;
3226 if (plugintable[index].hdlPlugin != NULL) {
3227 PassFunc = (MP_DeregisterForObjectVisibilityChangesPluginFn)
3228 dlsym(plugintable[index].hdlPlugin,
3229 "MP_DeregisterForObjectVisibilityChangesPlugin");
3230 if (PassFunc != NULL) {
3231 status = PassFunc(pClientFn, objectType);
3232 }
3233 }
3234 }
3235
3236 (void) pthread_mutex_unlock(&mp_lib_mutex);
3237 return (status);
3238 }
3239
3240 /**
3241 *******************************************************************************
3242 *
3243 * Compare two Oids for equality to see whether they refer to the same object.
3244 *
3245 * @param oid1
3246 * Oid to compare.
3247 *
3248 * @param oid2
3249 * Oid to compare.
3250 *
3251 * @return An MP_STATUS indicating if the operation was successful or if
3252 * an error occurred.
3253 *
3254 * @retval MP_STATUS_SUCCESS
3255 * Returned when the two Oids do refer to the same object.
3256 *
3257 * @retval MP_STATUS_FAILED
3258 * Returned if the Oids don't compare.
3259 *
3260 *******************************************************************************
3261 */
MP_CompareOIDs(MP_OID oid1,MP_OID oid2)3262 MP_STATUS MP_CompareOIDs(
3263 MP_OID oid1,
3264 MP_OID oid2)
3265 {
3266 if ((oid1.objectType == oid2.objectType) && (oid1.ownerId == oid2.ownerId)
3267 && (oid1.objectSequenceNumber == oid2.objectSequenceNumber)) {
3268 return (MP_STATUS_SUCCESS);
3269 } else {
3270 return (MP_STATUS_FAILED);
3271 }
3272 }
3273
3274 /**
3275 *******************************************************************************
3276 *
3277 * Frees memory returned by an MP API.
3278 *
3279 * @param pOidList
3280 * A pointer to the memory returned by an MP API. On successful
3281 return, the allocated memory is freed.
3282 *
3283 * @return An MP_STATUS indicating if the operation was successful or if
3284 * an error occurred.
3285 *
3286 * @retval MP_STATUS_SUCCESS
3287 * Returned when pPluginId is deregistered successfully.
3288 *
3289 * @retval MP_STATUS_INVALID_PARAMETER
3290 * Returned if pMemory is NULL or specifies a memory area to which
3291 * data cannot be written.
3292 *
3293 *******************************************************************************
3294 */
MP_FreeOidList(MP_OID_LIST * pOidList)3295 MP_STATUS MP_FreeOidList(MP_OID_LIST *pOidList)
3296 {
3297 if (pOidList == NULL) {
3298 return (MP_STATUS_INVALID_PARAMETER);
3299 }
3300
3301 free(pOidList);
3302
3303 return (MP_STATUS_SUCCESS);
3304 }
3305
3306 static MP_CHAR *HDR =
3307 "#\n"
3308 "# This file contains names and references to MP API plugin libraries\n"
3309 "#\n"
3310 "# Do NOT manually edit this file\n"
3311 "#\n"
3312 "# Format:\n"
3313 "#\n"
3314 "# <library ID> <library pathname>\n"
3315 "#\n";
3316
3317 #define CLEANUP_N_RET(fd, ret) \
3318 if (lock_register(fd, F_SETLK, F_UNLCK, 0, SEEK_SET, 0) < 0) { \
3319 close(fd); \
3320 return (MP_STATUS_FAILED); \
3321 } \
3322 close(fd); \
3323 return (ret)
3324
3325 /*
3326 * This function sets an advisory lock on the file pointed to by the argument
3327 * fd, which is a file descriptor. The lock is set using fcntl() which uses
3328 * flock structure.
3329 */
3330 static int
lock_register(int fd,int cmd,int type,off_t offset,int whence,off_t len)3331 lock_register(int fd, int cmd, int type, off_t offset, int whence, off_t len)
3332 {
3333 struct flock lock;
3334
3335 lock.l_type = type;
3336 lock.l_start = offset;
3337 lock.l_whence = whence;
3338 lock.l_len = len;
3339
3340 return (fcntl(fd, cmd, &lock));
3341 }
3342
3343 /*
3344 * This function searches for "srch_str" (of length "slen") in "buf" (of length
3345 * "buflen"). If it is not found, "write_offset" has the offset in "buf" where
3346 * "srch_str" would have to be added in "buf". If "srch_str" is found in "buf",
3347 * "write_offset" has its offset in "buf"
3348 *
3349 * ARGUMENTS :
3350 * buf - buffer to search in
3351 * buflen - length of buffer
3352 * srch_id - id to search
3353 * id_len - length of srch_id
3354 * write_offset - Set in function on exit
3355 * - It is the offset in buf where srch_str is or should be
3356 * bytes_left - Set in function on exit
3357 * - It is the # of bytes left beyond write_offset in buf
3358 * RETURN VALUES :
3359 * Zero - "srch_id" found in "buf"... "write_offset" has offset in "buf"
3360 * != 0 - "srch_str" NOT found in "buf" ... "write_offset" points to the end of
3361 * "buf".
3362 */
3363 static int
search_line(MP_CHAR * buf,size_t buflen,MP_CHAR * srch_id,size_t id_len,int * write_offset,int * bytes_left)3364 search_line(MP_CHAR *buf, size_t buflen, MP_CHAR *srch_id, size_t id_len,
3365 int *write_offset, int *bytes_left)
3366 {
3367 int retval, sizeof_conf_hdr = strlen(HDR);
3368 MP_CHAR *sol; /* Pointer to Start-Of-Line */
3369 MP_CHAR *cur_pos; /* current position */
3370
3371 *bytes_left = buflen;
3372 *write_offset = 0;
3373
3374 if (buf == NULL || buflen <= 0)
3375 return (-1);
3376
3377 if (srch_id == NULL || id_len <= 0)
3378 return (0);
3379
3380 sol = cur_pos = buf;
3381
3382 /*
3383 * mp conf file should not be edited but takes care of
3384 * any extra white space when parsing the line.
3385 *
3386 * The line should have id + delimiter + name + newline.
3387 */
3388 while (*bytes_left >= (id_len + 3)) {
3389 /* skip leading blank or space. */
3390 while ((*cur_pos == ' ') || (*cur_pos == '\t')) {
3391 cur_pos++;
3392 }
3393
3394 if (strncmp(cur_pos, srch_id, id_len) == 0) {
3395 /* id matched. */
3396 cur_pos += id_len;
3397
3398 while (*cur_pos != '\n') {
3399 cur_pos++;
3400 }
3401 *write_offset = (sol - buf);
3402 *bytes_left = buflen - ((cur_pos + 1) - buf);
3403 return (0);
3404 } else {
3405 /* move to the next line */
3406 while (*cur_pos != '\n') {
3407 cur_pos++;
3408 }
3409 *bytes_left = buflen - ((cur_pos + 1) - buf);
3410 }
3411 sol = cur_pos = cur_pos + 1;
3412 }
3413
3414 /* Given strings are not found. */
3415 *write_offset = buflen;
3416 return (-1);
3417 }
3418
3419 /**
3420 *******************************************************************************
3421 *
3422 * Registers a plugin with common library. The implementation of this routine
3423 * is based on configuration file /etc/mpapi.conf that contains a list of
3424 * plugin libraries.
3425 *
3426 * @param pPluginId
3427 * A pointer to the key name shall be the reversed domain name of
3428 * the vendor followed by followed by the vendor specific name for
3429 * the plugin that uniquely identifies the plugin. Should be NULL
3430 * terminated.
3431 *
3432 * @param pFileName
3433 * The full path to the plugin library.
3434 * Should be NULL terminated.
3435 *
3436 * @return An MP_STATUS indicating if the operation was successful or if
3437 * an error occurred.
3438 *
3439 * @retval MP_STATUS_SUCCESS
3440 * Returned when pPluginId is deregistered successfully.
3441 *
3442 * @retval MP_STATUS_INVALID_PARAMETER
3443 * Returned if pPluginId is NULL or specifies a memory area that
3444 * is not executable.
3445 *
3446 * @retval MP_STATUS_FAILED
3447 * Returned if pClientFn deregistration is not possible at this time.
3448 *
3449 *******************************************************************************
3450 */
MP_RegisterPlugin(MP_WCHAR * pPluginId,char * pFileName)3451 MP_STATUS MP_RegisterPlugin(
3452 MP_WCHAR *pPluginId,
3453 char *pFileName)
3454 {
3455 int mpconf, bytes_left, write_offset;
3456 MP_CHAR fullline[MAX_LINE_SIZE]; /* Full line to add to mpapi.conf */
3457 MP_CHAR *mpconf_buf;
3458 MP_CHAR pluginid[MAX_NAME_SIZE];
3459 char systemPath[MAX_NAME_SIZE], mpConfFilePath[MAX_NAME_SIZE];
3460 MP_UINT32 new_file_flag = 0;
3461 MP_UINT32 sizeof_conf_hdr = strlen(HDR);
3462 struct stat stbuf;
3463
3464 if ((pPluginId == NULL) || (pFileName == NULL)) {
3465 return (MP_STATUS_INVALID_PARAMETER);
3466 }
3467
3468 if (stat(pFileName, &stbuf) != 0) {
3469 return (MP_STATUS_INVALID_PARAMETER);
3470 }
3471
3472 if (wcstombs(pluginid, pPluginId, MAX_NAME_SIZE) != wcslen(pPluginId)) {
3473 return (MP_STATUS_INVALID_PARAMETER);
3474 }
3475
3476 *fullline = '\0';
3477 strncpy(fullline, pluginid, MAX_NAME_SIZE);
3478 /* add tab */
3479 strncat(fullline, "\t", MAX_LINE_SIZE - strlen(pluginid));
3480 strncat(fullline, pFileName, MAX_LINE_SIZE - strlen(pluginid) - 1);
3481 /* add a new line. */
3482 strncat(fullline, "\n",
3483 MAX_LINE_SIZE - strlen(pluginid) - strlen(pFileName) -1);
3484
3485 /* Open configuration file from known location */
3486 strncpy(mpConfFilePath, "/etc/mpapi.conf", MAX_NAME_SIZE);
3487
3488 if ((chmod(mpConfFilePath, S_IRUSR|S_IRGRP|S_IROTH) == -1) &&
3489 (errno == ENOENT)) {
3490 new_file_flag = 1;
3491 }
3492
3493 if ((mpconf = open(mpConfFilePath, O_RDWR | O_CREAT)) == -1) {
3494 return (MP_STATUS_FAILED);
3495 }
3496
3497 if (fchmod(mpconf, S_IRUSR | S_IRGRP | S_IROTH) < 0) {
3498 close(mpconf);
3499 return (MP_STATUS_FAILED);
3500 }
3501
3502 if (lock_register(mpconf, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0) < 0) {
3503 close(mpconf);
3504 return (MP_STATUS_FAILED);
3505 }
3506
3507 if (fstat(mpconf, &stbuf) == -1) {
3508 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3509 }
3510
3511 if ((new_file_flag) || (stbuf.st_size == 0)) {
3512 if (write(mpconf, HDR, sizeof_conf_hdr) !=
3513 sizeof_conf_hdr) {
3514 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3515 }
3516
3517 if (pwrite(mpconf, fullline, strlen(fullline),
3518 sizeof_conf_hdr) !=
3519 strlen(fullline)) {
3520 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3521 }
3522 CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS);
3523 }
3524
3525 if ((mpconf_buf = (MP_CHAR *)mmap(0, stbuf.st_size,
3526 PROT_READ | PROT_WRITE,
3527 MAP_SHARED, mpconf, 0)) == MAP_FAILED) {
3528 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3529 }
3530
3531 if (search_line(mpconf_buf, stbuf.st_size,
3532 pluginid, strlen(pluginid), &write_offset, &bytes_left) == 0) {
3533 /* found a match. */
3534 munmap((void *)mpconf_buf, stbuf.st_size);
3535 CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS);
3536 } else {
3537 munmap((void *)mpconf_buf, stbuf.st_size);
3538 /* append the fullline to the mpconf. */
3539 if (pwrite(mpconf, fullline, strlen(fullline),
3540 write_offset) !=
3541 strlen(fullline)) {
3542 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3543 } else {
3544 CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS);
3545 }
3546 }
3547 }
3548
3549 /**
3550 *******************************************************************************
3551 *
3552 * Deregisters a plugin from the common library. This routine is based on
3553 * configuration file /etc/mpapi.conf that contains a list of plugin libraries.
3554 *
3555 * @param pPluginId
3556 * A pointer to a Plugin ID previously registered using
3557 * the MP_RegisterPlugin API..
3558 *
3559 * @return An MP_STATUS indicating if the operation was successful or if
3560 * an error occurred.
3561 *
3562 * @retval MP_STATUS_SUCCESS
3563 * Returned when pPluginId is deregistered successfully.
3564 *
3565 * @retval MP_STATUS_INVALID_PARAMETER
3566 * Returned if pPluginId is NULL or specifies a memory area that
3567 * is not executable.
3568 *
3569 * @retval MP_STATUS_FAILED
3570 * Returned if pClientFn deregistration is not possible at this time.
3571 *
3572 *******************************************************************************
3573 */
MP_DeregisterPlugin(MP_WCHAR * pPluginId)3574 MP_STATUS MP_DeregisterPlugin(
3575 MP_WCHAR *pPluginId)
3576 {
3577 int mpconf, tmp_mpconf, bytes_left, write_offset;
3578 char systemPath[MAX_NAME_SIZE], mpConfFilePath[MAX_NAME_SIZE],
3579 tmp_mpConfFilePath[MAX_NAME_SIZE + sizeof(pid_t)];
3580 MP_CHAR pluginid[MAX_NAME_SIZE];
3581 MP_CHAR *mpconf_buf;
3582 MP_UINT32 sizeof_conf_hdr = strlen(HDR);
3583 struct stat stbuf;
3584
3585 if (pPluginId == NULL) {
3586 return (MP_STATUS_INVALID_PARAMETER);
3587 }
3588
3589 if (wcstombs(pluginid, pPluginId, MAX_NAME_SIZE) != wcslen(pPluginId)) {
3590 return (MP_STATUS_INVALID_PARAMETER);
3591 }
3592
3593 /* Open configuration file from known location */
3594 strncpy(mpConfFilePath, "/etc/mpapi.conf", MAX_NAME_SIZE);
3595
3596 if ((chmod(mpConfFilePath, S_IRUSR|S_IRGRP|S_IROTH) == -1) &&
3597 (errno == ENOENT)) {
3598 /* no file found */
3599 return (MP_STATUS_UNKNOWN_FN);
3600 }
3601
3602 if ((mpconf = open(mpConfFilePath, O_RDWR)) == -1) {
3603 return (MP_STATUS_FAILED);
3604 }
3605
3606 if (fchmod(mpconf, S_IRUSR | S_IRGRP | S_IROTH) < 0) {
3607 close(mpconf);
3608 return (MP_STATUS_FAILED);
3609 }
3610
3611 if (lock_register(mpconf, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0) < 0) {
3612 close(mpconf);
3613 return (MP_STATUS_FAILED);
3614 }
3615
3616 if (fstat(mpconf, &stbuf) == -1) {
3617 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3618 }
3619
3620 if (stbuf.st_size == 0) {
3621 CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS);
3622 }
3623
3624 if ((mpconf_buf = (MP_CHAR *)mmap(0, stbuf.st_size,
3625 PROT_READ | PROT_WRITE,
3626 MAP_SHARED, mpconf, 0)) == MAP_FAILED) {
3627 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3628 }
3629
3630 if (search_line(mpconf_buf, stbuf.st_size, pluginid, strlen(pluginid),
3631 &write_offset, &bytes_left) != 0) {
3632 munmap((void *)mpconf_buf, stbuf.st_size);
3633 CLEANUP_N_RET(mpconf, MP_STATUS_UNKNOWN_FN);
3634 } else {
3635 /*
3636 * found a match.
3637 * construct temp file name using pid.
3638 */
3639 (void) snprintf(tmp_mpConfFilePath, MAX_NAME_SIZE,
3640 "%s%ld", "/etc/mpapi.conf", getpid());
3641
3642 if ((tmp_mpconf = open(tmp_mpConfFilePath,
3643 O_RDWR|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR)) < 0) {
3644 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3645 }
3646
3647 if (write(tmp_mpconf, mpconf_buf, write_offset) != write_offset) {
3648 close(tmp_mpconf);
3649 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3650 }
3651
3652 if (pwrite(tmp_mpconf, mpconf_buf + (stbuf.st_size - bytes_left),
3653 bytes_left, write_offset) != bytes_left) {
3654 close(tmp_mpconf);
3655 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3656 }
3657
3658 close(tmp_mpconf);
3659 munmap((void *)mpconf_buf, stbuf.st_size);
3660
3661 /* rename temp file to mpConfFile before unlock and close. */
3662 if (rename(tmp_mpConfFilePath, mpConfFilePath) != 0) {
3663 CLEANUP_N_RET(mpconf, MP_STATUS_FAILED);
3664 } else {
3665 CLEANUP_N_RET(mpconf, MP_STATUS_SUCCESS);
3666 }
3667 }
3668 }
3669