1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <unistd.h>
30 #include <netdb.h>
31 #include <errno.h>
32 
33 #include "util.h"
34 #include "cimKeys.h"
35 #include "providerNames.h"
36 #include "messageStrings.h"
37 #include "drive_descriptors.h"
38 #include "ctrl_descriptors.h"
39 #include "Solaris_MPXIOInterface.h"
40 
41 
42 #define	MPXIO_GETINSTANCE		"MPXIO_INTERFACE,GET_INSTANCE"
43 #define	MPXIO_ENUMINSTANCES		"MPXIO_INTERFACE,ENUM_INSTANCES"
44 #define	MPXIO_ENUMINSTANCENAMES		"MPXIO_INTERFACE,ENUM_INSTANCENAMES"
45 #define	MPXIO_CREATEINSTANCE		"MPXIO_INTERFACE,CREATE_INSTANCE"
46 #define	MPXIO_DELETEINSTANCE		"MPXIO_INTERFACE,DELETE_INSTANCE"
47 #define	MPXIO_SETINSTANCE		"MPXIO_INTERFACE,SET_INSTANCE"
48 #define	MPXIO_GETPROPERTY		"MPXIO_INTERFACE,GET_PROPERTY"
49 #define	MPXIO_SETPROPERTY		"MPXIO_INTERFACE,SET_PROPERTY"
50 #define	MPXIO_INVOKEMETHOD		"MPXIO_INTERFACE,INVOKE_METHOD"
51 #define	MPXIO_EXECQUERY			"MPXIO_INTERFACE,EXEC_QUERY"
52 #define	MPXIO_ASSOCIATORS		"MPXIO_INTERFACE,ASSOCIATORS"
53 #define	MPXIO_ASSOCIATORNAMES		"MPXIO_INTERFACE,ASSOCIATOR_NAMES"
54 #define	MPXIO_REFERENCES		"MPXIO_INTERFACE,REFERENCES"
55 #define	MPXIO_REFERENCENAMES		"MPXIO_INTERFACE,REFERENCE_NAMES"
56 
57 static
58 CCIMInstanceList *
59 mpxioIntAssocToInstList(CCIMObjectPath *pObjectName, cimchar *pObjectNameRole,
60 	CCIMObjectPathList *objList, cimchar *objRole, int *error);
61 
62 static
63 CCIMInstance  *
64 mpxioIntAssocToInst(CCIMObjectPath *obj1, cimchar *obj1Role,
65 	CCIMObjectPath *obj2, cimchar *obj2Role, int *error);
66 
67 /*
68  * Solaris_MPXIOInterface provider
69  *
70  * It is important to note that all memory allocated by these functions
71  * and passed to the CIMOM, is freed by the door process prior to
72  * sending a copy of the data to the CIMOM.
73  */
74 
75 /*
76  * Name: cp_getInstance_Solaris_MPXIOInterface
77  *
78  * Description: Returns an instance which matches the passed in object path
79  * if found.
80  *
81  * Parameters:
82  *	pOP - An CCIMObjectPath * which contains the information on
83  *	the class for which to find the instance.
84  * Returns:
85  *	CCIMInstance * if matched instance is found. Otherwise, NULL.
86  */
87 
88 CCIMInstance*
cp_getInstance_Solaris_MPXIOInterface(CCIMObjectPath * pOP)89 cp_getInstance_Solaris_MPXIOInterface(CCIMObjectPath* pOP)
90 {
91 	CCIMInstance* 		inst = NULL;
92 	CCIMPropertyList* 	pCurPropList;
93 	CCIMObjectPath		*antOp = NULL;
94 	CCIMObjectPath		*depOp = NULL;
95 	dm_descriptor_t		d_descriptor;
96 	dm_descriptor_t		c_descriptor;
97 	char			*name;
98 	int			error;
99 
100 	if (pOP == NULL ||
101 		((pCurPropList = pOP->mKeyProperties) == NULL)) {
102 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_INVALID_PARAMETER,
103 		NULL, NULL, &error);
104 	    return ((CCIMInstance *)NULL);
105 	}
106 
107 	antOp = (CCIMObjectPath *)util_getKeyValue(
108 		pCurPropList, reference, ANTECEDENT, &error);
109 
110 	if (error == 0) {
111 	    depOp = (CCIMObjectPath *)util_getKeyValue(
112 		pCurPropList, reference, DEPENDENT, &error);
113 	}
114 
115 	if (error != 0) {
116 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
117 		NULL, &error);
118 	    return ((CCIMInstance *)NULL);
119 	}
120 	/*
121 	 * Now, get the name of the antecedent from the object path.
122 	 */
123 
124 	if (((pCurPropList = antOp->mKeyProperties) == NULL) ||
125 	    ((pCurPropList = depOp->mKeyProperties) == NULL)) {
126 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
127 		NULL, &error);
128 	    return ((CCIMInstance *)NULL);
129 	}
130 
131 	pCurPropList = antOp->mKeyProperties;
132 	name = (cimchar *)util_getKeyValue(pCurPropList, string,
133 	    DEVICEID, &error);
134 	if (error != 0) {
135 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
136 		NULL, &error);
137 	    return ((CCIMInstance *)NULL);
138 	}
139 	/*
140 	 * The only reason it is needed to get the descriptor for these
141 	 * two devices is to verify that they still exist and are valid.
142 	 * If they are not found, then getting the instance for this
143 	 * association as passed in by the client is not possible.
144 	 */
145 	c_descriptor = dm_get_descriptor_by_name(DM_CONTROLLER, name,
146 	    &error);
147 	/*
148 	 * Not found. Return a null instance.
149 	 */
150 	if (error == ENODEV || c_descriptor == NULL) {
151 	    return ((CCIMInstance *)NULL);
152 	}
153 	if (error != 0) {
154 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_FAILED,
155 		DM_GET_DESC_BYNAME_FAILURE, NULL, &error);
156 	    return ((CCIMInstance *)NULL);
157 	}
158 	dm_free_descriptor(c_descriptor);
159 
160 	pCurPropList = depOp->mKeyProperties;
161 	name = (cimchar *)util_getKeyValue(pCurPropList, string,
162 	    DEVICEID, &error);
163 	if (error != 0) {
164 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_INVALID_PARAMETER,
165 		NULL, NULL, &error);
166 	    return ((CCIMInstance *)NULL);
167 	}
168 
169 	d_descriptor = dm_get_descriptor_by_name(DM_DRIVE, name, &error);
170 
171 	/*
172 	 * Not found. Return a null instance.
173 	 */
174 
175 	if (error == ENODEV || d_descriptor == NULL) {
176 	    return ((CCIMInstance *)NULL);
177 	}
178 
179 	if (error != 0) {
180 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_FAILED,
181 		DM_GET_DESC_BYNAME_FAILURE, NULL, &error);
182 	    return ((CCIMInstance*)NULL);
183 	}
184 	dm_free_descriptor(d_descriptor);
185 
186 	/*
187 	 * At this point I have verified I have the two devices that
188 	 * are part of this association. Use the object paths I got
189 	 * earlier to create the mpxiointerface instance.
190 	 */
191 	inst = mpxioIntAssocToInst(antOp, ANTECEDENT, depOp, DEPENDENT, &error);
192 
193 	if (error != 0) {
194 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_FAILED,
195 		MPXIOINT_ASSOC_TO_INSTANCE_FAILURE, NULL, &error);
196 	    return ((CCIMInstance *)NULL);
197 	}
198 	return (inst);
199 }
200 
201 /*
202  * Name: cp_enumInstances_Solaris_MPXIOInterface
203  *
204  * Description: Returns a linked list of instances of
205  *      Solaris_MPXIOInterface if found.
206  *
207  * Parameters:
208  *	pOP - An CCIMObjectPath * which contains the information on
209  *	the class for which to find the instances.
210  * Returns:
211  *	CCIMInstanceList * if istances are found. NULL otherwise.
212  */
213 
214 /* ARGSUSED */
215 CCIMInstanceList*
cp_enumInstances_Solaris_MPXIOInterface(CCIMObjectPath * pOP)216 cp_enumInstances_Solaris_MPXIOInterface(CCIMObjectPath* pOP)
217 {
218 	CCIMInstanceList	*instList = NULL;
219 	CCIMObjectPathList	*cObjList;
220 	CCIMObjectPathList	*tmpObjList;
221 	CCIMObjectPath		*objPath;
222 	CCIMInstance		*inst;
223 	CCIMException		*ex;
224 	dm_descriptor_t		*d_descriptorp = NULL;
225 	int			error = 0;
226 
227 
228 	objPath = cim_createEmptyObjectPath(MPXIO_CONTROLLER);
229 	if (objPath == NULL) {
230 	    ex = cim_getLastError();
231 	    util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
232 		CREATE_OBJECT_PATH, ex, &error);
233 	    return ((CCIMInstanceList *)NULL);
234 	}
235 
236 	cObjList = cimom_enumerateInstanceNames(objPath, cim_false);
237 	cim_freeObjectPath(objPath);
238 
239 	/*
240 	 * NULL is an error. Empty list is not.
241 	 */
242 	if (cObjList == NULL) {
243 	    ex = cim_getLastError();
244 	    util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
245 		ENUM_INSTANCENAMES_FAILURE, ex, &error);
246 	    return ((CCIMInstanceList *)NULL);
247 	}
248 
249 	if (cObjList->mDataObject == NULL) {
250 	    return ((CCIMInstanceList *)NULL);
251 	}
252 	/*
253 	 * Loop through all of these controller objects and get the associated
254 	 * disks.
255 	 */
256 
257 	instList = cim_createInstanceList();
258 	if (instList == NULL) {
259 	    ex = cim_getLastError();
260 	    util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
261 		CREATE_INSTANCE_LIST_FAILURE, ex, &error);
262 	    return ((CCIMInstanceList *)NULL);
263 	}
264 
265 	for (tmpObjList = cObjList; tmpObjList != NULL &&
266 	    tmpObjList->mDataObject != NULL;
267 		tmpObjList = tmpObjList->mNext) {
268 
269 	    CCIMObjectPath 	*cOp;
270 	    CCIMInstanceList	*tmpList;
271 	    CCIMInstanceList	*tmpList1 = NULL;
272 	    CCIMPropertyList	*pCurPropList;
273 	    CCIMObjectPathList	*dObjList;
274 	    CCIMInstanceList	*tL;
275 	    dm_descriptor_t	c_descriptor;
276 	    char 		*name = NULL;
277 
278 	    cOp = tmpObjList->mDataObject;
279 	    if ((pCurPropList = cOp->mKeyProperties) == NULL) {
280 		util_handleError(MPXIO_ENUMINSTANCES,
281 		    CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
282 		cim_freeInstanceList(instList);
283 		cim_freeObjectPathList(cObjList);
284 		return ((CCIMInstanceList *)NULL);
285 	    }
286 
287 	    name = (cimchar *)util_getKeyValue(pCurPropList, string,
288 		DEVICEID, &error);
289 	    if (error != 0 || name == NULL) {
290 		util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_INVALID_PARAMETER,
291 		    NULL, NULL, &error);
292 		cim_freeInstanceList(instList);
293 		cim_freeObjectPathList(cObjList);
294 		return ((CCIMInstanceList *)NULL);
295 	    }
296 
297 	    c_descriptor = dm_get_descriptor_by_name(DM_CONTROLLER, name,
298 		&error);
299 	    if (error == ENODEV || c_descriptor == NULL) {
300 		continue;
301 	    }
302 	    if (error != 0) {
303 		util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
304 		    DM_GET_DESC_BYNAME_FAILURE, NULL, &error);
305 		cim_freeInstanceList(instList);
306 		cim_freeObjectPathList(cObjList);
307 		return ((CCIMInstanceList *)NULL);
308 	    }
309 
310 	    d_descriptorp = dm_get_associated_descriptors(c_descriptor,
311 		DM_DRIVE, &error);
312 	    dm_free_descriptor(c_descriptor);
313 		/*
314 		 * If there are no drives associated with this controller,
315 		 * continue on to the next controller.
316 		 */
317 	    if (d_descriptorp == NULL ||
318 		d_descriptorp[0] == NULL) {
319 		continue;
320 	    }
321 	    if (error != 0) {
322 		util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
323 		    DM_GET_ASSOC_FAILURE, NULL, &error);
324 		cim_freeInstanceList(instList);
325 		cim_freeObjectPathList(cObjList);
326 		return ((CCIMInstanceList *)NULL);
327 	    }
328 
329 	    tmpList = drive_descriptors_toCCIMObjPathInstList(
330 		DISK_DRIVE, d_descriptorp, &error);
331 	    dm_free_descriptors(d_descriptorp);
332 
333 	    if (error != 0) {
334 		util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
335 		    DRIVE_DESC_TO_INSTANCE_FAILURE, NULL, &error);
336 		cim_freeInstanceList(instList);
337 		cim_freeObjectPathList(cObjList);
338 		return ((CCIMInstanceList *)NULL);
339 	    }
340 
341 	    if (tmpList == NULL) {
342 		continue;
343 	    }
344 
345 	    dObjList = cim_createObjectPathList(tmpList);
346 	    cim_freeInstanceList(tmpList);
347 
348 	    if (dObjList == NULL) {
349 		util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
350 		    DRIVE_DESC_TO_INSTANCE_FAILURE, NULL, &error);
351 		cim_freeInstanceList(instList);
352 		cim_freeObjectPathList(cObjList);
353 		return ((CCIMInstanceList *)NULL);
354 	    }
355 	    tmpList1 = mpxioIntAssocToInstList(
356 		cOp, ANTECEDENT, dObjList, DEPENDENT, &error);
357 	    cim_freeObjectPathList(dObjList);
358 
359 	    if (error != 0) {
360 		util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
361 		    DRIVE_DESC_TO_INSTANCE_FAILURE, NULL, &error);
362 		cim_freeInstanceList(instList);
363 		cim_freeObjectPathList(cObjList);
364 		return ((CCIMInstanceList *)NULL);
365 	    }
366 		/*
367 		 * Assign a pointer to the tmplist. Traverse the list with
368 		 * this pointer so as not to disturb the original value of
369 		 * the instance list. This is needed for freeing the list
370 		 * later.
371 		 */
372 	    tL = tmpList1;
373 	    do {
374 		inst = cim_copyInstance(tL->mDataObject);
375 		instList = cim_addInstance(instList, inst);
376 		if (instList == NULL) {
377 			/*
378 			 * In this case we do not free the indivual instance
379 			 * added to the instance list. On error, the original
380 			 * instance list is freed.
381 			 */
382 		    util_handleError(MPXIO_ENUMINSTANCENAMES, CIM_ERR_FAILED,
383 			ADD_INSTANCE_FAILURE, NULL, &error);
384 		    cim_freeInstance(inst);
385 		    cim_freeObjectPathList(cObjList);
386 		    cim_freeInstanceList(tmpList1);
387 		    return ((CCIMInstanceList *)NULL);
388 		}
389 		tL = tL->mNext;
390 	    } while (tL);
391 
392 	    cim_freeInstanceList(tmpList1);
393 	} /* end for */
394 
395 	cim_freeObjectPathList(cObjList);
396 
397 	/*
398 	 * It is possible I will have an empty instance list at
399 	 * this point. So, I must check and NULL this out if
400 	 * there are no entries.
401 	 */
402 	if (instList->mDataObject == NULL) {
403 	    cim_freeInstanceList(instList);
404 	    instList = NULL;
405 	}
406 	return (instList);
407 }
408 
409 /*
410  * Name: cp_enumInstanceNames_Solaris_MPXIOInterface
411  *
412  * Description: Returns a linked list of CCIMObjectPath *
413  *      of Solaris_MPXIOInterface if found.
414  *
415  * Parameters:
416  *	pOP - An CCIMObjectPath * which contains the information on
417  *	the class for which to find the instances.
418  * Returns:
419  *	CCIMObjectPathList * if objects are found. NULL otherwise.
420  */
421 
422 CCIMObjectPathList*
cp_enumInstanceNames_Solaris_MPXIOInterface(CCIMObjectPath * pOP)423 cp_enumInstanceNames_Solaris_MPXIOInterface(CCIMObjectPath * pOP) {
424 
425 	CCIMInstanceList	*instList;
426 	CCIMObjectPathList	*objList = NULL;
427 	int			error;
428 
429 
430 	if (pOP == NULL) {
431 	    util_handleError(MPXIO_ENUMINSTANCENAMES,
432 		CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
433 	    return ((CCIMObjectPathList *)NULL);
434 	}
435 
436 	/*
437 	 * Call in to enumInstances and then convert the instance list in
438 	 * to an object list.
439 	 */
440 
441 	instList = cp_enumInstances_Solaris_MPXIOInterface(pOP);
442 
443 	if (instList != NULL) {
444 	    objList = cim_createObjectPathList(instList);
445 	    cim_freeInstanceList(instList);
446 	}
447 
448 	return (objList);
449 }
450 
451 /*
452  * Creating an instance of a Solaris_MPXIOInterface is not supported.
453  */
454 
455 /* ARGSUSED */
456 CCIMObjectPath*
cp_createInstance_Solaris_MPXIOInterface(CCIMObjectPath * pOP,CCIMInstance * pInst)457 cp_createInstance_Solaris_MPXIOInterface(CCIMObjectPath* pOP,
458     CCIMInstance* pInst)
459 {
460 	int	error;
461 
462 	util_handleError(MPXIO_CREATEINSTANCE, CIM_ERR_NOT_SUPPORTED, NULL,
463 	    NULL, &error);
464 	return ((CCIMObjectPath *)NULL);
465 }
466 
467 
468 /*
469  * Deleting an instance of a Solaris_MPXIOInterface is not supported.
470  */
471 
472 /* ARGSUSED */
473 CIMBool
cp_deleteInstance_Solaris_MPXIOInterface(CCIMObjectPath * pInst)474 cp_deleteInstance_Solaris_MPXIOInterface(CCIMObjectPath* pInst)
475 {
476 	int	error;
477 
478 	util_handleError(MPXIO_DELETEINSTANCE, CIM_ERR_NOT_SUPPORTED, NULL,
479 	    NULL, &error);
480 	return (cim_false);
481 }
482 
483 /*
484  * Name: cp_getProperty_Solaris_MPXIOInterface
485  *
486  * Description: Returns the property requested, if found.
487  *
488  * Parameters:
489  *	pOP - An CCIMObjectPath * which contains the information on
490  *	the class for which to find the instances.
491  * Returns:
492  *	CCIMProperty * if found.
493  */
494 
495 /* ARGSUSED */
496 CCIMProperty	*
cp_getProperty_Solaris_MPXIOInterface(CCIMObjectPath * pOP,char * pPropName)497 cp_getProperty_Solaris_MPXIOInterface(CCIMObjectPath *pOP,
498     char *pPropName)
499 {
500 
501 	CCIMProperty	*prop = NULL;
502 	CCIMInstance	*inst = NULL;
503 	int		error = 0;
504 
505 	if (pOP == NULL) {
506 	    util_handleError(MPXIO_GETPROPERTY,
507 		CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
508 	    return ((CCIMProperty *)NULL);
509 	}
510 
511 	inst = cp_getInstance_Solaris_MPXIOInterface(pOP);
512 	if (inst == NULL) {
513 	    return ((CCIMProperty *)NULL);
514 	}
515 	prop = cim_getProperty(inst, pPropName);
516 	cim_freeInstance(inst);
517 	return (prop);
518 }
519 
520 /*
521  * Setting an instance of a Solaris_MPXIOInterface is not supported.
522  */
523 
524 /* ARGSUSED */
525 CIMBool
cp_setInstance_Solaris_MPXIOInterface(CCIMObjectPath * pOP,CCIMInstance * pInst)526 cp_setInstance_Solaris_MPXIOInterface(CCIMObjectPath* pOP, CCIMInstance* pInst)
527 {
528 	int	error;
529 
530 	util_handleError(MPXIO_SETINSTANCE, CIM_ERR_NOT_SUPPORTED, NULL,
531 	    NULL, &error);
532 	return (cim_false);
533 }
534 
535 /*
536  * Setting a property on a Solaris_MPXIOInterface is not supported.
537  */
538 
539 /* ARGSUSED */
540 CIMBool
cp_setProperty_Solaris_MPXIOInterface(CCIMObjectPath * pOP,CCIMProperty * pProp)541 cp_setProperty_Solaris_MPXIOInterface(CCIMObjectPath* pOP, CCIMProperty* pProp)
542 {
543 	int	error;
544 
545 	util_handleError(MPXIO_SETPROPERTY, CIM_ERR_NOT_SUPPORTED, NULL,
546 	    NULL, &error);
547 	return (cim_false);
548 }
549 
550 /*
551  * No Methods for Solaris_MPXIOInterface.
552  */
553 
554 /* ARGSUSED */
555 CCIMProperty*
cp_invokeMethod_Solaris_MPXIOInterface(CCIMObjectPath * op,cimchar * methodName,CCIMPropertyList * inParams,CCIMPropertyList * outParams)556 cp_invokeMethod_Solaris_MPXIOInterface(
557     CCIMObjectPath* op, cimchar* methodName,
558 	CCIMPropertyList* inParams, CCIMPropertyList* outParams)
559 {
560 
561 	CCIMProperty	*retVal = (CCIMProperty	*)NULL;
562 	return (retVal);
563 }
564 
565 /*
566  * Name: cp_execQuery_Solaris_MPXIOInterface
567  *
568  * Description:
569  * Returns an instance list which matches the query if any are found.
570  *
571  * Parameters:
572  *	CCIMObjectPath *op - An CCIMObjectPath * which contains the
573  *	information on the class for which to find the instances.
574  *
575  * 	selectList - Not used
576  *	nonJoinExp - Not used
577  *
578  * Returns:
579  *	CCIMInstance * if matched instance is found. Otherwise, NULL.
580  */
581 /*
582  * Currently, there is no WQL parser for the C providers. As a result,
583  * what is returned to the CIMOM is a list of instances with
584  * a NULL value at the beginning of the list. This NULL value indicates
585  * to the CIMOM that it must do the filtering for the client.
586  */
587 
588 /* ARGSUSED */
589 CCIMInstanceList*
cp_execQuery_Solaris_MPXIOInterface(CCIMObjectPath * op,cimchar * selectList,cimchar * nonJoinExp,cimchar * queryExp,int queryType)590 cp_execQuery_Solaris_MPXIOInterface(CCIMObjectPath *op,
591     cimchar *selectList, cimchar *nonJoinExp, cimchar *queryExp, int queryType)
592 {
593 	CCIMInstanceList	*instList = NULL;
594 	CCIMInstanceList	*result;
595 	CCIMInstance		*emptyInst;
596 	CCIMException		*ex;
597 	int			error;
598 
599 	if (op == NULL) {
600 	    util_handleError(MPXIO_EXECQUERY, CIM_ERR_INVALID_PARAMETER, NULL,
601 		NULL, &error);
602 	    return ((CCIMInstanceList *)NULL);
603 	}
604 
605 	instList = cp_enumInstances_Solaris_MPXIOInterface(op);
606 
607 	if (instList == NULL) {
608 	    return ((CCIMInstanceList *)NULL);
609 	}
610 	/*
611 	 * Create a null instance and add it to the beginning
612 	 * of the list to indicate to the CIMOM that no filtering
613 	 * was done.
614 	 */
615 
616 	emptyInst = cim_createInstance("");
617 	if (emptyInst == NULL) {
618 	    ex = cim_getLastError();
619 	    util_handleError(MPXIO_EXECQUERY, CIM_ERR_FAILED,
620 		CREATE_INSTANCE_FAILURE, ex, &error);
621 	    return ((CCIMInstanceList *)NULL);
622 	}
623 
624 	result = cim_createInstanceList();
625 	if (result == NULL) {
626 	    ex = cim_getLastError();
627 	    util_handleError(MPXIO_EXECQUERY, CIM_ERR_FAILED,
628 		CREATE_INSTANCE_LIST_FAILURE, ex, &error);
629 	    cim_freeInstance(emptyInst);
630 	    cim_freeInstanceList(instList);
631 	    return ((CCIMInstanceList *)NULL);
632 	}
633 
634 	result = cim_addInstance(result, emptyInst);
635 	if (result == NULL) {
636 	    ex = cim_getLastError();
637 	    util_handleError(MPXIO_EXECQUERY, CIM_ERR_FAILED,
638 		ADD_INSTANCE_FAILURE, ex, &error);
639 	    cim_freeInstance(emptyInst);
640 	    cim_freeInstanceList(instList);
641 	    return ((CCIMInstanceList *)NULL);
642 	}
643 
644 	/*
645 	 * Since copying the original list to the new list will
646 	 * leave no way to free the original list, manually
647 	 * concatenate the original list to the new one.
648 	 */
649 
650 	result->mNext = instList;
651 	return (result);
652 }
653 
654 /*
655  * Name: cp_associators_Solaris_MPXIOInterface
656  *
657  * Description:
658  * Returns a instances of objects associated with the passed in
659  * object if there are any.
660  *
661  * Parameters:
662  *
663  *	CCIMObjectPath *pAssocName - The name of the association that
664  *	the client wants information about.
665  *
666  *	CCIMObjectPath *pObjectName - An CCIMObjectPath * which contains the
667  *	information on the class for which to find the associated instances.
668  *
669  *	cimchar *pResultClass - If specified, only return instances that
670  *	are of this class type.
671  *
672  *      cimchar *pRole - If specified, must be valid for the object path
673  *	passed in requesting the associated instances.
674  *
675  *	cimchar *pResultRole - If specified, only return instances that
676  *	are playing this role in the association.
677  *
678  *
679  * Returns:
680  *	CCIMInstanceList * if associated objects are found. NULL otherwise.
681  */
682 
683 /* ARGSUSED */
684 CCIMInstanceList *
cp_associators_Solaris_MPXIOInterface(CCIMObjectPath * pAssocName,CCIMObjectPath * pObjectName,cimchar * pResultClass,cimchar * pRole,cimchar * pResultRole)685 cp_associators_Solaris_MPXIOInterface(CCIMObjectPath *pAssocName,
686     CCIMObjectPath *pObjectName, cimchar *pResultClass, cimchar *pRole,
687 	cimchar *pResultRole)
688 {
689 	CCIMPropertyList	*pCurPropList;
690 	CCIMInstanceList	*instList = NULL;
691 	dm_descriptor_t		*assoc_descriptors;
692 	dm_descriptor_t		obj_desc;
693 	char			*name;
694 	int			error = 0;
695 	int			isAntecedent = 0;
696 
697 	if (pObjectName == NULL ||
698 	    pObjectName->mName == NULL ||
699 		((pCurPropList = pObjectName->mKeyProperties) == NULL)) {
700 		util_handleError(MPXIO_ASSOCIATORS, CIM_ERR_INVALID_PARAMETER,
701 		    NULL, NULL, &error);
702 		return ((CCIMInstanceList *)NULL);
703 	}
704 
705 	if (strcasecmp(pObjectName->mName, MPXIO_CONTROLLER) == 0) {
706 	    isAntecedent = 1;
707 	}
708 
709 	if (pRole != NULL) {
710 	    if (strcasecmp(pRole, ANTECEDENT) == 0) {
711 		if (isAntecedent != 1) {
712 		    util_handleError(MPXIO_ASSOCIATORS,
713 			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
714 		    return ((CCIMInstanceList *)NULL);
715 		}
716 	    } else if (strcasecmp(pRole, DEPENDENT) == 0) {
717 		if (isAntecedent == 1) {
718 		    util_handleError(MPXIO_ASSOCIATORS,
719 			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
720 		    return ((CCIMInstanceList *)NULL);
721 		}
722 	    }
723 	}
724 
725 	/*
726 	 * Both mpxio controller and disk drive have deviceid as the
727 	 * key.
728 	 */
729 
730 	name = (cimchar *)util_getKeyValue(pCurPropList, string, DEVICEID,
731 	    &error);
732 	if (error != 0) {
733 	    util_handleError(MPXIO_ASSOCIATORS, CIM_ERR_INVALID_PARAMETER, NULL,
734 		NULL, &error);
735 	    return ((CCIMInstanceList *)NULL);
736 	}
737 
738 	if (isAntecedent) {
739 	    obj_desc = dm_get_descriptor_by_name(DM_CONTROLLER, name,
740 		&error);
741 	} else {
742 	    obj_desc = dm_get_descriptor_by_name(DM_DRIVE, name,
743 		&error);
744 	}
745 	/*
746 	 * No device found.
747 	 */
748 	if (error == ENODEV || obj_desc == NULL) {
749 	    return ((CCIMInstanceList *)NULL);
750 	}
751 	if (error != 0) {
752 	    util_handleError(MPXIO_ASSOCIATORS, CIM_ERR_FAILED,
753 		DM_GET_DESC_BYNAME_FAILURE, NULL, &error);
754 	    return ((CCIMInstanceList *)NULL);
755 	}
756 
757 	if (isAntecedent) {
758 		/*
759 		 * Controller calling this method, return instances of the
760 		 * disk drives associatied with this controller.
761 		 */
762 
763 	    assoc_descriptors = dm_get_associated_descriptors(obj_desc,
764 		DM_DRIVE, &error);
765 	    dm_free_descriptor(obj_desc);
766 
767 	    if (assoc_descriptors == NULL ||
768 		assoc_descriptors[0] == NULL) {
769 		return ((CCIMInstanceList *)NULL);
770 	    }
771 
772 	    if (error != 0) {
773 		util_handleError(MPXIO_ASSOCIATORS,  CIM_ERR_FAILED,
774 		    DM_GET_ASSOC_FAILURE, NULL, &error);
775 		return ((CCIMInstanceList *)NULL);
776 	    }
777 		/*
778 		 * Generate the inst list of the associated disk drives.
779 		 */
780 
781 	    instList = drive_descriptors_toCCIMObjPathInstList(DISK_DRIVE,
782 		assoc_descriptors, &error);
783 	    dm_free_descriptors(assoc_descriptors);
784 
785 	    if (error != 0) {
786 		util_handleError(MPXIO_ASSOCIATORS, CIM_ERR_FAILED,
787 		    DRIVE_DESC_TO_INSTANCE_FAILURE, NULL, &error);
788 		return ((CCIMInstanceList *)NULL);
789 	    }
790 	} else {
791 		/*
792 		 * This is the disk drive calling this function. Return the
793 		 * controllers that are associated with this disk.
794 		 */
795 	    assoc_descriptors = dm_get_associated_descriptors(obj_desc,
796 		DM_CONTROLLER, &error);
797 	    dm_free_descriptor(obj_desc);
798 
799 	    if (assoc_descriptors == NULL ||
800 		assoc_descriptors[0] == NULL) {
801 		return ((CCIMInstanceList *)NULL);
802 	    }
803 
804 	    if (error != 0) {
805 		util_handleError(MPXIO_ASSOCIATORS,  CIM_ERR_FAILED,
806 		    DM_GET_ASSOC_FAILURE, NULL, &error);
807 		return ((CCIMInstanceList *)NULL);
808 	    }
809 
810 	    instList = ctrl_descriptors_toCCIMInstanceList(MPXIO_CONTROLLER,
811 		assoc_descriptors, &error, 1, "scsi_vhci");
812 	    dm_free_descriptors(assoc_descriptors);
813 
814 	    if (error != 0) {
815 		util_handleError(MPXIO_ASSOCIATORS, CIM_ERR_FAILED,
816 		    MPXIOCTRL_DESC_TO_INSTANCE_FAILURE, NULL, &error);
817 		return ((CCIMInstanceList *)NULL);
818 	    }
819 	}
820 
821 	return (instList);
822 }
823 
824 /*
825  * Name: cp_associatorNames_Solaris_MPXIOInterface
826  *
827  * Description:
828  * Returns a list of objects associated with the passed in
829  * object if there are any via the object CCIMObjectPath.
830  *
831  * Parameters:
832  *
833  *	CCIMObjectPath *pAssocName - The name of the association that
834  *	the client wants information about.
835  *
836  *	CCIMObjectPath *pObjectName - An CCIMObjectPath * which contains the
837  *	information on the class for which to find the associated instances.
838  *
839  *	cimchar *pResultClass - If specified, only return instances that
840  *	are of this class type.
841  *
842  *      cimchar *pRole - If specified, must be valid for the object path
843  *	passed in requesting the associated instances.
844  *
845  *	cimchar *pResultRole - If specified, only return instances that
846  *	are playing this role in the association.
847  *
848  *
849  * Returns:
850  *	CCIMObjectPathList * if associated objects are found. Otherwise, NULL.
851  */
852 /* ARGSUSED */
853 CCIMObjectPathList *
cp_associatorNames_Solaris_MPXIOInterface(CCIMObjectPath * pAssocName,CCIMObjectPath * pObjectName,cimchar * pResultClass,cimchar * pRole,cimchar * pResultRole)854 cp_associatorNames_Solaris_MPXIOInterface(CCIMObjectPath *pAssocName,
855     CCIMObjectPath *pObjectName, cimchar *pResultClass, cimchar *pRole,
856 	cimchar *pResultRole)
857 {
858 
859 	CCIMInstanceList	*instList;
860 	CCIMObjectPathList	*objList = NULL;
861 	int			error;
862 
863 	if (pObjectName == NULL) {
864 	    util_handleError(MPXIO_ASSOCIATORNAMES,
865 		CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
866 	    return ((CCIMObjectPathList *)NULL);
867 	}
868 
869 	instList =
870 	    cp_associators_Solaris_MPXIOInterface(
871 		pAssocName, pObjectName, pResultClass, pRole, pResultRole);
872 
873 	if (instList != NULL) {
874 	    objList = cim_createObjectPathList(instList);
875 	    cim_freeInstanceList(instList);
876 	}
877 	return (objList);
878 }
879 
880 /*
881  * Name: cp_references_Solaris_MPXIOInterface
882  *
883  * Description:
884  * Returns a instances of objects that have references to the passed in
885  * object if there are any.
886  *
887  * Parameters:
888  *
889  *	CCIMObjectPath *pAssocName - The name of the association that
890  *	the client wants information about.
891  *
892  *	CCIMObjectPath *pObjectName - An CCIMObjectPath * which contains the
893  *	information on the class for which to find the associated instances.
894  *
895  *      cimchar *pRole - If specified, must be valid for the object path
896  *	passed in requesting the associated instances.
897  *
898  * Returns:
899  *	CCIMInstanceList * if associated objects are found. NULL otherwise.
900  */
901 
902 /* ARGSUSED */
903 CCIMInstanceList *
cp_references_Solaris_MPXIOInterface(CCIMObjectPath * pAssocName,CCIMObjectPath * pObjectName,char * pRole)904 cp_references_Solaris_MPXIOInterface(CCIMObjectPath *pAssocName,
905 CCIMObjectPath *pObjectName, char *pRole)
906 {
907 
908 	CCIMInstanceList	*instList = NULL;
909 	CCIMObjectPathList	*objList;
910 	int			error;
911 
912 	if (pObjectName == NULL) {
913 	    util_handleError(MPXIO_REFERENCES, CIM_ERR_INVALID_PARAMETER,
914 		NULL, NULL, &error);
915 	    return ((CCIMInstanceList *)NULL);
916 	}
917 	/*
918 	 * Get the list of those objects that are referred to by
919 	 * the calling object.
920 	 */
921 
922 	objList =
923 	    cp_associatorNames_Solaris_MPXIOInterface(
924 		pAssocName, pObjectName, NULL, NULL, NULL);
925 
926 	if (objList == NULL) {
927 	    return ((CCIMInstanceList *)NULL);
928 	}
929 
930 	/*
931 	 * Now generate the list of instances to return.
932 	 */
933 
934 	if ((strcasecmp(pObjectName->mName, MPXIO_CONTROLLER)) == 0) {
935 	    instList = mpxioIntAssocToInstList(pObjectName,
936 		ANTECEDENT, objList, DEPENDENT, &error);
937 	} else {
938 	    instList = mpxioIntAssocToInstList(pObjectName,
939 		DEPENDENT, objList, ANTECEDENT, &error);
940 	}
941 
942 	cim_freeObjectPathList(objList);
943 	return (instList);
944 }
945 
946 /*
947  * Name: cp_referenceNames_Solaris_MPXIOInterface
948  *
949  * Description:
950  * Returns a instances of objects that have references to the passed in
951  * object if there are any.
952  *
953  * Parameters:
954  *
955  *	CCIMObjectPath *pAssocName - The name of the association that
956  *	the client wants information about.
957  *
958  *	CCIMObjectPath *pObjectName - An CCIMObjectPath * which contains the
959  *	information on the class for which to find the associated instances.
960  *
961  *      cimchar *pRole - If specified, must be valid for the object path
962  *	passed in requesting the associated instances.
963  *
964  *
965  * Returns:
966  *	CCIMObjectPathList * if associated objects are found. NULL otherwise.
967  *
968  */
969 /* ARGSUSED */
970 CCIMObjectPathList *
cp_referenceNames_Solaris_MPXIOInterface(CCIMObjectPath * pAssocName,CCIMObjectPath * pObjectName,cimchar * pRole)971 cp_referenceNames_Solaris_MPXIOInterface(CCIMObjectPath *pAssocName,
972     CCIMObjectPath *pObjectName, cimchar *pRole)
973 {
974 
975 	CCIMInstanceList	*instList;
976 	CCIMObjectPathList	*objList = NULL;
977 	int			error;
978 
979 	if (pObjectName == NULL) {
980 	    util_handleError(MPXIO_REFERENCENAMES,
981 		CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
982 	    return ((CCIMObjectPathList *)NULL);
983 	}
984 
985 	instList =
986 	    cp_references_Solaris_MPXIOInterface(pAssocName,
987 		pObjectName, pRole);
988 	if (instList != NULL) {
989 	    objList = cim_createObjectPathList(instList);
990 	    cim_freeInstanceList(instList);
991 	}
992 
993 	return (objList);
994 }
995 
996 /*
997  * Create the association class with the passed in attributes.
998  */
999 static
1000 CCIMInstanceList  *
mpxioIntAssocToInstList(CCIMObjectPath * pObjectName,cimchar * pObjectNameRole,CCIMObjectPathList * objList,cimchar * objRole,int * error)1001 mpxioIntAssocToInstList(CCIMObjectPath *pObjectName, cimchar *pObjectNameRole,
1002 	CCIMObjectPathList *objList, cimchar *objRole, int *error)
1003 {
1004 
1005 	CCIMObjectPathList	*tmpList;
1006 	CCIMInstanceList	*instList = NULL;
1007 	CCIMInstance		*inst;
1008 	CCIMObjectPath		*obj1;
1009 	CCIMObjectPath		*obj2;
1010 	CCIMException		*ex;
1011 
1012 	*error = 0;
1013 
1014 	/*
1015 	 * If no objects associated with this one, return NULL.
1016 	 */
1017 	if (objList == NULL) {
1018 	    return ((CCIMInstanceList *)NULL);
1019 	}
1020 
1021 	instList = cim_createInstanceList();
1022 	if (instList == NULL) {
1023 	    ex = cim_getLastError();
1024 	    util_handleError(MPXIO_INTERFACE, CIM_ERR_FAILED,
1025 		CREATE_INSTANCE_FAILURE, ex, error);
1026 	    return ((CCIMInstanceList *)NULL);
1027 	}
1028 
1029 	tmpList = objList;
1030 	while (tmpList != NULL) {
1031 	    obj1 = tmpList->mDataObject;
1032 	    obj2 = cim_copyObjectPath(pObjectName);
1033 	    if (obj2 == NULL) {
1034 		ex = cim_getLastError();
1035 		util_handleError(MPXIO_INTERFACE, CIM_ERR_FAILED,
1036 		    COPY_OBJPATH_FAILURE, ex, error);
1037 		return ((CCIMInstanceList *)NULL);
1038 	    }
1039 
1040 	    inst = mpxioIntAssocToInst(obj1, objRole, obj2, pObjectNameRole,
1041 		error);
1042 	    cim_freeObjectPath(obj2);
1043 	    if (*error != 0) {
1044 		util_handleError(MPXIO_INTERFACE, CIM_ERR_FAILED,
1045 		    MPXIOINT_ASSOC_TO_INSTANCE_FAILURE, NULL, error);
1046 		cim_freeInstanceList(instList);
1047 		return ((CCIMInstanceList *)NULL);
1048 	    }
1049 
1050 	    instList = cim_addInstance(instList, inst);
1051 	    if (instList == NULL) {
1052 		ex = cim_getLastError();
1053 		util_handleError(MPXIO_INTERFACE, CIM_ERR_FAILED,
1054 		    ADD_INSTANCE_FAILURE, ex, error);
1055 		cim_freeInstance(inst);
1056 		return ((CCIMInstanceList *)NULL);
1057 	    }
1058 	    tmpList = tmpList->mNext;
1059 	}
1060 	return (instList);
1061 }
1062 
1063 static
1064 CCIMInstance  *
mpxioIntAssocToInst(CCIMObjectPath * obj1,cimchar * obj1Role,CCIMObjectPath * obj2,cimchar * obj2Role,int * error)1065 mpxioIntAssocToInst(CCIMObjectPath *obj1, cimchar *obj1Role,
1066 	CCIMObjectPath *obj2, cimchar *obj2Role, int *error)
1067 {
1068 
1069 	CCIMInstance	*inst = NULL;
1070 	CCIMException	*ex;
1071 
1072 	*error	= 0;
1073 
1074 	inst = cim_createInstance(MPXIO_INTERFACE);
1075 	if (inst == NULL) {
1076 	    ex = cim_getLastError();
1077 	    util_handleError(MPXIO_INTERFACE, CIM_ERR_FAILED,
1078 		MPXIOINT_ASSOC_TO_INSTANCE_FAILURE, ex, error);
1079 	    return ((CCIMInstance *)NULL);
1080 	}
1081 
1082 	util_doReferenceProperty(obj2Role, obj2, cim_true, inst, error);
1083 	if (*error != 0) {
1084 	    ex = cim_getLastError();
1085 	    util_handleError(MPXIO_INTERFACE, CIM_ERR_FAILED,
1086 		CREATE_REFPROP_FAILURE, ex, error);
1087 	    cim_freeInstance(inst);
1088 	    return ((CCIMInstance *)NULL);
1089 	}
1090 
1091 	util_doReferenceProperty(obj1Role, obj1, cim_true, inst,
1092 	    error);
1093 	if (*error != 0) {
1094 	    ex = cim_getLastError();
1095 	    util_handleError(MPXIO_INTERFACE, CIM_ERR_FAILED,
1096 		CREATE_REFPROP_FAILURE, ex, error);
1097 	    cim_freeInstance(inst);
1098 	    return ((CCIMInstance *)NULL);
1099 	}
1100 	return (inst);
1101 }
1102