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 "ctrl_descriptors.h"
38 #include "Solaris_MPXIOComponent.h"
39 
40 #define	MPXIO_GETINSTANCE		"MPXIO_COMPONENT,GET_INSTANCE"
41 #define	MPXIO_ENUMINSTANCES		"MPXIO_COMPONENT,ENUM_INSTANCES"
42 #define	MPXIO_ENUMINSTANCENAMES		"MPXIO_COMPONENT,ENUM_INSTANCENAMES"
43 #define	MPXIO_CREATEINSTANCE		"MPXIO_COMPONENT,CREATE_INSTANCE"
44 #define	MPXIO_DELETEINSTANCE		"MPXIO_COMPONENT,DELETE_INSTANCE"
45 #define	MPXIO_SETINSTANCE		"MPXIO_COMPONENT,SET_INSTANCE"
46 #define	MPXIO_GETPROPERTY		"MPXIO_COMPONENT,GET_PROPERTY"
47 #define	MPXIO_SETPROPERTY		"MPXIO_COMPONENT,SET_PROPERTY"
48 #define	MPXIO_INVOKEMETHOD		"MPXIO_COMPONENT,INVOKE_METHOD"
49 #define	MPXIO_EXECQUERY			"MPXIO_COMPONENT,EXEC_QUERY"
50 #define	MPXIO_ASSOCIATORS		"MPXIO_COMPONENT,ASSOCIATORS"
51 #define	MPXIO_ASSOCIATORNAMES		"MPXIO_COMPONENT,ASSOCIATOR_NAMES"
52 #define	MPXIO_REFERENCES		"MPXIO_COMPONENT,REFERENCES"
53 #define	MPXIO_REFERENCENAMES		"MPXIO_COMPONENT,REFERENCE_NAMES"
54 
55 static
56 CCIMInstanceList *
57 mpxioCompToInstList(CCIMObjectPath *pObjectName, cimchar *pObjectNameRole,
58 	CCIMObjectPathList *objList, cimchar *objRole, int *error);
59 
60 static
61 CCIMInstance  *
62 mpxioCompToInst(CCIMObjectPath *obj1, cimchar *obj1Role,
63 	CCIMObjectPath *obj2, cimchar *obj2Role, int *error);
64 
65 /*
66  * Solaris_MPXIOComponent provider
67  *
68  * It is important to note that all memory allocated by these functions
69  * and passed to the CIMOM, is freed by the door process prior to
70  * sending a copy of the data to the CIMOM.
71  */
72 
73 /*
74  * Name: cp_getInstance_Solaris_MPXIOComponent
75  *
76  * Description: Returns an instance which matches the passed in object path
77  * if found.
78  *
79  * Parameters:
80  *	pOP - An CCIMObjectPath * which contains the information on
81  *	the class for which to find the instance.
82  * Returns:
83  *	CCIMInstance * if matched instance is found. Otherwise, NULL.
84  */
85 
86 /* ARGSUSED */
87 CCIMInstance*
cp_getInstance_Solaris_MPXIOComponent(CCIMObjectPath * pOP)88 cp_getInstance_Solaris_MPXIOComponent(CCIMObjectPath* pOP)
89 {
90 	CCIMInstance		*inst = NULL;
91 	CCIMPropertyList	*pCurPropList;
92 	CCIMObjectPath		*antOp = NULL;
93 	CCIMObjectPath		*depOp = NULL;
94 	dm_descriptor_t		m_descriptor;
95 	dm_descriptor_t		c_descriptor;
96 	char			*name;
97 	int			error;
98 
99 	if (pOP == NULL ||
100 	    (pCurPropList = pOP->mKeyProperties) == NULL) {
101 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
102 		NULL, &error);
103 	    return ((CCIMInstance*)NULL);
104 	}
105 
106 	antOp = (CCIMObjectPath *)util_getKeyValue(pCurPropList, reference,
107 	    GROUP, &error);
108 
109 	if (error == 0) {
110 	    depOp = (CCIMObjectPath *)util_getKeyValue(pCurPropList, reference,
111 		PART, &error);
112 	}
113 
114 	if (error != 0) {
115 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
116 		NULL, &error);
117 	    return ((CCIMInstance*)NULL);
118 	}
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, DEVICEID,
133 	    &error);
134 	if (error != 0 || name == NULL) {
135 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
136 		NULL, &error);
137 	    return ((CCIMInstance *)NULL);
138 	}
139 
140 	/*
141 	 * The only reason it is needed to get the descriptor for these
142 	 * two devices is to verify that they still exist and are valid.
143 	 * If they are not found, then getting the instance for this
144 	 * association as passed in by the client is not possible.
145 	 */
146 	m_descriptor = dm_get_descriptor_by_name(DM_CONTROLLER, name,
147 	    &error);
148 	/*
149 	 * Not found. Return a null instance.
150 	 */
151 	if (error == ENODEV || m_descriptor == NULL) {
152 	    return ((CCIMInstance *)NULL);
153 	}
154 	if (error != 0) {
155 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_FAILED,
156 		DM_GET_DESC_BYNAME_FAILURE, NULL, &error);
157 	    return ((CCIMInstance*)NULL);
158 	}
159 	dm_free_descriptor(m_descriptor);
160 	/*
161 	 * Now, get the name of the dependent from the object path.
162 	 */
163 	pCurPropList = depOp->mKeyProperties;
164 	name = (cimchar *)util_getKeyValue(pCurPropList, string, DEVICEID,
165 	    &error);
166 	if (error != 0 || name == NULL) {
167 	    util_handleError(MPXIO_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
168 		NULL, &error);
169 	    return ((CCIMInstance *)NULL);
170 	}
171 	c_descriptor = dm_get_descriptor_by_name(DM_PATH, name,
172 	    &error);
173 	/*
174 	 * Not found. Return a null instance.
175 	 */
176 	if (error == ENODEV || c_descriptor == NULL) {
177 	    return ((CCIMInstance *)NULL);
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(c_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 = mpxioCompToInst(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_MPXIOComponent
203  *
204  * Description: Returns a linked list of instances of
205  *      Solaris_MPXIOComponent 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.
212  *	Otherwise, NULL is returned.
213  */
214 
215 /* ARGSUSED */
216 CCIMInstanceList*
cp_enumInstances_Solaris_MPXIOComponent(CCIMObjectPath * pOP)217 cp_enumInstances_Solaris_MPXIOComponent(CCIMObjectPath* pOP)
218 {
219 	CCIMInstanceList	*instList = NULL;
220 	CCIMObjectPathList	*cObjList;
221 	CCIMObjectPathList	*tmpObjList;
222 	CCIMObjectPath		*objPath;
223 	CCIMInstance		*inst;
224 	CCIMException		*ex;
225 	int			error = 0;
226 
227 	/*
228 	 * Get the list of MPXIO Controllers. Then get the associated paths
229 	 * via the device api.
230 	 */
231 
232 	objPath = cim_createEmptyObjectPath(MPXIO_CONTROLLER);
233 	if (objPath == NULL) {
234 	    ex = cim_getLastError();
235 	    util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
236 		CREATE_OBJECT_PATH, ex, &error);
237 	    return ((CCIMInstanceList *)NULL);
238 	}
239 
240 	cObjList = cimom_enumerateInstanceNames(objPath, cim_false);
241 	cim_freeObjectPath(objPath);
242 
243 	/*
244 	 * NULL means error, empty list does not.
245 	 */
246 	if (cObjList == NULL) {
247 	    ex = cim_getLastError();
248 	    util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
249 		ENUM_INSTANCENAMES_FAILURE, ex,
250 		&error);
251 	    return ((CCIMInstanceList *)NULL);
252 	}
253 
254 	if (cObjList->mDataObject == NULL) {
255 	    return ((CCIMInstanceList *)NULL);
256 	}
257 
258 	/*
259 	 * Loop through all of these controller objects and get the associated
260 	 * paths.
261 	 */
262 
263 	instList = cim_createInstanceList();
264 	if (instList == NULL) {
265 	    ex = cim_getLastError();
266 	    util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
267 		CREATE_INSTANCE_LIST_FAILURE, ex, &error);
268 	    return ((CCIMInstanceList *)NULL);
269 	}
270 
271 	for (tmpObjList = cObjList; tmpObjList != NULL;
272 	    tmpObjList = tmpObjList->mNext) {
273 
274 	    char 		*name = NULL;
275 	    CCIMObjectPath 	*cOp;
276 	    CCIMInstanceList	*tmpList;
277 	    CCIMInstanceList	*tmpList1;
278 	    CCIMPropertyList	*pCurPropList;
279 	    CCIMObjectPathList	*dObjList;
280 	    CCIMInstanceList	*tL;
281 	    dm_descriptor_t	m_descriptor;
282 	    dm_descriptor_t	*c_descriptorp = NULL;
283 
284 	    cOp = tmpObjList->mDataObject;
285 	    if ((pCurPropList = cOp->mKeyProperties) == NULL) {
286 		util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_INVALID_PARAMETER,
287 		    NULL, NULL, &error);
288 		cim_freeInstanceList(instList);
289 		cim_freeObjectPathList(cObjList);
290 		return ((CCIMInstanceList *)NULL);
291 	    }
292 
293 	    name = (cimchar *)util_getKeyValue(pCurPropList, string, DEVICEID,
294 		&error);
295 	    if (error != 0 || name == NULL) {
296 		util_handleError(MPXIO_ENUMINSTANCES,
297 		    CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
298 		cim_freeInstanceList(instList);
299 		cim_freeObjectPathList(cObjList);
300 		return ((CCIMInstanceList *)NULL);
301 	    }
302 
303 	    m_descriptor = dm_get_descriptor_by_name(DM_CONTROLLER, name,
304 		&error);
305 	    if (error == ENODEV || m_descriptor == NULL) {
306 		continue;
307 	    }
308 	    if (error != 0) {
309 		util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
310 		    DM_GET_DESC_BYNAME_FAILURE, NULL, &error);
311 		cim_freeInstanceList(instList);
312 		cim_freeObjectPathList(cObjList);
313 		return ((CCIMInstanceList *)NULL);
314 	    }
315 
316 	    c_descriptorp = dm_get_associated_descriptors(m_descriptor,
317 		DM_PATH, &error);
318 	    dm_free_descriptor(m_descriptor);
319 		/*
320 		 * If there are no paths associated with this mpxio controller,
321 		 * continue on to the next controller.
322 		 */
323 
324 	    if (c_descriptorp == NULL) {
325 		continue;
326 	    }
327 
328 	    if (c_descriptorp[0] == NULL) {
329 		dm_free_descriptors(c_descriptorp);
330 		continue;
331 	    }
332 
333 	    if (error != 0) {
334 		util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
335 		    DM_GET_ASSOC_FAILURE, NULL, &error);
336 		cim_freeInstanceList(instList);
337 		cim_freeObjectPathList(cObjList);
338 		return ((CCIMInstanceList *)NULL);
339 	    }
340 
341 	    tmpList = ctrl_descriptors_toCCIMInstanceList(
342 		SCSI_CONTROLLER, c_descriptorp, &error, 5, "scsi");
343 	    dm_free_descriptors(c_descriptorp);
344 
345 	    if (error != 0) {
346 		util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
347 		    DRIVE_DESC_TO_INSTANCE_FAILURE, NULL, &error);
348 		cim_freeInstanceList(instList);
349 		cim_freeObjectPathList(cObjList);
350 		return ((CCIMInstanceList *)NULL);
351 	    }
352 
353 	    dObjList = cim_createObjectPathList(tmpList);
354 	    cim_freeInstanceList(tmpList);
355 
356 	    if (dObjList == NULL) {
357 		util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
358 		    DRIVE_DESC_TO_INSTANCE_FAILURE, NULL, &error);
359 		cim_freeInstanceList(instList);
360 		cim_freeObjectPathList(cObjList);
361 		return ((CCIMInstanceList *)NULL);
362 	    }
363 	    tmpList1 = mpxioCompToInstList(
364 		cOp, ANTECEDENT, dObjList, DEPENDENT, &error);
365 	    cim_freeObjectPathList(dObjList);
366 
367 	    if (error != 0) {
368 		util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
369 		    DRIVE_DESC_TO_INSTANCE_FAILURE, NULL, &error);
370 		cim_freeInstanceList(instList);
371 		cim_freeObjectPathList(cObjList);
372 		return ((CCIMInstanceList *)NULL);
373 	    }
374 
375 	    tL = tmpList1;
376 	    do {
377 		inst = cim_copyInstance(tL->mDataObject);
378 		instList = cim_addInstance(instList, inst);
379 		if (instList == NULL) {
380 		    ex = cim_getLastError();
381 		    util_handleError(MPXIO_ENUMINSTANCES, CIM_ERR_FAILED,
382 			ADD_INSTANCE_FAILURE, ex, &error);
383 		    cim_freeObjectPathList(cObjList);
384 		    cim_freeInstance(inst);
385 		    cim_freeObjectPathList(tmpList1);
386 		    return ((CCIMInstanceList *)NULL);
387 		}
388 		tL = tL->mNext;
389 	    } while (tL);
390 
391 	    cim_freeObjectPathList(tmpList1);
392 	} /* end for */
393 
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_MPXIOComponent
411  *
412  * Description: Returns a linked list of CCIMObjectPath *
413  *      of Solaris_MPXIOComponent 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.
420  *	Otherwise, NULL is returned.
421  */
422 
423 CCIMObjectPathList*
cp_enumInstanceNames_Solaris_MPXIOComponent(CCIMObjectPath * pOP)424 cp_enumInstanceNames_Solaris_MPXIOComponent(CCIMObjectPath * pOP) {
425 
426 	CCIMInstanceList	*instList;
427 	CCIMObjectPathList	*objList = NULL;
428 	int			error;
429 
430 	if (pOP == NULL) {
431 	    util_handleError(MPXIO_ENUMINSTANCENAMES,
432 		CIM_ERR_INVALID_PARAMETER, NULL,
433 		NULL, &error);
434 	    return ((CCIMObjectPathList *)NULL);
435 	}
436 
437 	/*
438 	 * Call in to enumInstances and then convert the instance list in
439 	 * to an object list.
440 	 */
441 
442 	instList = cp_enumInstances_Solaris_MPXIOComponent(pOP);
443 
444 	if (instList->mDataObject != NULL) {
445 	    objList = cim_createObjectPathList(instList);
446 	    cim_freeInstanceList(instList);
447 	}
448 
449 	return (objList);
450 }
451 
452 /*
453  * Creating an instance of a Solaris_MPXIOComponent is not supported.
454  */
455 
456 /* ARGSUSED */
457 CCIMObjectPath*
cp_createInstance_Solaris_MPXIOComponent(CCIMObjectPath * pOP,CCIMInstance * pInst)458 cp_createInstance_Solaris_MPXIOComponent(CCIMObjectPath* pOP,
459     CCIMInstance* pInst)
460 {
461 	int	error;
462 
463 	util_handleError(MPXIO_COMPONENT, CIM_ERR_NOT_SUPPORTED, NULL,
464 	    NULL, &error);
465 	return ((CCIMObjectPath *)NULL);
466 }
467 
468 /*
469  * Deleting an instance of a Solaris_MPXIOComponent is not supported.
470  */
471 
472 /* ARGSUSED */
473 CIMBool
cp_deleteInstance_Solaris_MPXIOComponent(CCIMObjectPath * pInst)474 cp_deleteInstance_Solaris_MPXIOComponent(CCIMObjectPath* pInst)
475 {
476 	int	error;
477 
478 	util_handleError(MPXIO_COMPONENT, CIM_ERR_NOT_SUPPORTED, NULL,
479 	    NULL, &error);
480 	return (cim_false);
481 }
482 
483 /*
484  * Name: cp_getProperty_Solaris_MPXIOComponent
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_MPXIOComponent(CCIMObjectPath * pOP,char * pPropName)497 cp_getProperty_Solaris_MPXIOComponent(CCIMObjectPath *pOP,
498     char *pPropName)
499 {
500 
501 	CCIMProperty	*prop = NULL;
502 	CCIMInstance	*inst = NULL;
503 	int		error = 0;
504 
505 
506 	if (pOP == NULL) {
507 	    util_handleError(MPXIO_GETPROPERTY, CIM_ERR_INVALID_PARAMETER, NULL,
508 		NULL, &error);
509 	    return ((CCIMProperty *)NULL);
510 	}
511 
512 	inst = cp_getInstance_Solaris_MPXIOComponent(pOP);
513 	if (inst == NULL) {
514 	    return ((CCIMProperty *)NULL);
515 	}
516 
517 	prop = cim_getProperty(inst, pPropName);
518 	cim_freeInstance(inst);
519 	return (prop);
520 }
521 
522 /*
523  * Setting an instance of a Solaris_MPXIOComponent is not supported.
524  */
525 
526 /* ARGSUSED */
527 CIMBool
cp_setInstance_Solaris_MPXIOComponent(CCIMObjectPath * pOP,CCIMInstance * pInst)528 cp_setInstance_Solaris_MPXIOComponent(CCIMObjectPath* pOP, CCIMInstance* pInst)
529 {
530 	int	error;
531 
532 	util_handleError(MPXIO_COMPONENT, CIM_ERR_NOT_SUPPORTED, NULL,
533 	    NULL, &error);
534 	return (cim_false);
535 }
536 
537 /*
538  * Setting a property on a Solaris_MPXIOComponent is not supported.
539  */
540 
541 /* ARGSUSED */
542 CIMBool
cp_setProperty_Solaris_MPXIOComponent(CCIMObjectPath * pOP,CCIMProperty * pProp)543 cp_setProperty_Solaris_MPXIOComponent(CCIMObjectPath* pOP, CCIMProperty* pProp)
544 {
545 	int	error;
546 
547 	util_handleError(MPXIO_COMPONENT, CIM_ERR_NOT_SUPPORTED, NULL,
548 	    NULL, &error);
549 	return (cim_false);
550 }
551 
552 /*
553  * No Methods for Solaris_MPXIOComponent.
554  */
555 
556 /* ARGSUSED */
557 CCIMProperty*
cp_invokeMethod_Solaris_MPXIOComponent(CCIMObjectPath * op,cimchar * methodName,CCIMPropertyList * inParams,CCIMPropertyList * outParams)558 cp_invokeMethod_Solaris_MPXIOComponent(
559     CCIMObjectPath* op, cimchar* methodName,
560 	CCIMPropertyList* inParams, CCIMPropertyList* outParams)
561 {
562 	CCIMProperty	*retVal = (CCIMProperty	*)NULL;
563 	return (retVal);
564 }
565 
566 /*
567  * Name: cp_execQuery_Solaris_MPXIOComponent
568  *
569  * Description:
570  * Returns an instance list which matches the query if any are found.
571  *
572  * Parameters:
573  *	CCIMObjectPath *op - An CCIMObjectPath * which contains the
574  *	information on the class for which to find the instances.
575  *
576  * 	selectList - Not used
577  *	nonJoinExp - Not used
578  *
579  * Returns:
580  *	CCIMInstance * if matched instance is found. Otherwise, NULL.
581  */
582 /*
583  * Currently, there is no WQL parser for the C providers. As a result,
584  * what is returned to the CIMOM is a list of instances with
585  * a NULL value at the beginning of the list. This NULL value indicates
586  * to the CIMOM that it must do the filtering for the client.
587  */
588 
589 /* ARGSUSED */
590 CCIMInstanceList*
cp_execQuery_Solaris_MPXIOComponent(CCIMObjectPath * op,cimchar * selectList,cimchar * nonJoinExp,cimchar * queryExp,int queryType)591 cp_execQuery_Solaris_MPXIOComponent(CCIMObjectPath *op,
592     cimchar *selectList, cimchar *nonJoinExp, cimchar *queryExp, int queryType)
593 {
594 	CCIMInstanceList	*instList = NULL;
595 	CCIMInstanceList	*result;
596 	CCIMInstance		*emptyInst;
597 	CCIMException		*ex;
598 	int			error;
599 
600 	if (op == NULL) {
601 	    util_handleError(MPXIO_EXECQUERY, CIM_ERR_INVALID_PARAMETER, NULL,
602 		NULL, &error);
603 	    return ((CCIMInstanceList *)NULL);
604 	}
605 
606 	instList = cp_enumInstances_Solaris_MPXIOComponent(op);
607 
608 	if (instList == NULL) {
609 	    return ((CCIMInstanceList *)NULL);
610 	}
611 	/*
612 	 * Create a null instance and add it to the beginning
613 	 * of the list to indicate to the CIMOM that no filtering
614 	 * was done.
615 	 */
616 
617 	emptyInst = cim_createInstance("");
618 	if (emptyInst == NULL) {
619 	    ex = cim_getLastError();
620 	    util_handleError(MPXIO_EXECQUERY, CIM_ERR_FAILED,
621 		CREATE_INSTANCE_FAILURE, ex, &error);
622 	    return ((CCIMInstanceList *)NULL);
623 	}
624 
625 	result = cim_createInstanceList();
626 	if (result == NULL) {
627 	    ex = cim_getLastError();
628 	    util_handleError(MPXIO_EXECQUERY, CIM_ERR_FAILED,
629 		CREATE_INSTANCE_LIST_FAILURE, ex, &error);
630 	    cim_freeInstance(emptyInst);
631 	    cim_freeInstanceList(instList);
632 	    return ((CCIMInstanceList *)NULL);
633 	}
634 
635 	result = cim_addInstance(result, emptyInst);
636 	if (result == NULL) {
637 	    ex = cim_getLastError();
638 	    util_handleError(MPXIO_EXECQUERY, CIM_ERR_FAILED,
639 		ADD_INSTANCE_FAILURE, ex, &error);
640 	    cim_freeInstance(emptyInst);
641 	    cim_freeInstanceList(instList);
642 	    return ((CCIMInstanceList *)NULL);
643 	}
644 
645 	/*
646 	 * Since copying the original list to the new list will
647 	 * leave no way to free the original list, manually
648 	 * concatenate the original list to the new one.
649 	 */
650 
651 	result->mNext = instList;
652 	return (result);
653 }
654 
655 /*
656  * Name: cp_associators_Solaris_MPXIOComponent
657  *
658  * Description:
659  * Returns instances of objects associated with the passed in
660  * object if there are any.
661  *
662  * Parameters:
663  *
664  *	CCIMObjectPath *pAssocName - The name of the association that
665  *	the client wants information about.
666  *
667  *	CCIMObjectPath *pObjectName - An CCIMObjectPath * which contains the
668  *	information on the class for which to find the associated instances.
669  *
670  *	cimchar *pResultClass - If specified, only return instances that
671  *	are of this class type.
672  *
673  *      cimchar *pRole - If specified, must be valid for the object path
674  *	passed in requesting the associated instances.
675  *
676  *	cimchar *pResultRole - If specified, only return instances that
677  *	are playing this role in the association.
678  *
679  *
680  * Returns:
681  *	CCIMInstanceList * if associated objects are found.
682  *	Otherwise, NULL is returned.
683  */
684 
685 /* ARGSUSED */
686 CCIMInstanceList *
cp_associators_Solaris_MPXIOComponent(CCIMObjectPath * pAssocName,CCIMObjectPath * pObjectName,cimchar * pResultClass,cimchar * pRole,cimchar * pResultRole)687 cp_associators_Solaris_MPXIOComponent(CCIMObjectPath *pAssocName,
688     CCIMObjectPath *pObjectName, cimchar *pResultClass, cimchar *pRole,
689 	cimchar *pResultRole)
690 {
691 	CCIMPropertyList	*pCurPropList;
692 	CCIMInstanceList	*instList = NULL;
693 	CCIMException		*ex;
694 	dm_descriptor_t		*assoc_descriptors;
695 	dm_descriptor_t		obj_desc;
696 	char			*name;
697 	int			error = 0;
698 	int			isGroup = 0;
699 
700 	if (pObjectName == NULL ||
701 	    ((pCurPropList = pObjectName->mKeyProperties) == NULL)) {
702 	    util_handleError(MPXIO_ASSOCIATORS, CIM_ERR_INVALID_PARAMETER, NULL,
703 		NULL, &error);
704 	    return ((CCIMInstanceList *)NULL);
705 	}
706 
707 	if (strcasecmp(pObjectName->mName, MPXIO_CONTROLLER) == 0) {
708 	    isGroup = 1;
709 	}
710 
711 	if (pRole != NULL) {
712 	    if (strcasecmp(pRole, GROUP) == 0) {
713 		if (isGroup != 1) {
714 		    util_handleError(MPXIO_ASSOCIATORS,
715 			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
716 		    return ((CCIMInstanceList *)NULL);
717 		}
718 	    }
719 	}
720 
721 	/*
722 	 * Both mpxio controller and the paths have deviceid as the
723 	 * key.
724 	 */
725 
726 	name = (cimchar *)util_getKeyValue(pCurPropList, string, DEVICEID,
727 	    &error);
728 	if (error != 0) {
729 	    util_handleError(MPXIO_ASSOCIATORS, CIM_ERR_INVALID_PARAMETER, NULL,
730 		NULL, &error);
731 	    return ((CCIMInstanceList *)NULL);
732 	}
733 
734 	if (isGroup == 1) {
735 	    obj_desc = dm_get_descriptor_by_name(DM_CONTROLLER, name,
736 		&error);
737 	} else {
738 	    obj_desc = dm_get_descriptor_by_name(DM_PATH, name,
739 		&error);
740 	}
741 	if (error == ENODEV || obj_desc == NULL) {
742 	    return ((CCIMInstanceList *)NULL);
743 	}
744 	if (error != 0) {
745 	    util_handleError(MPXIO_ASSOCIATORS,  CIM_ERR_FAILED,
746 		DM_GET_ASSOC_FAILURE, NULL, &error);
747 	    return ((CCIMInstanceList *)NULL);
748 	}
749 
750 	if (isGroup) {
751 		/*
752 		 * Get associated descriptors.
753 		 */
754 	    assoc_descriptors = dm_get_associated_descriptors(obj_desc,
755 		DM_PATH, &error);
756 	    dm_free_descriptor(obj_desc);
757 
758 	    if (assoc_descriptors == NULL) {
759 		return ((CCIMInstanceList *)NULL);
760 	    }
761 
762 	    if (assoc_descriptors[0] == NULL) {
763 		dm_free_descriptors(assoc_descriptors);
764 		return ((CCIMInstanceList *)NULL);
765 	    }
766 
767 	    if (error != 0) {
768 		util_handleError(MPXIO_ASSOCIATORS,  CIM_ERR_FAILED,
769 		    DM_GET_ASSOC_FAILURE, NULL, &error);
770 		return ((CCIMInstanceList *)NULL);
771 	    }
772 		/*
773 		 * Generate the inst list of the associated paths.
774 		 */
775 	    instList = ctrl_descriptors_toCCIMInstanceList(SCSI_CONTROLLER,
776 		assoc_descriptors, &error, 1, "scsi");
777 	    dm_free_descriptors(assoc_descriptors);
778 
779 	    if (error != 0) {
780 		ex = cim_getLastError();
781 		util_handleError(MPXIO_ASSOCIATORS, CIM_ERR_FAILED,
782 		    SCSICTRL_DESC_TO_INSTANCE_FAILURE, ex, &error);
783 		return ((CCIMInstanceList *)NULL);
784 	    }
785 	} else {
786 		/*
787 		 * This is the underlying ctrl calling this function. Return
788 		 * the controllers that are associated with this disk.
789 		 */
790 
791 	    assoc_descriptors = dm_get_associated_descriptors(obj_desc,
792 		DM_CONTROLLER, &error);
793 	    dm_free_descriptor(obj_desc);
794 
795 	    if (assoc_descriptors == NULL) {
796 		return ((CCIMInstanceList *)NULL);
797 	    }
798 
799 	    if (assoc_descriptors[0] == NULL) {
800 		dm_free_descriptors(assoc_descriptors);
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 	    instList = ctrl_descriptors_toCCIMInstanceList(MPXIO_CONTROLLER,
810 		assoc_descriptors, &error, 1, "scsi_vhci");
811 	    dm_free_descriptors(assoc_descriptors);
812 
813 	    if (error != 0) {
814 		util_handleError(MPXIO_ASSOCIATORS, CIM_ERR_FAILED,
815 		    MPXIOCTRL_DESC_TO_INSTANCE_FAILURE, NULL, &error);
816 		return ((CCIMInstanceList *)NULL);
817 	    }
818 	}
819 	return (instList);
820 }
821 
822 /*
823  * Name: cp_associatorNames_Solaris_MPXIOComponent
824  *
825  * Description:
826  * Returns a list of objects associated with the passed in
827  * object if there are any via the object CCIMObjectPath.
828  *
829  * Parameters:
830  *
831  *	CCIMObjectPath *pAssocName - The name of the association that
832  *	the client wants information about.
833  *
834  *	CCIMObjectPath *pObjectName - An CCIMObjectPath * which contains the
835  *	information on the class for which to find the associated instances.
836  *
837  *	cimchar *pResultClass - If specified, only return instances that
838  *	are of this class type.
839  *
840  *      cimchar *pRole - If specified, must be valid for the object path
841  *	passed in requesting the associated instances.
842  *
843  *	cimchar *pResultRole - If specified, only return instances that
844  *	are playing this role in the association.
845  *
846  *
847  * Returns:
848  *	CCIMObjectPathList * if associated objects are found.
849  *	Otherwise, NULL is returned.
850  */
851 
852 /* ARGSUSED */
853 CCIMObjectPathList *
cp_associatorNames_Solaris_MPXIOComponent(CCIMObjectPath * pAssocName,CCIMObjectPath * pObjectName,cimchar * pResultClass,cimchar * pRole,cimchar * pResultRole)854 cp_associatorNames_Solaris_MPXIOComponent(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 	instList =
869 	    cp_associators_Solaris_MPXIOComponent(
870 		pAssocName, pObjectName, pResultClass, pRole, pResultRole);
871 
872 	if (instList != NULL) {
873 	    objList = cim_createObjectPathList(instList);
874 	    cim_freeInstanceList(instList);
875 	}
876 	return (objList);
877 }
878 
879 /*
880  * Name: cp_references_Solaris_MPXIOComponent
881  *
882  * Description:
883  * Returns instances of objects that have references to the passed in
884  * object if there are any.
885  *
886  * Parameters:
887  *
888  *	CCIMObjectPath *pAssocName - The name of the association that
889  *	the client wants information about.
890  *
891  *	CCIMObjectPath *pObjectName - An CCIMObjectPath * which contains the
892  *	information on the class for which to find the associated instances.
893  *
894  *      cimchar *pRole - If specified, must be valid for the object path
895  *	passed in requesting the associated instances.
896  *
897  * Returns:
898  *	CCIMInstanceList * if associated objects are found. Thist list
899  *	may be empty. NULL is returned on error.
900  */
901 
902 /* ARGSUSED */
903 CCIMInstanceList *
cp_references_Solaris_MPXIOComponent(CCIMObjectPath * pAssocName,CCIMObjectPath * pObjectName,char * pRole)904 cp_references_Solaris_MPXIOComponent(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 	/*
919 	 * Get the list of those objects that are referred to by
920 	 * the calling object.
921 	 */
922 
923 	objList =
924 	    cp_associatorNames_Solaris_MPXIOComponent(
925 		pAssocName, pObjectName, NULL, NULL, NULL);
926 
927 	if (objList == NULL) {
928 	    return ((CCIMInstanceList *)NULL);
929 	}
930 
931 	/*
932 	 * Now generate the list of instances to return.
933 	 */
934 
935 	if ((strcasecmp(pObjectName->mName, MPXIO_CONTROLLER)) == 0) {
936 	    instList = mpxioCompToInstList(pObjectName,
937 		ANTECEDENT, objList, DEPENDENT, &error);
938 	} else {
939 	    instList = mpxioCompToInstList(pObjectName,
940 		DEPENDENT, objList, ANTECEDENT, &error);
941 	}
942 
943 	cim_freeObjectPathList(objList);
944 	return (instList);
945 }
946 
947 /*
948  * Name: cp_referenceNames_Solaris_MPXIOComponent
949  *
950  * Description:
951  * Returns a instances of objects that have references to the passed in
952  * object if there are any.
953  *
954  * Parameters:
955  *
956  *	CCIMObjectPath *pAssocName - The name of the association that
957  *	the client wants information about.
958  *
959  *	CCIMObjectPath *pObjectName - An CCIMObjectPath * which contains the
960  *	information on the class for which to find the associated instances.
961  *
962  *      cimchar *pRole - If specified, must be valid for the object path
963  *	passed in requesting the associated instances.
964  *
965  *
966  * Returns:
967  *	CCIMObjectPathList * if associated objects are found. Otherwise, NULL.
968  *
969  */
970 
971 /* ARGSUSED */
972 CCIMObjectPathList *
cp_referenceNames_Solaris_MPXIOComponent(CCIMObjectPath * pAssocName,CCIMObjectPath * pObjectName,cimchar * pRole)973 cp_referenceNames_Solaris_MPXIOComponent(CCIMObjectPath *pAssocName,
974     CCIMObjectPath *pObjectName, cimchar *pRole)
975 {
976 
977 	CCIMInstanceList	*instList;
978 	CCIMObjectPathList	*objList = NULL;
979 	int			error;
980 
981 	if (pObjectName == NULL) {
982 	    util_handleError(MPXIO_REFERENCENAMES,
983 		CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
984 	    return ((CCIMObjectPathList *)NULL);
985 	}
986 	instList =
987 	    cp_references_Solaris_MPXIOComponent(pAssocName,
988 		pObjectName, pRole);
989 
990 	if (instList != NULL) {
991 	    objList = cim_createObjectPathList(instList);
992 	    cim_freeInstanceList(instList);
993 	}
994 	return (objList);
995 }
996 
997 /*
998  * Create the association class with the passed in attributes.
999  */
1000 static
1001 CCIMInstanceList  *
mpxioCompToInstList(CCIMObjectPath * pObjectName,cimchar * pObjectNameRole,CCIMObjectPathList * objList,cimchar * objRole,int * error)1002 mpxioCompToInstList(CCIMObjectPath *pObjectName, cimchar *pObjectNameRole,
1003 	CCIMObjectPathList *objList, cimchar *objRole, int *error)
1004 {
1005 
1006 	CCIMObjectPathList	*tmpList;
1007 	CCIMInstanceList	*instList = NULL;
1008 	CCIMInstance		*inst;
1009 	CCIMObjectPath		*obj1;
1010 	CCIMObjectPath		*obj2;
1011 	CCIMException		*ex;
1012 
1013 	*error = 0;
1014 
1015 	/*
1016 	 * If no objects associated with this one, return NULL.
1017 	 */
1018 	if (objList == NULL) {
1019 	    return ((CCIMInstanceList *)NULL);
1020 	}
1021 
1022 	instList = cim_createInstanceList();
1023 	if (instList == NULL) {
1024 	    ex = cim_getLastError();
1025 	    util_handleError(MPXIO_COMPONENT, CIM_ERR_FAILED,
1026 		CREATE_INSTANCE_FAILURE, ex, error);
1027 	    return ((CCIMInstanceList *)NULL);
1028 	}
1029 
1030 	tmpList = objList;
1031 	while (tmpList != NULL) {
1032 	    obj1 = tmpList->mDataObject;
1033 	    obj2 = cim_copyObjectPath(pObjectName);
1034 	    if (obj2 == NULL) {
1035 		ex = cim_getLastError();
1036 		util_handleError(MPXIO_COMPONENT, CIM_ERR_FAILED,
1037 		    COPY_OBJPATH_FAILURE, ex, error);
1038 		return ((CCIMInstanceList *)NULL);
1039 	    }
1040 
1041 	    inst = mpxioCompToInst(obj1, objRole, obj2, pObjectNameRole,
1042 		error);
1043 	    cim_freeObjectPath(obj2);
1044 	    if (*error != 0) {
1045 		util_handleError(MPXIO_COMPONENT, CIM_ERR_FAILED,
1046 		    MPXIOINT_ASSOC_TO_INSTANCE_FAILURE, NULL, error);
1047 		cim_freeInstanceList(instList);
1048 		return ((CCIMInstanceList *)NULL);
1049 	    }
1050 
1051 	    instList = cim_addInstance(instList, inst);
1052 	    if (instList == NULL) {
1053 		ex = cim_getLastError();
1054 		util_handleError(MPXIO_COMPONENT, CIM_ERR_FAILED,
1055 		    ADD_INSTANCE_FAILURE, ex, error);
1056 		cim_freeInstance(inst);
1057 		return ((CCIMInstanceList *)NULL);
1058 	    }
1059 	    tmpList = tmpList->mNext;
1060 	}
1061 	return (instList);
1062 }
1063 
1064 /*
1065  * Create an instance of an mpxio group object.
1066  */
1067 static
1068 CCIMInstance  *
mpxioCompToInst(CCIMObjectPath * obj1,cimchar * obj1Role,CCIMObjectPath * obj2,cimchar * obj2Role,int * error)1069 mpxioCompToInst(CCIMObjectPath *obj1, cimchar *obj1Role,
1070 	CCIMObjectPath *obj2, cimchar *obj2Role, int *error)
1071 {
1072 
1073 	CCIMInstance	*inst = NULL;
1074 	CCIMException	*ex;
1075 
1076 	*error = 0;
1077 	inst = cim_createInstance(MPXIO_COMPONENT);
1078 	if (inst == NULL) {
1079 	    ex = cim_getLastError();
1080 	    util_handleError(MPXIO_COMPONENT, CIM_ERR_FAILED,
1081 		MPXIOINT_ASSOC_TO_INSTANCE_FAILURE, ex, error);
1082 	    return ((CCIMInstance *)NULL);
1083 	}
1084 
1085 	util_doReferenceProperty(obj2Role, obj2, cim_true, inst, error);
1086 	util_doReferenceProperty(obj1Role, obj1, cim_true, inst, error);
1087 	if (*error != 0) {
1088 	    ex = cim_getLastError();
1089 	    util_handleError(MPXIO_COMPONENT, CIM_ERR_FAILED,
1090 		CREATE_REFPROP_FAILURE, ex, error);
1091 	    cim_freeInstance(inst);
1092 	    return ((CCIMInstance *)NULL);
1093 	}
1094 	return (inst);
1095 }
1096