PageRenderTime 302ms CodeModel.GetById 247ms app.highlight 48ms RepoModel.GetById 1ms app.codeStats 1ms

/usr/src/cmd/wbem/provider/c/wbem_disk/assoc/Solaris_MPXIOInterface.c

https://bitbucket.org/osunix/osunix-gate
C | 1101 lines | 643 code | 138 blank | 320 comment | 163 complexity | 54db1f1cb84d2beb7b07eb615a65a10f MD5 | raw file
   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
  57static
  58CCIMInstanceList *
  59mpxioIntAssocToInstList(CCIMObjectPath *pObjectName, cimchar *pObjectNameRole,
  60	CCIMObjectPathList *objList, cimchar *objRole, int *error);
  61
  62static
  63CCIMInstance  *
  64mpxioIntAssocToInst(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
  88CCIMInstance*
  89cp_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 */
 215CCIMInstanceList*
 216cp_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
 422CCIMObjectPathList*
 423cp_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 */
 456CCIMObjectPath*
 457cp_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 */
 473CIMBool
 474cp_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 */
 496CCIMProperty	*
 497cp_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 */
 525CIMBool
 526cp_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 */
 540CIMBool
 541cp_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 */
 555CCIMProperty*
 556cp_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 */
 589CCIMInstanceList*
 590cp_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 */
 684CCIMInstanceList *
 685cp_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 */
 853CCIMObjectPathList *
 854cp_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 */
 903CCIMInstanceList *
 904cp_references_Solaris_MPXIOInterface(CCIMObjectPath *pAssocName,
 905CCIMObjectPath *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 */
 970CCIMObjectPathList *
 971cp_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 */
 999static
1000CCIMInstanceList  *
1001mpxioIntAssocToInstList(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
1063static
1064CCIMInstance  *
1065mpxioIntAssocToInst(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}