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