Exemple #1
0
CMPIStatus CWS_DirectoryCreateInstance( CMPIInstanceMI * mi, 
                    const CMPIContext * ctx, 
                    const CMPIResult * rslt, 
                    const CMPIObjectPath * cop, 
                    const CMPIInstance * ci) 
{
  CMPIStatus st = {CMPI_RC_OK,NULL};
  CWS_FILE   filebuf;
  CMPIData   data;

  if (!silentMode()) fprintf(stderr,"--- CWS_DirectoryCreateInstance() \n");

  data = CMGetProperty(ci,"Name",NULL);
  if (!CMGetCharsPtr(data.value.string, NULL) ||
      strncmp(CMGetCharsPtr(data.value.string, NULL),CWS_FILEROOT,
          strlen(CWS_FILEROOT))) {
    CMSetStatusWithChars(_broker,&st,CMPI_RC_ERR_FAILED,
             "Invalid path name");
  } else if (!makeFileBuf(ci,&filebuf) || !CWS_Create_Directory(&filebuf)) {
    CMSetStatusWithChars(_broker,&st,CMPI_RC_ERR_FAILED,
             "Could not create instance");
  }

  return st;
}
/**
    Create Instance from inst, using object-path op as reference.
*/
CMPIStatus TestInstanceProviderCreateInstance (
    CMPIInstanceMI * mi,
    const CMPIContext * ctx,
    const CMPIResult * rslt,
    const CMPIObjectPath * cop,
    const CMPIInstance * ci)
{
    CMPIStatus rc = { CMPI_RC_OK, NULL };
    CMPIInstance * inst;
    CMPIValue value_inst;
    CMPIData key1,key2, retInst;
    CMPIObjectPath *obp;
    unsigned int j = 0;
    if(ci)
    {
        /* clone the instance to be added to the array */
        inst = CMClone(ci, &rc);
        key1 = CMGetProperty(inst, "Identifier", &rc);
        for (j=0; j < numOfInst ; j++)
        {
            /* check for validity of Instance, that its not deleted */
            if (valid[j] == 1)
            {
                /* get element(instance) from array */
                retInst = CMGetArrayElementAt(clone_arr_ptr, j, &rc);
                /* get object-path of instance */
                obp = CMGetObjectPath(retInst.value.inst, &rc);
                /* get key from this object-path */
                key2 = CMGetKey(obp, "Identifier", &rc);
                /*compare key values.
                  If they match throw exception as two instance with same key
                  properties cannot exists. */
                if(key1.value.uint8 == key2.value.uint8)
                {
		  CMRelease(inst);
                    CMReturn (CMPI_RC_ERR_ALREADY_EXISTS);
                }
            }
        }
        value_inst.inst = inst;
        /* If instance doesnot exists in array add it */
        rc = CMSetArrayElementAt(
            clone_arr_ptr,
            numOfInst,
            &value_inst,
            CMPI_instance);
        valid[numOfInst]=1;
        numOfInst++;
        /* return object-path of instance */
        CMReturnObjectPath(rslt, cop);
        CMReturnDone(rslt);
    }
    else
    {
        CMReturn (CMPI_RC_ERR_NOT_SUPPORTED);
    }
    CMRelease(inst);
    CMReturn (CMPI_RC_OK);
}
/**
    Replace an existing Instance from inst, using object-path op as reference.
*/
CMPIStatus TestInstanceProviderModifyInstance  (
    CMPIInstanceMI * mi,
    const CMPIContext * ctx,
    const CMPIResult * rslt,
    const CMPIObjectPath * cop,
    const CMPIInstance * ci,
    const char **properties)
{
    CMPIStatus rc = { CMPI_RC_OK, NULL };
    CMPIInstance * inst;
    CMPIValue val1, val2;
    CMPIData key1, key2, retData1, retInst;
    CMPIObjectPath *obp;
    unsigned int j = 0, flag = 0;
    if(ci)
    {
        inst = CMClone(ci, &rc);
        /* get key from the object-path */
        key1 = CMGetKey(cop, "Identifier", &rc);
        val1.uint8 = key1.value.uint8;
        /* get the value of Message property */
        retData1 = CMGetProperty(inst, "Message", &rc);
        val2.string = retData1.value.string;
        for (j=0; j < numOfInst; j++)
        {
            /* check for validity of Instance, that its not deleted */
            if (valid[j] == 1)
            {
                /* get element(instance) from array */
                retInst = CMGetArrayElementAt(clone_arr_ptr, j, &rc);
                /* get object-path of instance */
                obp = CMGetObjectPath(retInst.value.inst, &rc);
                /* get key from this object-path */
                key2 = CMGetKey(obp, "Identifier", &rc);
                /*compare key values.
                  If they match then set the properties received from client */
                if(key1.value.uint8 == key2.value.uint8)
                {
                    CMSetProperty(
                        retInst.value.inst,
                        "Message",
                        &val2,
                        CMPI_string);
                    flag = 1;
                }
            }
        }
        CMRelease(inst);
        /*If match fails, throw exception, as instance to be mmodified is not
          found */
        if(!flag)
        {
            CMReturn (CMPI_RC_ERR_NOT_FOUND);
        }
    }
    CMReturnDone (rslt);
    CMReturn (CMPI_RC_OK);
}
Exemple #4
0
int makeFileBuf(const CMPIInstance *instance, CWS_FILE *cwsf)
{
  CMPIData dt;
  CMPIStatus rc = {CMPI_RC_OK,NULL};
  if (instance && cwsf) {
    dt=CMGetProperty(instance,"Name",&rc);
    if (rc.rc == CMPI_RC_OK)
    {
        // Name needs be valid before copied using strcpy
        if (CMPI_goodValue == dt.state)
        {
            strcpy(cwsf->cws_name,CMGetCharsPtr(dt.value.string,NULL));
        }
    }
    dt=CMGetProperty(instance,"FileSize",&rc);
    if (rc.rc == CMPI_RC_OK)
    {
        cwsf->cws_size=dt.value.uint64;
    }
#ifndef SIMULATED
     dt=CMGetProperty(instance,"CreationDate",&rc);
     if (rc.rc == CMPI_RC_OK)
     {
         cwsf->cws_ctime=CMGetBinaryFormat(dt.value.dateTime,NULL);
     }
    dt=CMGetProperty(instance,"LastModified",&rc);
    if (rc.rc == CMPI_RC_OK)
    {
        cwsf->cws_mtime=CMGetBinaryFormat(dt.value.dateTime,NULL);
    }
    dt=CMGetProperty(instance,"LastAccessed",&rc);
    if (rc.rc == CMPI_RC_OK)
    {
        cwsf->cws_atime=CMGetBinaryFormat(dt.value.dateTime,NULL);
    }
#endif
    dt=CMGetProperty(instance,"Readable",&rc);
    if (rc.rc == CMPI_RC_OK)
    {
        cwsf->cws_mode=dt.value.boolean ? 0400 : 0;
    }
    dt=CMGetProperty(instance,"Writeable",&rc);
    if (rc.rc == CMPI_RC_OK)
    {
        cwsf->cws_mode+=(dt.value.boolean ? 0200 : 0);
    }
    dt=CMGetProperty(instance,"Executable",&rc);
    if (rc.rc == CMPI_RC_OK)
    {
        cwsf->cws_mode+=(dt.value.boolean ? 0100 : 0);
    }
    return 1;
  }
  return 0;
}
void
filterInternalProps(CMPIInstance* ci) 
{

  CMPIStatus      pst = { CMPI_RC_OK, NULL };
  CMGetProperty(ci, "LastSequenceNumber", &pst);
  /* prop is set, need to clear it out */
  if (pst.rc != CMPI_RC_ERR_NOT_FOUND) {
    filterFlagProperty(ci, "LastSequenceNumber");
  }
  CMGetProperty(ci, "SequenceContext", &pst);
  /* prop is set, need to clear it out */
  if (pst.rc != CMPI_RC_ERR_NOT_FOUND) {
    filterFlagProperty(ci, "SequenceContext");
  }

  return;
}
int kvp_rasd_to_kvp_rec(
    const CMPIBroker *broker,
    CMPIInstance *kvp_rasd,
    kvp *kvp_rec,
    CMPIStatus *status)
{

    CMPIStatus local_status = {CMPI_RC_OK, NULL};
    CMPIData propertyvalue;

    kvp_rec = malloc(sizeof(kvp));

    if(kvp_rec == NULL)
    {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
                     ("--- Cannot malloc memory for kvp record"));
        CMSetStatusWithChars(broker, status, CMPI_RC_ERROR_SYSTEM, "Unable to malloc memory");
        goto Error;
    }

    propertyvalue = CMGetProperty(kvp_rasd, "key", &local_status);
    if((local_status.rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue))
    {
        kvp_rec->key = strdup(CMGetCharPtr(propertyvalue.value.string));
    }
    propertyvalue = CMGetProperty(kvp_rasd, "value", &local_status);
    if((local_status.rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue))
    {
        kvp_rec->value = strdup(CMGetCharPtr(propertyvalue.value.string));
    }
    propertyvalue = CMGetProperty(kvp_rasd, "VM_ID", &local_status);
    if((local_status.rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue))
    {
        kvp_rec->vm_uuid = strdup(CMGetCharPtr(propertyvalue.value.string));
    }

    return 1;
Error:
    return 0;

}
Exemple #7
0
/*****************************************************************************
 * Modify a backend xen resource identified by the the CIM instance based
 * on the instance's properties
 *
 * @param in broker - CMPI factory service broker
 * @param in ft - xen backend provider function table
 * @param in res_id - opaque data identifying the CIM object being modified
 * @param in caller_id - CIM caller's credentials
 * @param in modified_res - modifed version of the xen resource
 * @param in properties - CIM properties that caller cares about
 * @return CMPIrc error codes
 *****************************************************************************/
CMPIrc prov_pxy_modify(
    const CMPIBroker *broker,
    const XenProviderInstanceFT* ft,
    const void *res_id,
    struct xen_call_context *caller_id, 
    const void *modified_res,
    const char **properties)
{
    (void)properties;
    CMPIData data;
    CMPIStatus status = {CMPI_RC_OK, NULL};
    char *inst_id;
    xen_utils_session *session = NULL;

    _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO,("Modify an Instance"));
    CMPIInstance *inst = (CMPIInstance *)res_id;
    if(CMIsNullObject(inst))  {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("input parameter res_id is invalid"));
        return CMPI_RC_ERR_FAILED;
    }
    CMPIObjectPath *op = CMGetObjectPath(inst, &status);
    CMPIString *cn = CMGetClassName(op, &status);

    /* Get target resource */
    const char *key_prop = ft->xen_resource_get_key_property(broker, CMGetCharPtr(cn));
    data = CMGetProperty(inst, key_prop, &status);
    if((status.rc != CMPI_RC_OK) || CMIsNullValue(data)) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Could not get target resource"));
        return CMPI_RC_ERR_FAILED;
    }
    inst_id = CMGetCharPtr(data.value.string);
    if((inst_id == NULL) || (*inst_id == '\0')) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Could not get inst id"));
        return CMPI_RC_ERR_FAILED;
    }
    if(!xen_utils_validate_session(&session, caller_id)) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("--- Unable to establish connection with Xen"));
        return CMPI_RC_ERR_FAILED;
    }

    /* Call the target provider */
    status.rc = ft->xen_resource_modify(broker, res_id, modified_res, properties, status, inst_id, session);

    xen_utils_cleanup_session(session);
    return status.rc;
}
Exemple #8
0
/*****************************************************************************
 * Delete a backend xen resource identified by the the CIM instance
 *
 * @param in broker - CMPI factory service broker
 * @param in ft - xen backend provider function table
 * @param in res_id - opaque data identifying the CIM object being deleted
 * @param in caller_id - CIM caller's credentials
 * @return CMPIrc error codes
 *****************************************************************************/
CMPIrc prov_pxy_delete(
    const CMPIBroker *broker,
    const XenProviderInstanceFT* ft,
    const void *res_id, 
    struct xen_call_context *caller_id
    )
{
    CMPIInstance *inst = (CMPIInstance *)res_id;
    CMPIData data;
    CMPIStatus status = {CMPI_RC_OK, NULL};

    _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Delete an instance"));
    CMPIObjectPath *op = CMGetObjectPath(inst, &status);
    CMPIString *cn = CMGetClassName(op, &status);

    xen_utils_session *session = NULL;   
    if(CMIsNullObject(inst)) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Invalid parameter"));
        return CMPI_RC_ERR_FAILED;
    }

    const char *key_prop = ft->xen_resource_get_key_property(broker, CMGetCharPtr(cn));
    data = CMGetProperty(inst, key_prop ,&status); 
    if((status.rc != CMPI_RC_OK) || CMIsNullValue(data)) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Could not get property"));
        return CMPI_RC_ERR_FAILED;
    }

    char *inst_id = CMGetCharPtr(data.value.string);       
    if((inst_id == NULL) || (*inst_id == '\0')) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Could not get inst id"));
        return CMPI_RC_ERR_FAILED;
    }

    if(!xen_utils_validate_session(&session, caller_id)) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,("Unable to establish connection with Xen"));  
        return CMPI_RC_ERR_FAILED;                             
    }
    /* get the object and delete it */
    status.rc = ft->xen_resource_delete(broker, session, inst_id);

    xen_utils_cleanup_session(session);
    return status.rc;
}
Exemple #9
0
CMPIStatus TestCMPIBrokerInstanceProviderExecQuery (CMPIInstanceMI * mi,
    const CMPIContext * ctx,
    const CMPIResult * rslt,
    const CMPIObjectPath * ref,
    const char *lang,
    const char *query)
{
    CMPIData retData;
    CMPIString* type;
    CMPIBoolean bol=0;
    CMPIStatus rc = {CMPI_RC_OK, NULL};

    PROV_LOG_OPEN (_ClassName, _ProviderLocation);
    PROV_LOG ("ExecQuery");
    retData = CMGetProperty(_inst, "n64", &rc);
    PROV_LOG("++++ Status of CMGetProperty : (%s)",
        strCMPIStatus(rc));
    PROV_LOG("n64 = %" PEGASUS_64BIT_CONVERSION_WIDTH "u",
        retData.value.uint64);

    type = CDGetType (_broker, rslt, &rc);
    PROV_LOG ("++++ Status of mbEncGetType with input of type "
        "CMPIResult with CMPI_ResultExecQueryOnStack_Ftab : (%s) type(%s)",
        strCMPIStatus (rc),
        CMGetCharsPtr(type, NULL));

    bol = CDIsOfType (_broker, rslt, "CMPIResult", &rc);
    if ( bol )
    {
        PROV_LOG ("++++ CDIsOfType for CMPIResult with "
            "CMPI_ResultExecQueryOnStack_Ftab status is (%s) : %d",
            strCMPIStatus (rc),
            bol);
    }
 
    PROV_LOG_CLOSE();
    CMReturnInstance(rslt, _inst);
    CMReturnDone(rslt);
    CMReturn (CMPI_RC_OK);
}
CMPIStatus
deliverInd(const CMPIObjectPath * ref, const CMPIArgs * in, CMPIInstance * ind)
{
  _SFCB_ENTER(TRACE_INDPROVIDER, "deliverInd");
  CMPIInstance   *hci,
                 *sub;
  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIString     *dest;
  char            strId[64];
  ExpSegments     xs;
  UtilStringBuffer *sb;
  static int      id = 1;
  char           *resp;
  char           *msg;

  if ((hci = internalProviderGetInstance(ref, &st)) == NULL) {
    setStatus(&st, CMPI_RC_ERR_NOT_FOUND, NULL);
    _SFCB_RETURN(st);
  }
  dest = CMGetProperty(hci, "destination", NULL).value.string;
  _SFCB_TRACE(1, ("--- destination: %s\n", (char *) dest->hdl));
  sub = CMGetArg(in, "subscription", NULL).value.inst;

  sprintf(strId, "%d", id++);
  xs = exportIndicationReq(ind, strId);
  sb = segments2stringBuffer(xs.segments);
  if (exportIndication
      ((char *) dest->hdl, (char *) sb->ft->getCharPtr(sb), &resp, &msg)) {
    setStatus(&st, CMPI_RC_ERR_FAILED, NULL);
  }
  RespSegment     rs = xs.segments[5];
  UtilStringBuffer *usb = (UtilStringBuffer *) rs.txt;
  CMRelease(usb);
  CMRelease(sb);
  if (resp)
    free(resp);
  if (msg)
    free(msg);
  _SFCB_RETURN(st);
}
int refillRetryQ (const CMPIContext * ctx)
{
  _SFCB_ENTER(TRACE_INDPROVIDER, "refillRetryQ");  
  int qfill=0;
  if (RQhead==NULL) {
    // The queue is empty, check if there are instances to be restored
    CMPIObjectPath * op=CMNewObjectPath(_broker,"root/interop","SFCB_IndicationElement",NULL);
    CMPIEnumeration * enm = _broker->bft->enumerateInstances(_broker, ctx, op, NULL, NULL);
    while(enm && enm->ft->hasNext(enm, NULL)) {
    // get the properties from the repo instance
      CMPIData inst=CMGetNext(enm,NULL);
      CMPIData indID=CMGetProperty(inst.value.inst,"indicationID",NULL);
      CMPIData rcount=CMGetProperty(inst.value.inst,"retryCount",NULL);
      CMPIData last=CMGetProperty(inst.value.inst,"lastDelivery",NULL);
      CMPIData ind=CMGetProperty(inst.value.inst,"ind",NULL);
      CMPIData sub=CMGetProperty(inst.value.inst,"sub",NULL);
      CMPIData ld=CMGetProperty(inst.value.inst,"ld",NULL);
      _SFCB_TRACE(1,("--- Requeueing indication id:%d",indID.value.Int));
      // Rebuild the queue element
      RTElement *element;
      element = (RTElement *) malloc(sizeof(*element));
      element->instanceID=indID.value.Int;
      element->lasttry=last.value.Int;
      element->count=rcount.value.Int;
      element->ind=ind.value.ref->ft->clone(ind.value.ref,NULL);
      element->ref=ld.value.ref->ft->clone(ld.value.ref,NULL);
      element->sub=sub.value.ref->ft->clone(sub.value.ref,NULL);
      CMPIObjectPath * indele=CMGetObjectPath(inst.value.inst,NULL);
      element->SFCBIndEle=indele->ft->clone(indele,NULL);
      // call enq
      enqRetry(element,ctx,0);
      qfill=1;
    }
    // spawn thread if we queued anything
    if ((qfill == 1 ) && (retryRunning == 0)) {
      retryRunning=1;
      _SFCB_TRACE(1,("--- Starting retryExport thread"));
      pthread_attr_init(&tattr);
      pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
      CMPIContext * pctx = native_clone_CMPIContext(ctx);
      pthread_create(&t, &tattr,&retryExport,(void *) pctx);
    }
  }

  _SFCB_RETURN(0); 
}
Exemple #12
0
CMPIStatus TestCMPIBrokerInstanceProviderCreateInstance (CMPIInstanceMI * mi,
    const CMPIContext * ctx,
    const CMPIResult * rslt,
    const CMPIObjectPath * cop,
    const CMPIInstance * ci)
{
    const CMPIString* retNamespace;
    const CMPIString* retClassname;
    CMPIString* type;
    const char* str1;
    const char* str2;
    CMPIStatus rc = { CMPI_RC_OK, NULL };
    CMPIData retData;
    CMPIObjectPath *obj;
    CMPIBoolean bol = 0;

    PROV_LOG_OPEN (_ClassName, _ProviderLocation);
    PROV_LOG("CreateInstance");

    retNamespace = CMGetNameSpace(cop, &rc);
    retClassname = CMGetClassName(cop, &rc);
    str1 = CMGetCharsPtr(retNamespace, &rc);
    str2 = CMGetCharsPtr(retClassname, &rc);
    PROV_LOG("++++Obtained Namespace : (%s) Class (%s)", str1, str2);

    if(ci)
    { 
        /* Test to increase coverage in Broker_Enc.cpp*/
        type = CDToString (_broker, ci, &rc);
        PROV_LOG ("++++ Passing CMPIInstance with CMPI_InstanceOnStack_Ftab "
            "to mbEncToString successes : "
            "(%s)",
            strCMPIStatus (rc));    

        type = CDGetType (_broker, ci, &rc);
        PROV_LOG ("++++ Status of mbEncGetType with input of type CMPIInstance"
            " : (%s) type(%s)",
            strCMPIStatus (rc),
            CMGetCharsPtr(type, NULL));

        bol = CDIsOfType (_broker, ci, "CMPIInstance", &rc);
        if ( bol )
        {
            PROV_LOG ("++++ CDIsOfType for CMPIInstance with "
                "CMPI_InstanceOnStack_Ftab status is (%s) : %d",
                strCMPIStatus (rc),
                bol);
        }

        type = CDToString (_broker, cop, &rc);
        PROV_LOG ("++++ Passing CMPIObjectPath with "
            "CMPI_ObjectPathOnStack_Ftab to mbEncToString successes : (%s)",
            strCMPIStatus (rc));    

        type = CDGetType (_broker, cop, &rc);
        PROV_LOG ("++++ Status of mbEncGetType with input of type "
            "CMPIObjectPath : (%s) type(%s)",
            strCMPIStatus (rc),
            CMGetCharsPtr(type, NULL));

        bol = CDIsOfType (_broker, cop, "CMPIObjectPath", &rc);
        if ( bol )
        {
            PROV_LOG ("++++ CDIsOfType for CMPIObjectPath with "
                "CMPI_ObjectPathOnStack_Ftab status is (%s) : %d",
                strCMPIStatus (rc),
                bol);
        }

        type = CDGetType (_broker, rslt, &rc);
        PROV_LOG ("++++ Status of mbEncGetType with input of type "
            "CMPIResult with CMPI_ResultRefOnStack_Ftab : (%s) type(%s)",
            strCMPIStatus (rc),
            CMGetCharsPtr(type, NULL));

        bol = CDIsOfType (_broker, rslt, "CMPIResult", &rc);
        if ( bol )
        {
            PROV_LOG ("++++ CDIsOfType for CMPIResult with "
                "CMPI_ResultRefOnStack_Ftab status is (%s) : %d",
                strCMPIStatus (rc),
                bol);
        }

        _inst = CMClone(ci, &rc);
        PROV_LOG("++++ Status of CMClone(ci) : (%s)",
            strCMPIStatus(rc));
        CMSetObjectPath (_inst, cop);
        PROV_LOG("++++ Status of CMSetObjectPath(_inst) : (%s)",
            strCMPIStatus(rc));
        _setProperty1(_inst, "*");
        retData = CMGetProperty(_inst, "n64", &rc);
        PROV_LOG("++++ Status of CMGetProperty : (%s)",
            strCMPIStatus(rc));
        PROV_LOG("n64 = %" PEGASUS_64BIT_CONVERSION_WIDTH "u",
            retData.value.uint64);
        retData = CMGetProperty(_inst, "n32", &rc);
        PROV_LOG("++++ Status of CMGetProperty : (%s)",
            strCMPIStatus(rc));
        PROV_LOG("n32 = %d", retData.value.uint32);

        obj = CMGetObjectPath(_inst, &rc);
        PROV_LOG("++++ Status of CMGetObjectPath : (%s)",
            strCMPIStatus(rc));
        retNamespace = CMGetNameSpace(obj, &rc);
        PROV_LOG("++++ Status of CMGetNameSpace : (%s)",
            strCMPIStatus(rc));
        retClassname = CMGetClassName(obj, &rc);
        PROV_LOG("++++ Status of CMGetClassName : (%s)",
            strCMPIStatus(rc));
        str1 = CMGetCharsPtr(retNamespace, &rc);
        PROV_LOG("++++ Status of CMGetCharsPtr : (%s)",
            strCMPIStatus(rc));
        str2 = CMGetCharsPtr(retClassname, &rc);
        PROV_LOG("++++ Status of CMGetCharsPtr : (%s)",
            strCMPIStatus(rc));
        PROV_LOG("++++Namespace (_inst): (%s) Class (*%s)", str1, str2);
        retData = CMGetProperty(_inst, "n64", &rc);
        PROV_LOG("++++ Status of CMGetProperty : (%s)",
            strCMPIStatus(rc));
        PROV_LOG("n64 = %" PEGASUS_64BIT_CONVERSION_WIDTH "u",
            retData.value.uint64);
        PROV_LOG_CLOSE ();

        CMReturnObjectPath(rslt, cop);
        CMReturnDone(rslt);
        CMReturn (CMPI_RC_OK);
    }
    else
    {
        PROV_LOG_CLOSE ();
        CMReturn (CMPI_RC_ERR_NOT_SUPPORTED);
    }
}
static int
_testArrayTypes()
{
  struct array_types {
    CMPIType        element_type;
    CMPIType        typeA;
    char           *typeName;
    char           *typeAName;
    char           *args_name;
  } types_arr[] = {
    {
    CMPI_uint32,
          CMPI_uint32A,
          "CMPI_uint32", "CMPI_uint32A", "CMPI_uint32_array"}, {
    CMPI_uint16,
          CMPI_uint16A,
          "CMPI_uint16", "CMPI_uint16A", "CMPI_uint16_array"}, {
    CMPI_uint8,
          CMPI_uint8A, "CMPI_uint8", "CMPI_uint8A", "CMPI_uint8_array"}, {
    CMPI_uint64,
          CMPI_uint64A,
          "CMPI_uint64", "CMPI_uint64A", "CMPI_uint64_array"}, {
    CMPI_sint32,
          CMPI_sint32A,
          "CMPI_sint32", "CMPI_sint32A", "CMPI_sint32_array"}, {
    CMPI_sint16,
          CMPI_sint16A,
          "CMPI_sint16", "CMPI_sint16A", "CMPI_sint16_array"}, {
    CMPI_sint8,
          CMPI_sint8A, "CMPI_sint8", "CMPI_sint8A", "CMPI_sint8_array"}, {
    CMPI_sint64,
          CMPI_sint64A,
          "CMPI_sint64", "CMPI_sint64A", "CMPI_sint64_array"}, {
    CMPI_real32,
          CMPI_real32A,
          "CMPI_real32", "CMPI_real32A", "CMPI_real32_array"}, {
    CMPI_real64,
          CMPI_real64A,
          "CMPI_real64", "CMPI_real64A", "CMPI_real64_array"}, {
    CMPI_char16,
          CMPI_char16A,
          "CMPI_char16", "CMPI_char16A", "CMPI_char16_array"}, {
    CMPI_boolean,
          CMPI_booleanA,
          "CMPI_boolean", "CMPI_booleanA", "CMPI_boolean_array"}, {
    CMPI_string,
          CMPI_stringA,
          "CMPI_string", "CMPI_stringA", "CMPI_string_array"}, {
    CMPI_dateTime,
          CMPI_dateTimeA,
          "CMPI_dateTime", "CMPI_dateTimeA", "CMPI_dateTime_array"}, {
    CMPI_ref, CMPI_refA, "CMPI_ref", "CMPI_refA", "CMPI_ref_array"}, {
    CMPI_instance,
          CMPI_instanceA,
          "CMPI_instance", "CMPI_instanceA", "CMPI_instance_array"}, {
  CMPI_null, CMPI_ARRAY, "Invalid", "InvalidArray", "Invalid_array"}};

  int             i,
                  flag,
                  size;
  CMPIStatus      rc = { CMPI_RC_OK, NULL };
  CMPIStatus      rc1 = { CMPI_RC_OK, NULL };
  CMPIArray      *arr = NULL;
  CMPIString     *retNamespace = NULL;
  CMPIString     *retClassname = NULL;
  CMPIValue       value,
                  value1;
  CMPIData        data;
  CMPIData        arr_data;
  CMPIData        dataInst;
  CMPIData        retDataInst;
  CMPIArgs       *args_ptr = NULL;
  CMPIObjectPath *objPath = make_ObjectPath(_broker,
                                            _Namespace,
                                            _ClassName);
  CMPIUint64      datetime1,
                  datetime2;
  const char     *str1;
  const char     *str2;

  size = 17;
  for (i = 0; i < size; i++) {
    args_ptr = CMNewArgs(_broker, &rc);
    switch (types_arr[i].element_type) {
    case CMPI_uint32:
      value.uint32 = 56;
      break;

    case CMPI_uint16:
      value.uint16 = 32;
      break;

    case CMPI_uint8:
      value.uint8 = 56;
      break;

    case CMPI_uint64:
      value.uint64 = 32;
      break;

    case CMPI_sint32:
      value.sint32 = -56;
      break;

    case CMPI_sint16:
      value.sint16 = -32;
      break;

    case CMPI_sint8:
      value.sint8 = -56;
      break;

    case CMPI_sint64:
      value.sint64 = -32;
      break;

    case CMPI_real32:
      value.real32 = (CMPIReal32) -32.78;
      break;

    case CMPI_real64:
      value.real64 = -899.32;
      break;

    case CMPI_char16:
      value.char16 = 'k';
      break;

    case CMPI_string:
      value.string = CMNewString(_broker, "string", &rc);
      break;

    case CMPI_boolean:
      value.boolean = 1;
      break;

    case CMPI_dateTime:
      value.dateTime = CMNewDateTime(_broker, &rc);
      break;

    case CMPI_ref:
      value.ref = CMNewObjectPath(_broker,
                                  "root/cimv2", "Sample_Instance", &rc);
      break;

    case CMPI_null:
      value.args = NULL;
      break;

    case CMPI_instance:
      value.inst = make_Instance(objPath);
      value1.uint32 = 20;
      rc = CMSetProperty(value.inst, "Property1", &value1, CMPI_uint32);
      break;
    }

    arr = NULL;
    rc = CMAddArg(args_ptr,
                  "EmptyArray", (CMPIValue *) & arr, types_arr[i].typeA);
    arr = CMNewArray(_broker, 1, types_arr[i].element_type, &rc);

    rc = CMSetArrayElementAt(arr, 0, &value, types_arr[i].element_type);

    rc = CMAddArg(args_ptr,
                  types_arr[i].args_name,
                  (CMPIValue *) & arr, types_arr[i].typeA);

    flag = 1;
    if ((types_arr[i].element_type) != CMPI_null) {
      data = CMGetArg(args_ptr, types_arr[i].args_name, &rc);

      arr_data = CMGetArrayElementAt(data.value.array, 0, &rc);

      switch (types_arr[i].element_type) {
      case CMPI_uint32:
        if (arr_data.value.uint32 != value.uint32) {
          flag = 0;
        }
        break;

      case CMPI_uint16:
        if (arr_data.value.uint16 != value.uint16) {
          flag = 0;
        }
        break;

      case CMPI_uint8:
        if (arr_data.value.uint8 != value.uint8) {
          flag = 0;
        }
        break;

      case CMPI_uint64:
        if (arr_data.value.uint64 != value.uint64) {
          flag = 0;
        }
        break;

      case CMPI_sint32:
        if (arr_data.value.sint32 != value.sint32) {
          flag = 0;
        }
        break;

      case CMPI_sint16:
        if (arr_data.value.sint16 != value.sint16) {
          flag = 0;
        }
        break;

      case CMPI_sint8:
        if (arr_data.value.sint8 != value.sint8) {
          flag = 0;
        }
        break;

      case CMPI_sint64:
        if (arr_data.value.sint64 != value.sint64) {
          flag = 0;
        }
        break;

      case CMPI_real32:
        if (arr_data.value.real32 != value.real32) {
          flag = 0;
        }
        break;

      case CMPI_real64:
        if (arr_data.value.real64 != value.real64) {
          flag = 0;
        }
        break;

      case CMPI_char16:
        if (arr_data.value.char16 != value.char16) {
          flag = 0;
        }
        break;

      case CMPI_string:
        str1 = CMGetCharsPtr(arr_data.value.string, &rc);
        str2 = CMGetCharsPtr(value.string, &rc1);
        if ((rc.rc != CMPI_RC_OK) ||
            (rc1.rc != CMPI_RC_OK) || strcmp(str1, str2)) {
          flag = 0;
        }
        break;

      case CMPI_boolean:
        if (arr_data.value.boolean != value.boolean) {
          flag = 0;
        }
        break;

      case CMPI_dateTime:
        datetime1 = CMGetBinaryFormat(arr_data.value.dateTime, &rc);
        datetime2 = CMGetBinaryFormat(value.dateTime, &rc1);
        if ((rc.rc != CMPI_RC_OK) ||
            (rc1.rc != CMPI_RC_OK) || (datetime1 != datetime2)) {
          flag = 0;
        }
        rc = CMRelease(value.dateTime);
        break;

      case CMPI_ref:
        retNamespace = CMGetNameSpace(arr_data.value.ref, &rc);
        retClassname = CMGetClassName(arr_data.value.ref, &rc1);
        if ((rc.rc == CMPI_RC_OK) && (rc1.rc == CMPI_RC_OK)) {
          str1 = CMGetCharsPtr(retNamespace, &rc);
          str2 = CMGetCharsPtr(retClassname, &rc1);
          if ((rc.rc == CMPI_RC_OK) && (rc1.rc == CMPI_RC_OK)) {
            if ((strcmp(str1, "root/cimv2")) ||
                (strcmp(str2, "TestCMPI_Instance"))) {
              flag = 0;
            }
          } else {
            flag = 0;
          }
        } else {
          flag = 0;
        }
        rc = CMRelease(value.ref);
        break;

      case CMPI_instance:
        retDataInst = CMGetProperty(arr_data.value.inst, "Property1", &rc);
        dataInst = CMGetProperty(value.inst, "Property1", &rc);
        if (retDataInst.value.uint32 != dataInst.value.uint32) {
          flag = 0;
        }
        rc = CMRelease(value.inst);
        break;
      }
      if (data.type == types_arr[i].typeA && flag) {
      }
    }
    rc = CMRelease(arr);
    rc = CMRelease(args_ptr);
  }
  return flag;
}
CMPIStatus
IndCIMXMLHandlerInvokeMethod(CMPIMethodMI * mi,
                             const CMPIContext *ctx,
                             const CMPIResult *rslt,
                             const CMPIObjectPath * ref,
                             const char *methodName,
                             const CMPIArgs * in, CMPIArgs * out)
{
  _SFCB_ENTER(TRACE_INDPROVIDER, "IndCIMXMLHandlerInvokeMethod");

  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIStatus      circ = { CMPI_RC_OK, NULL };
  struct timeval tv;
  struct timezone tz;
  static unsigned int indID=1;


  if (interOpNameSpace(ref, &st) == 0)
    _SFCB_RETURN(st);

  if (strcasecmp(methodName, "_deliver") == 0) {

    // On the first indication, check if reliable indications are enabled.
    if (RIEnabled == -1) {
      CMPIObjectPath *op=CMNewObjectPath(_broker,"root/interop","CIM_IndicationService",NULL);
      CMPIEnumeration *isenm = _broker->bft->enumerateInstances(_broker, ctx, op, NULL, NULL);
      CMPIData isinst=CMGetNext(isenm,NULL);
      CMPIData mc=CMGetProperty(isinst.value.inst,"DeliveryRetryAttempts",NULL);
      RIEnabled=mc.value.uint16;
    }

    CMPIInstance *indo=CMGetArg(in,"indication",NULL).value.inst;
    CMPIInstance *ind=CMClone(indo,NULL);
    CMPIContext    *ctxLocal=NULL;
    CMPIObjectPath *iop=NULL,*subop=NULL;
    CMPIInstance *sub=NULL;

    if (RIEnabled) {
      ctxLocal = prepareUpcall((CMPIContext *) ctx);
      // Set the indication sequence values
      iop=CMGetObjectPath(ind,NULL);
      CMAddKey(iop,"SFCB_IndicationID",&indID,CMPI_uint32);
      CMSetProperty(ind,"SFCB_IndicationID",&indID,CMPI_uint32);
      // Prevent this property from showing up in the indication
      filterFlagProperty(ind, "SFCB_IndicationID");
      sub=CMGetArg(in,"subscription",NULL).value.inst;
      CMPIData handler=CMGetProperty(sub, "Handler", &st);
      CMPIObjectPath *hop=handler.value.ref;
      CMPIInstance *hdlr=CBGetInstance(_broker, ctxLocal, hop, NULL, &st);

      // Build the complete sequence context
      // Get the stub from the handler
      CMPIString *context = CMGetProperty(hdlr, "SequenceContext", &st).value.string;
      // and add the sfcb start time
      char *cstr=malloc( (strlen(context->ft->getCharPtr(context,NULL)) + strlen(sfcBrokerStart) + 1) * sizeof(char));
      sprintf(cstr,"%s%s",context->ft->getCharPtr(context,NULL),sfcBrokerStart);
      context = sfcb_native_new_CMPIString(cstr, NULL, 0); 
      // and put it in the indication
      CMSetProperty(ind, "SequenceContext", &context, CMPI_string);
      free(cstr);
      CMRelease(context);

      // Get the proper sequence number
      CMPIValue lastseq = CMGetProperty(hdlr, "LastSequenceNumber", &st).value;
      lastseq.sint64++;
      // Handle wrapping of the signed int
      if (lastseq.sint64 < 0) lastseq.sint64=0;
      // Update the last used number in the handler
      CMSetProperty(hdlr, "LastSequenceNumber", &lastseq.sint64, CMPI_sint64);
      CBModifyInstance(_broker, ctxLocal, hop, hdlr, NULL);
      // And the indication
      CMSetProperty(ind, "SequenceNumber", &lastseq, CMPI_sint64);
    }

    // Now send the indication
    st = deliverInd(ref, in, ind);
    if (st.rc != 0) {
      if (RIEnabled){
        _SFCB_TRACE(1,("--- Indication delivery failed, adding to retry queue"));
        // Indication delivery failed, send to retry queue
        // build an element
        RTElement      *element;
        element = (RTElement *) malloc(sizeof(*element));
        element->ref=ref->ft->clone(ref,NULL);
        // Get the OP of the subscription and indication
        subop=CMGetObjectPath(sub,NULL);
        element->sub=subop->ft->clone(subop,NULL);
        element->ind=iop->ft->clone(iop,NULL);
        // Store other attrs
        element->instanceID=indID;
        element->count=0;
        gettimeofday(&tv, &tz);
        element->lasttry=tv.tv_sec;
        // Push the indication to the repo
        CBCreateInstance(_broker, ctxLocal, iop, ind, &circ);
        if (circ.rc != 0) {
            mlogf(M_ERROR,M_SHOW,"Pushing indication instance to repository failed, rc:%d\n",circ.rc);
        }
        indID++;
        // Add it to the retry queue
        enqRetry(element,ctx,1);
        // And launch the thread if it isn't already running
        pthread_attr_init(&tattr);
        pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
        if (retryRunning == 0) {
          retryRunning = 1;
          _SFCB_TRACE(1,("--- Starting retryExport thread"));
          CMPIContext    *pctx = native_clone_CMPIContext(ctx);
          pthread_create(&t, &tattr, &retryExport, (void *) pctx);
        }
        CMRelease(ctxLocal);
      }
    }
    CMRelease(ind);
  }
  else {
    printf("--- ClassProvider: Invalid request %s\n", methodName);
    st.rc = CMPI_RC_ERR_METHOD_NOT_FOUND;
  }

  _SFCB_RETURN(st);
}
void           *
retryExport(void *lctx)
{
  _SFCB_ENTER(TRACE_INDPROVIDER, "retryExport");

  CMPIObjectPath *ref;
  CMPIArgs       *in;
  CMPIInstance   *sub;
  CMPIContext    *ctx = (CMPIContext *) lctx;
  CMPIContext    *ctxLocal;
  RTElement      *cur,
                 *purge;
  struct timeval  tv;
  struct timezone tz;
  int             rint,
                  maxcount,
                  ract,
                  rtint;
  CMPIUint64      sfc = 0;
  CMPIObjectPath *op;
  CMPIEnumeration *isenm = NULL;

  //Setup signal handlers
  struct sigaction sa;
  sa.sa_handler = handle_sig_retry;
  sa.sa_flags = 0;
  sigemptyset(&sa.sa_mask);
  sigaction(SIGUSR2, &sa, NULL);

  CMPIStatus      st = { CMPI_RC_OK, NULL };

  ctxLocal = prepareUpcall(ctx);

  // Get the retry params from IndService
  op = CMNewObjectPath(_broker, "root/interop", "CIM_IndicationService",
                       NULL);
  isenm = _broker->bft->enumerateInstances(_broker, ctx, op, NULL, NULL);
  CMPIData        isinst = CMGetNext(isenm, NULL);
  CMPIData        mc =
      CMGetProperty(isinst.value.inst, "DeliveryRetryAttempts", NULL);
  CMPIData        ri =
      CMGetProperty(isinst.value.inst, "DeliveryRetryInterval", NULL);
  CMPIData        ra =
      CMGetProperty(isinst.value.inst, "SubscriptionRemovalAction", NULL);
  CMPIData        rti =
      CMGetProperty(isinst.value.inst, "SubscriptionRemovalTimeInterval",
                    NULL);
  maxcount = mc.value.uint16;   // Number of times to retry delivery
  rint = ri.value.uint32;       // Interval between retries
  rtint = rti.value.uint32;     // Time to allow sub to keep failing until 
  ract = ra.value.uint16;       // ... this action is taken

  // Now, run the queue
  sleep(5); //Prevent deadlock on startup when localmode is used.
  pthread_mutex_lock(&RQlock);
  cur = RQhead;
  while (RQhead != NULL) {
    if(retryShutdown) break; // Provider shutdown
    ref = cur->ref;
    // Build the CMPIArgs that deliverInd needs
    CMPIInstance *iinst=internalProviderGetInstance(cur->ind,&st);
    if (st.rc != 0 ) {
      mlogf(M_ERROR,M_SHOW,"Failed to retrieve indication instance from repository, rc:%d\n",st.rc);
      purge=cur;
      cur=cur->next;
      dqRetry(ctx,purge);
      continue;
    }
    in=CMNewArgs(_broker,NULL);
    CMAddArg(in,"indication",&iinst,CMPI_instance);
    sub=internalProviderGetInstance(cur->sub,&st);
    if (st.rc == CMPI_RC_ERR_NOT_FOUND) {
      // sub got deleted, purge this indication and move on
      _SFCB_TRACE(1,("--- Subscription for indication gone, deleting indication."));
      purge = cur;
      cur = cur->next;
      dqRetry(ctx,purge);
    } else {
      // Still valid, retry
      gettimeofday(&tv, &tz);
      if ((cur->lasttry + rint) > tv.tv_sec) {
        _SFCB_TRACE(1,("--- sleeping."));
        // no retries are ready, release the lock
        // and sleep for an interval, then relock
        pthread_mutex_unlock(&RQlock);
        sleep(rint);
        if(retryShutdown) break; // Provider shutdown
        pthread_mutex_lock(&RQlock);
      }
      st = deliverInd(ref, in, iinst);
      if ((st.rc == 0) || (cur->count >= maxcount - 1)) {
        // either it worked, or we maxed out on retries
        // If it succeeded, clear the failtime
        if (st.rc == 0) {
          _SFCB_TRACE(1,("--- Indication succeeded."));
          sfc = 0;
          CMSetProperty(sub, "DeliveryFailureTime", &sfc, CMPI_uint64);
          CBModifyInstance(_broker, ctxLocal, cur->sub, sub, NULL);
        }
        // remove from queue in either case
        _SFCB_TRACE(1,("--- Indication removed."));
        purge = cur;
        cur = cur->next;
        dqRetry(ctx,purge);
      } else {
        // still failing, leave on queue 
        _SFCB_TRACE(1,("--- Indication still failing."));
        cur->count++;
        gettimeofday(&tv, &tz);
        cur->lasttry = tv.tv_sec;

        CMPIInstance * indele=internalProviderGetInstance(cur->SFCBIndEle,&st);
        CMSetProperty(indele,"LastDelivery",&cur->lasttry,CMPI_sint32);
        CMSetProperty(indele,"RetryCount",&cur->count,CMPI_uint32);
        CBModifyInstance(_broker, ctxLocal, cur->SFCBIndEle, indele, NULL);

        CMPIData        sfcp =
            CMGetProperty(sub, "DeliveryFailureTime", NULL);
        sfc = sfcp.value.uint64;
        if (sfc == 0) {
          // if the time isn't set, this is the first failure
          sfc = tv.tv_sec;
          CMSetProperty(sub, "DeliveryFailureTime", &sfc, CMPI_uint64);
          CBModifyInstance(_broker, ctxLocal, cur->sub, sub, NULL);
          cur = cur->next;
        } else if (sfc + rtint < tv.tv_sec) {
          // Exceeded subscription removal threshold, if action is:
          // 2, delete the sub; 3, disable the sub; otherwise, nothing
          if (ract == 2) {
            _SFCB_TRACE(1,("--- Subscription threshold reached, deleting."));
            CBDeleteInstance(_broker, ctx, cur->sub);
            purge = cur;
            cur = cur->next;
            dqRetry(ctx,purge);
          } else if (ract == 3) {
            // Set sub state to disable(4)
            _SFCB_TRACE(1,("--- Subscription threshold reached, disable."));
            CMPIUint16      sst = 4;
            CMSetProperty(sub, "SubscriptionState", &sst, CMPI_uint16);
            CBModifyInstance(_broker, ctx, cur->sub, sub, NULL);
            purge = cur;
            cur = cur->next;
            dqRetry(ctx,purge);
          }
        } else {
          cur = cur->next;
        }
      }
    }
  }
  // Queue went dry, cleanup and exit
  _SFCB_TRACE(1,("--- Indication retry queue empty, thread exitting."));
  pthread_mutex_unlock(&RQlock);
  retryRunning = 0;
  CMRelease(ctxLocal);
  CMRelease(ctx);
  _SFCB_RETURN(NULL);
}
static int
_testSimpleTypes()
{
  CMPIArgs       *args_ptr = NULL;
  CMPIStatus      rc = { CMPI_RC_OK, NULL };
  CMPIStatus      rc1 = { CMPI_RC_OK, NULL };
  int             i,
                  flag,
                  size;
  CMPIValue       value;
  CMPIValue       value1;
  CMPIData        data;
  CMPIData        dataInst;
  CMPIData        retDataInst;
  CMPIString     *retNamespace = NULL;
  CMPIString     *retClassname = NULL;
  CMPIObjectPath *objPath = make_ObjectPath(_broker,
                                            _Namespace,
                                            _ClassName);
  const char     *str1;
  const char     *str2;

  struct array_types {
    CMPIType        element_type;
    char           *typeName;
    char           *args_name;
  } types_arr[] = {

    {
    CMPI_instance, "CMPI_instance", "CMPI_instance"}, {
  CMPI_ref, "CMPI_ref", "CMPI_ref"}};

  size = 2;

  flag = 1;
  for (i = 0; i < size; i++) {
    args_ptr = CMNewArgs(_broker, &rc);

    switch (types_arr[i].element_type) {
    case CMPI_ref:
      value.ref = CMNewObjectPath(_broker,
                                  "root/cimv2", "Sample_Instance", &rc);
      break;

    case CMPI_instance:
      value.inst = make_Instance(objPath);
      value1.uint32 = 20;
      rc = CMSetProperty(value.inst, "Property1", &value1, CMPI_uint32);
      break;
    }
    rc = CMAddArg(args_ptr,
                  types_arr[i].args_name,
                  (CMPIValue *) & value, types_arr[i].element_type);

    data = CMGetArg(args_ptr, types_arr[i].args_name, &rc);

    switch (types_arr[i].element_type) {
    case CMPI_ref:
      retNamespace = CMGetNameSpace(data.value.ref, &rc);
      retClassname = CMGetClassName(data.value.ref, &rc1);

      if ((rc.rc == CMPI_RC_OK) && (rc1.rc == CMPI_RC_OK)) {
        str1 = CMGetCharsPtr(retNamespace, &rc);
        str2 = CMGetCharsPtr(retClassname, &rc1);
        if ((rc.rc == CMPI_RC_OK) && (rc1.rc == CMPI_RC_OK)) {
          if ((strcmp(str1, "root/cimv2")) ||
              (strcmp(str2, "Sample_Instance"))) {
            flag = 0;
          }
        } else {
          flag = 0;
        }
      } else {
        flag = 0;
      }
      rc = CMRelease(value.ref);
      break;

    case CMPI_instance:
      retDataInst = CMGetProperty(data.value.inst, "Property1", &rc);
      dataInst = CMGetProperty(value.inst, "Property1", &rc);
      if (retDataInst.value.uint32 != dataInst.value.uint32) {
        flag = 0;
      }
      rc = CMRelease(value.inst);
      break;
    }
    if (data.type == types_arr[i].element_type && flag) {
    }
    rc = CMRelease(args_ptr);
  }
  return flag;
}
// For Increasing the Coverage of CMPIInstance
static int _testInstance ()
{
    CMPIStatus rc = { CMPI_RC_OK, NULL };
    CMPIInstance* instance = NULL;
    CMPIObjectPath* objPath = NULL;
    CMPIObjectPath* objPathFake = NULL;

    CMPIValue value;
    CMPIType type = CMPI_uint64;

    CMPIData retData;
    CMPIData returnedData1;

    const char* property_name = "s";
    const char* origin = "origin";

    void* handle;

    int flag = 1;

    value.uint64 = PEGASUS_UINT64_LITERAL(5000000000);

    PROV_LOG("++++ _testInstance");

    objPath = make_ObjectPath(_broker, _Namespace, "TestCMPI_Instance");
    instance = make_Instance(objPath);

    /* Test cases to increase coverage in instSetPropertyWithOrigin function */

    /* Setting n64 property in class TestCMPI_Instance. So origin has been
       set to TestCMPI_Instance.*/
    rc = CMSetPropertyWithOrigin(instance,
        "n64",
        &value,
        type,
        "TestCMPI_Instance");
    if ( rc.rc == CMPI_RC_OK )
    {
        PROV_LOG("++++  SetPropertyWithOrigin for n64 property status : (%s)",
            strCMPIStatus(rc));
    }

    /* CMGetProperty is called to verify the value of the property just being
       set. */
    retData = CMGetProperty(instance, "n64", &rc);

    if (retData.type == CMPI_uint64 &&
           retData.value.uint64 == PEGASUS_UINT64_LITERAL(5000000000))
    {
         PROV_LOG("++++  CMGetProperty for n64 property status : (%s),"
             "value (%"PEGASUS_64BIT_CONVERSION_WIDTH"u)",
             strCMPIStatus(rc),
             retData.value.uint64);
    }

    /* Setting  non-member property of type CMPI_ref*/
    type= CMPI_ref;
    value.ref = objPath;

    rc = CMSetPropertyWithOrigin(instance, "objPath", &value, type, origin);
    if ( rc.rc == CMPI_RC_OK )
    {
        PROV_LOG("++++  SetPropertyWithOrigin status : (%s)",strCMPIStatus(rc));
    }

    /* Setting non-memeber property of type other than CMPI_ref*/
    value.uint32 = 32;
    type = CMPI_uint32;
    rc = CMSetPropertyWithOrigin(instance, "n32", &value, type, NULL);
    if ( rc.rc == CMPI_RC_OK )
    {
        PROV_LOG("++++  SetPropertyWithOrigin status : (%s)",strCMPIStatus(rc));
    }

    /* Testing error path for instGetProperty with NULL property name*/
    returnedData1 = CMGetProperty(instance, NULL, &rc);
    if (rc.rc == CMPI_RC_ERR_INVALID_PARAMETER )
    {
        PROV_LOG("++++ CMGetProperty with NULL property name status: (%s) ",
            strCMPIStatus(rc));
    }
    /*-----------------------------------------------------------------------*/

    /* Test cases to cover error paths for instSetObjectPath and
       instSetPropertyFilter*/

    /* Testing error path by passing CMPIObjectPath with class name different
       from the classname for CMPIInstance in CMSetObjectPath*/

    objPathFake = CMNewObjectPath(_broker,
        _Namespace,
        "TestCMPIInstance_Method",
        NULL);
    rc = CMSetObjectPath(instance, objPathFake);
    if ( rc.rc == CMPI_RC_ERR_FAILED || rc.rc == CMPI_RC_ERR_NOT_SUPPORTED)
    {
        PROV_LOG("++++  Test for CMSetObjectPath with wrong input passed");
    }

    /* Testing error path by passing NULL to instSetObjectPath*/
    rc = CMSetObjectPath(instance, NULL);
    if ( rc.rc == CMPI_RC_ERR_INVALID_PARAMETER ||
        rc.rc == CMPI_RC_ERR_NOT_SUPPORTED)
    {
        PROV_LOG("++++  Test for CMSetObjectPath with NULL input passed ");
    }

    /* Testing error paths by setting handle to CMPIInstance to NULL and using
       that in calls to instSetObjectPath and instSetPropertyFilter*/
    handle = instance->hdl;
    instance->hdl = NULL ;
    rc = CMSetObjectPath(instance, NULL);
    if ( rc.rc == CMPI_RC_ERR_INVALID_HANDLE ||
        rc.rc == CMPI_RC_ERR_NOT_SUPPORTED)
    {
        PROV_LOG("++++  CMSetObjectPath with NULL handle for"
            " CMPIInstance passed");
    }
    PROV_LOG("++++ CMSetObjectPath : (%s) ",strCMPIStatus(rc));

    rc = CMSetPropertyFilter(instance,&property_name,NULL);
    if( rc.rc == CMPI_RC_ERR_INVALID_HANDLE )
    {
        PROV_LOG("++++  CMSetPropertyFilter with NULL handle for CMPIInstance"
            " status : (%s)", strCMPIStatus (rc));
    }
    instance->hdl = handle;
    /*-----------------------------------------------------------------------*/
    return flag;

} // _testInstance end
CMPIStatus
getRefs(const CMPIContext *ctx, const CMPIResult *rslt,
        const CMPIObjectPath * cop,
        const char *assocClass,
        const char *resultClass,
        const char *role,
        const char *resultRole,
        const char **propertyList, int associatorFunction)
{
  UtilList       *refs = UtilFactory->newList(memAddUtilList, memUnlinkEncObj);
  char           *ns = (char *) CMGetNameSpace(cop, NULL)->hdl;
  CMPIStatus      st = { CMPI_RC_OK, NULL };

  _SFCB_ENTER(TRACE_INTERNALPROVIDER, "getRefs");

  if (assocClass != NULL) {
    CMPIObjectPath *path;
    if (assocForName(ns, assocClass, role, resultRole) == NULL) {
      /*
       * for an unknown class we just return nothing 
       */
      _SFCB_RETURN(st);
    }
    path = CMNewObjectPath(_broker, ns, assocClass, NULL);
    SafeInternalProviderAddEnumInstances(refs, NULL, ctx, path,
                                         propertyList, &st, 1);
  }

  else {
    CMPIData        rv;
    CMPIObjectPath *op =
        CMNewObjectPath(Broker, ns, "$ClassProvider$", &st);
    CMPIArgs       *in = CMNewArgs(Broker, NULL);
    CMPIArgs       *out = CMNewArgs(Broker, NULL);
    rv = CBInvokeMethod(Broker, ctx, op, "getassocs", in, out, &st);
    if (out) {
      int             i,
                      m;
      CMPIArray      *ar = CMGetArg(out, "assocs", &st).value.array;
      for (i = 0, m = CMGetArrayCount(ar, NULL); i < m; i++) {
        char           *name =
            CMGetArrayElementAt(ar, i, NULL).value.string->hdl;
        if (name) {
          CMPIObjectPath *cop = CMNewObjectPath(Broker, ns, name, NULL);
          if (cop) {
            SafeInternalProviderAddEnumInstances(refs, NULL, ctx, cop,
                                                 propertyList, &st, 1);
          }
        }
        _SFCB_TRACE(1, ("--- assoc %s", name));
      }
    }
  }

  if (role) {
    // filter out the associations not matching the role property
    CMPIInstance   *ci;
    UtilStringBuffer *pn = normalizeObjectPathStrBuf(cop);
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      CMPIData        data = CMGetProperty(ci, role, NULL);
      if ((data.state & CMPI_notFound) ||
          data.type != CMPI_ref ||
          objectPathEquals(pn, data.value.ref, NULL, 0) == 0) {
        refs->ft->removeCurrent(refs);
      }
    }
    pn->ft->release(pn);
  }

  else {
    // filter out associations not referencing pathName
    CMPIInstance   *ci;
    int             matched,
                    i,
                    m;
    UtilStringBuffer *pn = normalizeObjectPathStrBuf(cop);
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      for (matched = 0, i = 0, m = CMGetPropertyCount(ci, NULL); i < m;
           i++) {
        CMPIData        data = CMGetPropertyAt(ci, i, NULL, NULL);
        if (data.type == CMPI_ref
            && objectPathEquals(pn, data.value.ref, NULL, 0)) {
          matched = 1;
          break;
        }
      }
      if (matched == 0)
        refs->ft->removeCurrent(refs);
    }
    pn->ft->release(pn);
  }

  if (associatorFunction == REF) {
    CMPIInstance   *ci;
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      CMReturnInstance(rslt, ci);
    }
    refs->ft->release(refs);
    _SFCB_RETURN(st);
  }

  else if (associatorFunction == REF_NAME) {
    CMPIInstance   *ci;
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      CMPIObjectPath *ref = CMGetObjectPath(ci, NULL);
      CMReturnObjectPath(rslt, ref);
    }
    refs->ft->release(refs);
    _SFCB_RETURN(st);
  }

  else {
    // Use hashtable to avoid dup'd associators
    CMPIInstance   *ci;
    UtilHashTable  *assocs =
        UtilFactory->newHashTable(61, UtilHashTable_charKey);
    UtilStringBuffer *pn = normalizeObjectPathStrBuf(cop);
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      // Q: for ASSOC_NAME we should not require the
      // object exist if we go by the book, should we?
      // The current approach retrieves the instances
      // via the CIMOM handle
      if (resultRole) {
        CMPIData        data = CMGetProperty(ci, resultRole, NULL);
        UtilStringBuffer *an = NULL;
        if ((data.state & CMPI_notFound) == 0 && data.type == CMPI_ref &&
            objectPathEquals(pn, data.value.ref, &an, 0) == 0) {
          if (resultClass == NULL
              || CMClassPathIsA(Broker, data.value.ref, resultClass,
                                NULL)) {
            CMPIInstance   *aci =
                CBGetInstance(Broker, ctx, data.value.ref, propertyList,
                              &st);
            assocs->ft->put(assocs, an->ft->getCharPtr(an), aci);
          }
        }
      }

      else {
        // must loop over the properties to find ref instances
        int             i,
                        m;
        for (i = 0, m = CMGetPropertyCount(ci, NULL); i < m; i++) {
          CMPIData        data = CMGetPropertyAt(ci, i, NULL, NULL);
          if (data.type == CMPI_ref) {
            CMPIObjectPath *ref = data.value.ref;
            CMPIString     *tns = CMGetNameSpace(ref, NULL);
            if (tns == NULL || tns->hdl == NULL)
              CMSetNameSpace(ref, ns);
            UtilStringBuffer *an = NULL;
            if (objectPathEquals(pn, ref, &an, 0) == 0) {

              if (resultClass == NULL
                  || CMClassPathIsA(Broker, ref, resultClass, NULL)) {
                CMPIInstance   *aci =
                    CBGetInstance(Broker, ctx, ref, propertyList, &st);
                if (aci)
                  assocs->ft->put(assocs, an->ft->getCharPtr(an), aci);
              }
            }
          }
        }
      }
    }

    {
      HashTableIterator *it;
      char           *an;
      CMPIInstance   *aci;
      for (it =
           assocs->ft->getFirst(assocs, (void **) &an, (void **) &aci); it;
           it =
           assocs->ft->getNext(assocs, it, (void **) &an,
                               (void **) &aci)) {
        if (associatorFunction == ASSOC)
          CMReturnInstance(rslt, aci);
        else {
          CMPIObjectPath *op = CMGetObjectPath(aci, NULL);
          CMReturnObjectPath(rslt, op);
        }
      }
    }

    refs->ft->release(refs);
    assocs->ft->release(assocs);
    pn->ft->release(pn);
    _SFCB_RETURN(st);

  }
}
/******************************************************************************
* checks for migratability or actually does the migration
******************************************************************************/
int MigrateVirtualSystem(
    const CMPIBroker *broker,   /* in - CMPI Broker that does most of the work */
    const CMPIContext *context, /* in - CMPI context for the caller */
    const CMPIArgs *argsin,     /* in - All the arguments for the method */
    const CMPIArgs *argsout,    /* out - All the output arguments for the method */
    xen_utils_session *session, /* in - Session for making xen calls */
    bool host_ip,               /* in - The host parameter is an IP address */
    bool migrate_check_only,    /* in -Check if migration is possible only, dont actually migrate */
    CMPIStatus *status)         /* out - Report CMPI status of method */
{
    char *hostid = NULL, *vm_uuid = NULL;
    CMPIData argdata;
    xen_vm vm = NULL;
    xen_host_set *host_set = NULL;
    CMPIInstance *msd = NULL;
    xen_host host = NULL;
    int rc = Xen_VirtualSystemMigrationService_MigrateVirtualSystemToSystem_Invalid_Parameter;
    CMPIrc statusrc = CMPI_RC_ERR_INVALID_PARAMETER;
    char *error_msg = "ERROR: Unknown error";
    xen_string_string_map *other_config=NULL;

    /* For now only Live migrations are supported */
    if(_GetArgument(broker, argsin, "MigrationSettingData", CMPI_chars, &argdata, status)) {
        /* Argument passed in as a MOF string, parse it */
        msd = xen_utils_parse_embedded_instance(broker, CMGetCharPtr(argdata.value.string));
        if (msd == NULL) { // parser returns zero for success, non-zero for error
            error_msg = "ERROR: Couldnt parse the 'MigrationSettingData' parameter";
            goto Exit;
        }
    }
    else
        /* Argument could have been passed in as an intance */
        if(_GetArgument(broker, argsin, "MigrationSettingData", CMPI_instance, &argdata, status))
            msd = argdata.value.inst;

    if(msd != NULL) {
        CMPIData data = CMGetProperty(msd, "MigrationType", status);
        if(data.value.uint16 != Xen_VirtualSystemMigrationSettingData_MigrationType_Live) {
            error_msg = "ERROR: 'MigrationSettingData' contains an invalid MigrationType (Live expected)";
            goto Exit;
        }
    }

    /* Host to migrate to */
    if(!host_ip) {
        /* required parameters */
        if(!_GetArgument(broker, argsin, "DestinationSystem", CMPI_ref, &argdata, status)){
            error_msg = "ERROR: 'DestionationSystem' parameter is missing";
            goto Exit;
        }
        else {
            /* This is the CIM reference to an existing Host object */
            CMPIData key;
            key = CMGetKey(argdata.value.ref, "Name", status);
            if(status->rc != CMPI_RC_OK || CMIsNullValue(key)) {
                error_msg = "ERROR: 'DestinationSystem' is missing the required 'Name' key";
                goto Exit;
            }
            hostid = CMGetCharPtr(key.value.string);
            if(!xen_host_get_by_uuid(session->xen, &host, hostid)) 
                goto Exit;
        }
    }
    else {
        if(!_GetArgument(broker, argsin, "DestinationHost", CMPI_string, &argdata, status)) {
            error_msg = "ERROR: 'DestinationHost' parameter is missing";
            goto Exit;
        }
        else {
            /* Determing Xen host based on IP address,. Cannot use inet_pton() and so on since DNS may not have been configured properly */
            hostid = CMGetCharPtr(argdata.value.string);
            _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Trying to migrate to DestinationHost : %s", hostid));
            if(!xen_host_get_all(session->xen, &host_set))
                goto Exit;
            int i=0;
            for (i=0; i<host_set->size; i++) {
                xen_host_record *host_rec = NULL;
                if(!xen_host_get_record(session->xen, &host_rec, host_set->contents[i]))
                    goto Exit;
                /* DestinationHost could be an IP address or the hostname */
                if((host_rec->address &&  (strcmp(hostid, host_rec->address) == 0)) || 
                   (host_rec->hostname && (strcmp(hostid, host_rec->hostname) == 0)) ||
                   (host_rec->name_label && (strcmp(hostid, host_rec->name_label) == 0))) { 
                    xen_host_record_free(host_rec);
                    host = host_set->contents[i];
                    host_set->contents[i] = NULL; /* dont free this one */
                    break;
                }
                xen_host_record_free(host_rec);
            }
        }
    }

    /* VM to migrate - required parameter */
    if(!_GetArgument(broker, argsin, "ComputerSystem", CMPI_ref, &argdata, status)) {
        if(!_GetArgument(broker, argsin, "ComputerSystem", CMPI_string, &argdata, status)) {
            error_msg = "ERROR: Missing the required 'ComputerSystem' parameter";
            goto Exit;
        }
        else
            vm_uuid = CMGetCharPtr(argdata.value.string);
    } else {
        argdata = CMGetKey(argdata.value.ref, "Name", status);
        if(status->rc != CMPI_RC_OK || CMIsNullValue(argdata)) {
            error_msg = "ERROR: ComputerSystem is missing the required 'Name' key";
            goto Exit;
        }
        vm_uuid = CMGetCharPtr(argdata.value.string);
    }
    status->rc = CMPI_RC_ERR_FAILED;
    rc = Xen_VirtualSystemMigrationService_MigrateVirtualSystemToSystem_Failed;
    if(xen_vm_get_by_uuid(session->xen, &vm, vm_uuid)) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Migrating %s to %s", vm_uuid, hostid));
        if(migrate_check_only) {
            /* Check to see if migration is possible */
            statusrc = CMPI_RC_OK;
            rc = Xen_VirtualSystemMigrationService_MigrateVirtualSystemToSystem_Completed_with_No_Error;
            bool migratable = xen_vm_assert_can_boot_here(session->xen, vm, host);
            if(migratable == false || !session->xen->ok) {
                migratable = false;

                // Workaround for kvp migration
                if(session->xen->error_description_count==1) {
                    if(xen_vm_get_other_config(session->xen, &other_config, vm)) {
                         if(xen_utils_get_from_string_string_map(other_config, "kvp_enabled")) {
                            _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Overwriting migratable to mark kvp vm as migratable, although its network"));
                            migratable=true;
                            RESET_XEN_ERROR(session->xen);
                         }
                         free(other_config);
                    } else {
                       _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Could not get other config."));
                    }
                }

                if(migratable == false && session->xen->error_description) {
                    /* This is not part of the MOF (and is not documented), but nice to have */
                    char *xen_error = xen_utils_get_xen_error(session->xen);
                    CMAddArg(argsout, "Reason", (CMPIValue *)xen_error, CMPI_chars);
                    free(xen_error);
                }
            }
            CMAddArg(argsout, "IsMigratable", (CMPIValue *)&migratable, CMPI_boolean);
        }
        else {
            /* Do the actual migration, this could take a few minutes */
            CMPIObjectPath* job_instance_op = NULL;
            migrate_job_context *job_context = calloc(1, sizeof(migrate_job_context));
            if(!job_context) {
                error_msg = "ERROR: Couldn't allocate memory for the migrate job.";
                goto Exit;
            }
            job_context->vm = vm;
            job_context->host = host;
            if(!job_create(broker, context, session, MIGRATE_VM_TASK_NAME, vm_uuid, 
                           migrate_task, job_context, &job_instance_op, status)) {
                error_msg = "ERROR: Couldn't prepare the Migrate job. Job wasnt started.";
                goto Exit;
            }
            statusrc = CMPI_RC_OK;
            rc = Xen_VirtualSystemMigrationService_MigrateVirtualSystemToHost_Method_Parameters_Checked___Job_Started;
            CMAddArg(argsout, "Job", (CMPIValue *)&job_instance_op, CMPI_ref);
            vm = NULL;      /* freed by async thread */
            host = NULL;    /* freed by async thread */
        }
    }

Exit:
    if(host)
        xen_host_free(host);
    if(vm)
        xen_vm_free(vm);
    if(host_set)
        xen_host_set_free(host_set);

    xen_utils_set_status(broker, status, statusrc, error_msg, session->xen);
    return rc;
}
static int
_testCMPIInstance()
{
  CMPIStatus      rc = { CMPI_RC_OK, NULL };

  CMPIInstance   *instance = NULL;
  CMPIInstance   *clonedInstance = NULL;
  CMPIObjectPath *objPath = NULL;
  CMPIObjectPath *newObjPath = NULL;
  CMPIObjectPath *returnedObjPath = NULL;

  CMPIData        returnedData1;
  CMPIData        returnedData2;
  CMPIData        clonedData1;

  CMPIString     *returnedName = NULL;
  unsigned int    count = 0;
  const char     *name1 = "firstPropertyName";
  CMPIValue       value1;
  const char     *name2 = "secondPropertyName";
  CMPIValue       value2;
  CMPIType        type = CMPI_uint64;
  CMPIBoolean     dataEqual = 0;
  CMPIBoolean     objectPathEqual = 0;
  CMPIBoolean     cloneSuccessful = 0;
  CMPIString     *beforeObjPath = NULL;
  CMPIString     *afterObjPath = NULL;
  const char     *beforeString = NULL;
  const char     *afterString = NULL;
  objPath = make_ObjectPath(_broker, _Namespace, _ClassName);
  instance = make_Instance(objPath);
  value1.uint32 = 10;
  rc = CMSetProperty(instance, name1, &value1, type);
  value2.uint32 = 20;
  rc = CMSetProperty(instance, name2, &value2, type);
  count = CMGetPropertyCount(instance, &rc);
  returnedData1 = CMGetProperty(instance, name1, &rc);
  if (returnedData1.value.uint32 == 10) {
    dataEqual = 1;
  }
  returnedData2 = CMGetPropertyAt(instance, 2, &returnedName, &rc);
  if (returnedData2.value.uint32 == 20) {
    dataEqual = 1;
  }
  newObjPath = make_ObjectPath(_broker, _Namespace, _ClassName);
  returnedObjPath = CMGetObjectPath(instance, &rc);
  beforeObjPath = CMObjectPathToString(returnedObjPath, &rc);
  beforeString = CMGetCharsPtr(beforeObjPath, &rc);
  rc = CMSetNameSpace(newObjPath, "newNamespace");
  rc = CMSetObjectPath(instance, newObjPath);
  returnedObjPath = CMGetObjectPath(instance, &rc);
  afterObjPath = CMObjectPathToString(returnedObjPath, &rc);
  afterString = CMGetCharsPtr(afterObjPath, &rc);
  afterString = CMGetCharsPtr(CMGetNameSpace(returnedObjPath, &rc), &rc);
  if (strcmp("newNamespace", afterString) == 0) {
    objectPathEqual = 1;
  }
  clonedInstance = instance->ft->clone(instance, &rc);
  clonedData1 = CMGetProperty(clonedInstance, name1, &rc);
  rc = clonedInstance->ft->release(clonedInstance);
  if (returnedData1.value.uint32 == clonedData1.value.uint32) {
    cloneSuccessful = 1;
  } else {
    cloneSuccessful = 0;
  }
  CMGetProperty(instance, "noProperty", &rc);
  if (rc.rc != CMPI_RC_ERR_NO_SUCH_PROPERTY) {
    return 1;
  }

  CMGetPropertyAt(instance, 100, &returnedName, &rc);
  if (rc.rc != CMPI_RC_ERR_NO_SUCH_PROPERTY) {
    return 1;
  }
  rc = instance->ft->release(instance);
  return 0;
}
/******************************************************************************
* disk_rasd_to_vbd
*
* This function attempts to parse a Xen_Disk CIM instance and populate a new
* VBD record. It also gets the record to the VDI that the VBD attaches to (could
* be a newly created VDI, if requested) and a handle to an existing SR as
* pointed to by the PoolID field in the CIM instance
*
* Returns 1 on Success and 0 on failure.
*******************************************************************************/
int disk_rasd_to_vbd(
    const CMPIBroker *broker,
    xen_utils_session* session,
    CMPIInstance *disk_rasd,
    xen_vbd_record **vbd_rec,
    xen_vdi_record **vdi_rec,
    xen_sr  *sr,
    CMPIStatus *status)
{
    CMPIData propertyvalue;
    char *error_msg = "ERROR: Unknown error";
    char *sr_label = NULL, *vdi_name_label = NULL, *vdi_name_desc = NULL;
    char *vbd_device = NULL, *vbd_uuid = NULL, *vdi_uuid = NULL;
    enum xen_vbd_type vbd_type = XEN_VBD_TYPE_DISK; /* default with Disk (as opposed to CDRom) */
    enum xen_vdi_type vdi_type = XEN_VDI_TYPE_USER;
    bool vbd_readonly = false, vbd_bootable = false;/* defaults for Disk type */
    int vbd_mode= XEN_VBD_MODE_RW;                  /* defaults for Disk type */
    int64_t disk_size = -1;                         /* for CDRoms - this is the size expected */
    char buf[MAX_INSTANCEID_LEN];

    *vbd_rec  = NULL;
    *vdi_rec  = NULL;

    /* only resource types of 15,16 and 19 are currently supported */
    int rc = CMPI_RC_ERR_INVALID_PARAMETER;
    propertyvalue = CMGetProperty(disk_rasd, "ResourceType", status);
    if ((status->rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue)) {
        error_msg = "ERROR: Xen_DiskSettingData has no ResourceType";
        goto Error;
    }
    int res_type = propertyvalue.value.uint16;
    if ((res_type == DMTF_ResourceType_CD_Drive) || (res_type == DMTF_ResourceType_DVD_drive)) {
        vbd_mode = XEN_VBD_MODE_RO;
        vbd_type = XEN_VBD_TYPE_CD;
    }
    else if ((res_type == DMTF_ResourceType_Storage_Extent) || (res_type == DMTF_ResourceType_Disk_Drive))
        vbd_type = XEN_VBD_TYPE_DISK;
    else {
        error_msg = "ERROR: Xen_DiskSettingData has unsupported ResourceType";
        goto Error;
    }

    /* Get the instance ID which has the device's UUID in it, if its available
      This will be usd during deletes and not used during create*/
    propertyvalue = CMGetProperty(disk_rasd, "InstanceID", status);
    if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
        _CMPIStrncpyDeviceNameFromID(buf, CMGetCharPtr(propertyvalue.value.string),
            sizeof(buf)/sizeof(buf[0]));
        vbd_uuid = strdup(buf);
    }

    /* The HostResource property is used to identify the VDI, if available */
    propertyvalue = CMGetProperty(disk_rasd, "HostResource", status);
    if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
        /* HostResource is always in WBEM URI format and it points to a 
          Xen_DiskImage object reference. Convert it to CMPIObjectPath */
        CMPIData data = CMGetArrayElementAt(propertyvalue.value.array, 0, NULL);
        CMPIObjectPath *obj_path = xen_utils_WBEM_URI_to_CMPIObjectPath(
                                       broker, 
                                       CMGetCharPtr(data.value.string));
        if (obj_path) {
            /* this should be a Xen_DiskImage object reference */
            /* Get the DeviceID key */
            propertyvalue = CMGetKey(obj_path, "DeviceID", status);
            if ((status->rc == CMPI_RC_OK) && 
                !CMIsNullValue(propertyvalue) && 
                propertyvalue.type == CMPI_string) {
                memset(buf, 0, sizeof(buf));
                _CMPIStrncpyDeviceNameFromID(buf, CMGetCharPtr(propertyvalue.value.string),
                                             sizeof(buf)/sizeof(buf[0]));
                vdi_uuid = strdup(buf);
            }
        }
    }
    if (!vdi_uuid) {
        /* second chance, Try the HostExtentName */
        propertyvalue = CMGetProperty(disk_rasd, "HostExtentName", status);
        if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue))
            vdi_uuid = strdup(CMGetCharPtr(propertyvalue.value.string));
    }
    /* Device is specified as the address on the host bus */
    propertyvalue = CMGetProperty(disk_rasd, "AddressOnParent", status);
    if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue))
        vbd_device = strdup(CMGetCharPtr(propertyvalue.value.string));

    propertyvalue = CMGetProperty(disk_rasd, "Bootable", status);
    if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue))
        vbd_bootable = propertyvalue.value.boolean;

    propertyvalue = CMGetProperty(disk_rasd, "Access", status);
    if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
        if (propertyvalue.value.uint16 == Access_Readable)
            vbd_mode = XEN_VBD_MODE_RO;
    }

    /*
    * The Pool ID property is used to identify the Xen SR
    * This could be NULL if VDIs are reused or if
    * the VBD has to be created on the default SR.
    */
    propertyvalue = CMGetProperty(disk_rasd, "PoolID", status);
    if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
        char *poolid = CMGetCharPtr(propertyvalue.value.string);
        if (poolid && (*poolid != '\0'))
            sr_label = strdup(poolid);
    }

    propertyvalue = CMGetProperty(disk_rasd, "ElementName", status);
    if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue))
        vdi_name_label = strdup(CMGetCharPtr(propertyvalue.value.string));

    propertyvalue = CMGetProperty(disk_rasd, "Description", status);
    if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue))
        vdi_name_desc = strdup(CMGetCharPtr(propertyvalue.value.string));

    /* Get the disk size from the CIM instance -
    * If this is a new disk, this property is required
    * If we are instantiating a CDRom VDI, this is not required */
    int64_t multiplier = 1; /* default to bytes */
    propertyvalue = CMGetProperty(disk_rasd, "AllocationUnits", status);
    if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
        char *units = CMGetCharPtr(propertyvalue.value.string);
        if ((multiplier = xen_utils_get_alloc_units(units)) == 0) {
            error_msg = "ERROR: Xen_DiskSettingData has unsupported AllocationUnits";
            goto Error;
        }
    }

    /* Limit and VirtualQuantity properties mean the same when we create the VBD */
    propertyvalue = CMGetProperty(disk_rasd, "VirtualQuantity", status);
    if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue))
        disk_size = (propertyvalue.value.uint64) * multiplier;

    if (vbd_type == XEN_VBD_TYPE_CD)
        vdi_type = XEN_VDI_TYPE_USER;

    /* We have enough information... create the Xen device records so we can */
    /* create new devices or identify existing ones */
    /* Create the VDI device record */
    rc = CMPI_RC_ERR_FAILED;
    *vdi_rec = xen_vdi_record_alloc();
    if (*vdi_rec == NULL) {
        error_msg = "ERROR: Unable to malloc memory";
        goto Error;
    }

    (*vdi_rec)->virtual_size  = disk_size;
#if OSS_XENAPI
    (*vdi_rec)->other_config  = xen_string_string_map_alloc(0);
    vdi_location = "";
    (*vdi_rec)->other_config->contents[0].key= strdup("location");
    (*vdi_rec)->other_config->contents[0].val = strdup(vdi_location);
    (*vdi_rec)->other_config->size = 1;
#else
    (*vdi_rec)->other_config  = xen_string_string_map_alloc(0);
    (*vdi_rec)->other_config->size = 0;
#endif
    (*vdi_rec)->type          = vdi_type;
    (*vdi_rec)->read_only     = vbd_readonly;
    (*vdi_rec)->name_label    = vdi_name_label;
    (*vdi_rec)->name_description = vdi_name_desc;

#if XENAPI_VERSION > 400
    (*vdi_rec)->managed = true;
#endif

    /* If VDI has already been created, use it */
    if (vdi_uuid) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("VDI specified in the RASD: -%s-", vdi_uuid));
        (*vdi_rec)->uuid = vdi_uuid;
    }

    /* create the VBD record */
    *vbd_rec = xen_vbd_record_alloc();
    if (*vbd_rec == NULL) {
        error_msg = "ERROR: Unable to malloc memory";
        goto Error;
    }

    if (vbd_uuid)
        (*vbd_rec)->uuid = vbd_uuid;

#if XENAPI_VERSION > 400
    if (vbd_device)
        (*vbd_rec)->userdevice = vbd_device;
    (*vbd_rec)->other_config = xen_string_string_map_alloc(0);
#endif
    (*vbd_rec)->bootable = vbd_bootable;
    (*vbd_rec)->mode = vbd_mode;
    (*vbd_rec)->type = vbd_type;
    (*vbd_rec)->qos_algorithm_params = xen_string_string_map_alloc(0);

    if (vbd_type == XEN_VBD_TYPE_CD)
        (*vdi_rec)->sharable = true;
    else
        (*vdi_rec)->sharable = false;

    /* Identify the Storage Repository where this VDI will be created (if its being created) */
    if (sr_label) {
        if (!_get_sr(broker, session, sr_label, true, sr, status)) {
            _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
                ("--- getting SR for %s failed", sr_label));
            goto Error;
        }
        free(sr_label);
    }
    return 1;

    Error:
    if (sr_label)
        free(sr_label);
    if (vdi_name_label) {
        free(vdi_name_label);
        if (*vdi_rec)
            (*vdi_rec)->name_label = NULL;
    }
    if(vdi_name_desc) {
        free(vdi_name_desc);
    }
    if(vbd_device) {
        free(vbd_device);
    }
    if(vbd_uuid) {
        free(vbd_uuid);
    }

    /* frees fields as well */
    if (*vbd_rec) {
        xen_vbd_record_free(*vbd_rec);
        *vbd_rec = NULL;
    }
    if (*vdi_rec) {
        xen_vdi_record_free(*vdi_rec);
        *vdi_rec = NULL;
    }
    xen_utils_set_status(broker, status, rc, error_msg, session->xen);
    return 0;
}
CMPIStatus TestInstanceProviderExecQuery (
    CMPIInstanceMI * mi,
    const CMPIContext * ctx,
    const CMPIResult * rslt,
    const CMPIObjectPath * referencePath,
    const char *query,
    const char *lang)
{
    CMPIStatus rc = { CMPI_RC_OK, NULL };
    CMPIStatus rc_Eval = { CMPI_RC_OK, NULL };
    CMPIStatus rc_Clone = { CMPI_RC_OK, NULL };
    CMPIStatus rc_Array = { CMPI_RC_OK, NULL };
    CMPISelectExp *se_def = NULL;
    CMPICount cnt = 0;
    CMPIArray *projection = NULL;
    unsigned int j = 0;
    CMPIBoolean evalRes;
    CMPIData arr_data;
    CMPIInstance *instance1;
    CMPIObjectPath *cop1;
    CMPIData data;
    CMPIValue value1;
    const char* prop_name;
    CMPIData retProp;

    /*create the select expression */
    se_def = CMNewSelectExp (_broker, query, lang, &projection, &rc_Clone);
    if (se_def)
    {
        /*loop over instances in array to evaluate for requested properties */
        for (j = 0; j < numOfInst ; j++)
        {
            /*check for validity of Instance,that its not deleted */
            if(valid[j] == 1)
            {
                /*get the element from array */
                arr_data = CMGetArrayElementAt(
                    clone_arr_ptr,
                    j,
                    &rc);
                /*Evaluate the instance using this select expression */
               evalRes = CMEvaluateSelExp(se_def,arr_data.value.inst, &rc_Eval);
                if (evalRes)
                {
                    /*check if any of properties are requested */
                    if (projection)
                    {
                        /*get number of properties requested */
                        cnt = CMGetArrayCount (projection, &rc_Array);
                        /*if count is not equal to number of properties of
                          instance */
                        if(cnt == 1)
                        {
                            /*check for the properties, requested */
                            data = CMGetArrayElementAt(
                                projection,
                                0,
                                &rc_Array);
                            prop_name = CMGetCharsPtr (
                                data.value.string,
                                &rc);
                            /*create the new instance that has to be returned */
                            cop1 = CMNewObjectPath(
                                _broker,
                                "root/cimv2",
                                _ClassName,
                                &rc);

                            instance1 = CMNewInstance(_broker,
                                cop1,
                                &rc);

                            /*if property name is "Identifier",
                               gets its value from instance */
                            if(!strcmp(prop_name, "Identifier"))
                            {
                                retProp = CMGetProperty(
                                    arr_data.value.inst,
                                        "Identifier",
                                        &rc);
                                value1.uint8 = retProp.value.uint8;
                                CMSetProperty(
                                    instance1,
                                    "Identifier",
                                    (CMPIValue *)&value1,
                                    CMPI_uint8);
                            }
                            /*if property name is "Message",
                              gets its value from instance */
                            if(!strcmp(prop_name, "Message"))
                            {
                                retProp = CMGetProperty(
                                    arr_data.value.inst,
                                    "Message",
                                    &rc);
                                    value1.string = retProp.value.string;
                                    CMSetProperty(
                                        instance1,
                                        "Message",
                                        (CMPIValue *)&value1,
                                        CMPI_string);
                            }
                            /*if the query is evaluated return instance */
                            CMReturnInstance (rslt, instance1);
                        }
                    }
                    else
                    {
                        CMReturnInstance(rslt, arr_data.value.inst);
                    }
                }
            }
        }
    }

    CMReturnDone (rslt);
    CMReturn (CMPI_RC_OK);
}
Exemple #23
0
CMPIStatus TestCMPIBrokerInstanceProviderGetInstance (CMPIInstanceMI * mi,
    const CMPIContext * ctx,
    const CMPIResult * rslt,
    const CMPIObjectPath * cop,
    const char **properties)
{
    CMPIStatus rc = {CMPI_RC_OK, NULL};
    CMPIString* retNamespace;
    CMPIString* retClassname;
    CMPIString* type;
    CMPIData retData;
    CMPIObjectPath* obj;
    CMPIBoolean bol = 0;
    const char* str1;
    const char* str2;

    PROV_LOG_OPEN (_ClassName, _ProviderLocation);
    PROV_LOG("GetInstance");
    PROV_LOG("++++Namespace ");

    obj = CMGetObjectPath(_inst, &rc);
    PROV_LOG("++++ Status of CMGetObjectPath : (%s)",
        strCMPIStatus(rc));
    retNamespace = CMGetNameSpace(obj, &rc);
    PROV_LOG("++++ Status of CMGetNameSpace : (%s)",
        strCMPIStatus(rc));
    retClassname = CMGetClassName(obj, &rc);
    PROV_LOG("++++ Status of CMGetClassName : (%s)",
        strCMPIStatus(rc));
    str1 = CMGetCharsPtr(retNamespace, &rc);
    PROV_LOG("++++ Status of CMGetCharsPtr : (%s)",
        strCMPIStatus(rc));
    str2 = CMGetCharsPtr(retClassname, &rc);
    PROV_LOG("++++ Status of CMGetCharsPtr : (%s)",
        strCMPIStatus(rc));
    retData = CMGetProperty(_inst, "n64", &rc);
    PROV_LOG("++++ Status of CMGetProperty : (%s)",
        strCMPIStatus(rc));
    PROV_LOG("n64 = %" PEGASUS_64BIT_CONVERSION_WIDTH "u",
        retData.value.uint64);
   
    /* Test cases for increasing coverage in CMPI_BrokerEnc.cpp*/
    type = CDGetType (_broker, rslt, &rc);
    PROV_LOG ("++++ Status of mbEncGetType with input of type "
        "CMPIResult with CMPI_ResultInstOnStack_Ftab : (%s) type(%s)",
        strCMPIStatus (rc),
        CMGetCharsPtr(type, NULL));

    bol = CDIsOfType (_broker, rslt, "CMPIResult", &rc);
    if ( bol )
    {
        PROV_LOG ("++++ CDIsOfType for CMPIResult with "
            "CMPI_ResultInstOnStack_Ftab status is (%s) : %d",
            strCMPIStatus (rc),
            bol);
    }
    PROV_LOG_CLOSE();

    if (_inst)
    {
        CMReturnInstance(rslt, _inst);
        CMReturnDone(rslt);
        CMReturn (CMPI_RC_OK);
    }
    else
    {
        CMReturn (CMPI_RC_ERR_NOT_SUPPORTED);
    }
}
CMPIStatus
IndCIMXMLHandlerCreateInstance(CMPIInstanceMI * mi,
                               const CMPIContext *ctx,
                               const CMPIResult *rslt,
                               const CMPIObjectPath * cop,
                               const CMPIInstance *ci)
{
  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIArgs       *in,
                 *out = NULL;
  CMPIObjectPath *op;
  CMPIData        rv;
  unsigned short  persistenceType;

  _SFCB_ENTER(TRACE_INDPROVIDER, "IndCIMXMLHandlerCreateInstance");

  if (interOpNameSpace(cop, &st) == 0)
    _SFCB_RETURN(st);

  internalProviderGetInstance(cop, &st);
  if (st.rc == CMPI_RC_ERR_FAILED)
    _SFCB_RETURN(st);
  if (st.rc == CMPI_RC_OK) {
    setStatus(&st, CMPI_RC_ERR_ALREADY_EXISTS, NULL);
    _SFCB_RETURN(st);
  }

  CMPIInstance   *ciLocal = CMClone(ci, NULL);
  memLinkInstance(ciLocal);
  CMPIObjectPath* copLocal = CMClone(cop, NULL);
  memLinkObjectPath(copLocal);

  setCCN(copLocal,ciLocal,"CIM_ComputerSystem");

  CMPIString *sysname=ciLocal->ft->getProperty(ciLocal,"SystemName",&st).value.string;
  if (sysname == NULL || sysname->hdl == NULL) {
    char hostName[512];
    hostName[0]=0;
    gethostname(hostName,511); /* should be the same as SystemName of IndicationService */
    CMAddKey(copLocal, "SystemName", hostName, CMPI_chars);
    CMSetProperty(ciLocal,"SystemName",hostName,CMPI_chars);
  }


  CMPIString     *dest =
      CMGetProperty(ciLocal, "destination", &st).value.string;
  if (dest == NULL || CMGetCharPtr(dest) == NULL) {
    setStatus(&st, CMPI_RC_ERR_FAILED,
              "Destination property not found; is required");
    CMRelease(ciLocal);
    _SFCB_RETURN(st);
  } else {                      /* if no scheme is given, assume http (as
                                 * req. for param by mof) */
    char           *ds = CMGetCharPtr(dest);
    if (strstr(ds, "://") == NULL) {
      char           *prefix = "http://";
      int             n = strlen(ds) + strlen(prefix) + 1;
      char           *newdest = (char *) malloc(n * sizeof(char));
      strcpy(newdest, prefix);
      strcat(newdest, ds);
      CMSetProperty(ciLocal, "destination", newdest, CMPI_chars);
      free(newdest);
    }
  }

  CMPIData        persistence =
      CMGetProperty(ciLocal, "persistencetype", &st);
  if (persistence.state == CMPI_nullValue
      || persistence.state == CMPI_notFound) {
    persistenceType = 2;        /* default is 2 = permanent */
  } else if (persistence.value.uint16 < 1 || persistence.value.uint16 > 3) {
    setStatus(&st, CMPI_RC_ERR_FAILED,
              "PersistenceType property must be 1, 2, or 3");
    CMRelease(ciLocal);
    _SFCB_RETURN(st);
  } else {
    persistenceType = persistence.value.uint16;
  }
  CMSetProperty(ciLocal, "persistencetype", &persistenceType, CMPI_uint16);

  if (CMClassPathIsA(_broker, copLocal, "cim_listenerdestination", NULL)) {
    //get the creation timestamp
    struct timeval  tv;
    struct timezone tz;
    char   context[100];
    gettimeofday(&tv, &tz);
    struct tm cttm;
    char * gtime = (char *) malloc(15 * sizeof(char));
    memset(gtime, 0, 15 * sizeof(char));
    if (gmtime_r(&tv.tv_sec, &cttm) != NULL) {
      strftime(gtime, 15, "%Y%m%d%H%M%S", &cttm);
    }

    // Even though reliable indications may be disabled, we need to do this 
    // in case it ever gets enabled.
    // Get the IndicationService name
    CMPIObjectPath * isop = CMNewObjectPath(_broker, "root/interop", "CIM_IndicationService", NULL);
    CMPIEnumeration * isenm = _broker->bft->enumerateInstances(_broker, ctx, isop, NULL, NULL);
    CMPIData isinst = CMGetNext(isenm, NULL);
    CMPIData mc = CMGetProperty(isinst.value.inst, "Name", NULL);

    // build the context string
    sprintf (context,"%s#%s#",mc.value.string->ft->getCharPtr(mc.value.string,NULL),gtime);
    CMPIValue scontext;
    scontext.string = sfcb_native_new_CMPIString(context, NULL, 0);
    free(gtime);

    // set the properties
    CMSetProperty(ciLocal, "SequenceContext", &scontext, CMPI_string);
    CMPIValue zarro = {.sint64 = -1 };
    CMSetProperty(ciLocal, "LastSequenceNumber", &zarro, CMPI_sint64);
  }

  CMPIString     *str = CDToString(_broker, copLocal, NULL);
  CMPIString     *ns = CMGetNameSpace(copLocal, NULL);
  _SFCB_TRACE(1,
              ("--- handler %s %s", (char *) ns->hdl, (char *) str->hdl));

  in = CMNewArgs(_broker, NULL);
  CMAddArg(in, "handler", &ciLocal, CMPI_instance);
  CMAddArg(in, "key", &copLocal, CMPI_ref);
  op = CMNewObjectPath(_broker, "root/interop",
                       "cim_indicationsubscription", &st);
  rv = CBInvokeMethod(_broker, ctx, op, "_addHandler", in, out, &st);

  if (st.rc == CMPI_RC_OK) {
    st = InternalProviderCreateInstance(NULL, ctx, rslt, copLocal, ciLocal);
  }
  else {
    rv=CBInvokeMethod(_broker,ctx,op,"_removeHandler",in,out,NULL);
  }

  _SFCB_RETURN(st);
}

CMPIStatus
IndCIMXMLHandlerModifyInstance(CMPIInstanceMI * mi,
                               const CMPIContext *ctx,
                               const CMPIResult *rslt,
                               const CMPIObjectPath * cop,
                               const CMPIInstance *ci,
                               const char **properties)
{
  CMPIStatus      st = { CMPI_RC_ERR_NOT_SUPPORTED, NULL };
  _SFCB_ENTER(TRACE_INDPROVIDER, "IndCIMXMLHandlerSetInstance");
  _SFCB_RETURN(st);
}
Exemple #25
0
/*****************************************************************************
 * Gets a specific xen resource identified by the CIM Instance passed in
 *
 * @param in broker - CMPI Broker services
 * @param in ft - xen backend provider function table
 * @param in res_id - resource identifying xen object being requested
 * @param in caller_id - CIM Caller's credentials
 * @param in properties - CIM properties caller's interested in
 * @param out res - xen provider resource
 * @return CMPIrc error codes
 *****************************************************************************/
CMPIrc prov_pxy_get(
    const CMPIBroker *broker,
    const XenProviderInstanceFT* ft,
    const void *res_id, 
    struct xen_call_context * caller_id, 
    const char **properties,
    void **res
    )
{
    CMPIInstance *inst = (CMPIInstance *)res_id;
    xen_utils_session *session = NULL;
    CMPIData data;
    static CMPIrc rc = CMPI_RC_OK;
    char *res_uuid=NULL;
    CMPIStatus status = {CMPI_RC_OK, NULL};
    (void)properties;

    CMPIObjectPath *op = CMGetObjectPath(inst, &status);
    CMPIString *cn = CMGetClassName(op, &status);
    if(CMIsNullObject(inst) || res == NULL) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,("Error get(): inst or res is NULL"));
        return CMPI_RC_ERR_FAILED;
    }

    const char *key_prop = ft->xen_resource_get_key_property(broker, 
                                                             CMGetCharPtr(cn));
    data = CMGetProperty(inst, key_prop ,&status); 
    if((status.rc != CMPI_RC_OK) || CMIsNullValue(data)) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
                     ("Error key_property %s couldnt be found for class %s", 
                      key_prop, CMGetCharPtr(cn)));
        return CMPI_RC_ERR_INVALID_PARAMETER;
    }

    /* Extract the resource identifier string from the CMPIString. */
    res_uuid = CMGetCharPtr(data.value.string);
    if(res_uuid == NULL) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Unable to extrace resource identifier string"));
        return CMPI_RC_ERR_FAILED;
    }

    if(!xen_utils_validate_session(&session, caller_id)) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Unable to establish connection with Xen"));
        return CMPI_RC_ERR_FAILED;
    }

    provider_resource *prov_res = calloc(1, sizeof(provider_resource));
    if(prov_res == NULL) {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Out of memory"));
        return CMPI_RC_ERR_FAILED;
    }

    prov_res->broker = broker;
    prov_res->classname = CMGetCharPtr(cn);
    prov_res->session = session;
    prov_res->cleanupsession = true;

    rc = ft->xen_resource_record_get_from_id(res_uuid, session, prov_res);
    if(rc != CMPI_RC_OK)
    {
        _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,("Error get(): get_xen_resource_record_from_id failed"));
        ft->xen_resource_record_cleanup(prov_res);
	xen_utils_cleanup_session(session);
        free(prov_res);
        return rc;
    }
    *res = (void *)prov_res;
    rc = CMPI_RC_OK;

    return rc;
}
CMPIStatus Linux_FanProviderSetInstance( CMPIInstanceMI * mi,
           const CMPIContext * ctx,
           const CMPIResult * rslt,
           const CMPIObjectPath * cop,
           const CMPIInstance * ci,
           const char ** properties) {
    UNUSED(mi); UNUSED(ctx); UNUSED(rslt); UNUSED(properties);

    CMPIStatus             rc    = {CMPI_RC_OK, NULL};
    CMPIData               data;
    char const           * device_id = NULL;
    struct cim_fan       * sptr;
    cim_fan_prop_value_t   cfpv;
    cim_fan_error_t        cmdrc;
    char const           * tmp = NULL;
    char buf[200];

    _OSBASE_TRACE(1, ("--- %s CMPI SetInstance() called", _ClassName));
    
    _check_system_key_value_pairs(_broker, cop, "SystemCreationClassName",
            "SystemName", &rc);
    if (rc.rc != CMPI_RC_OK) {
        _OSBASE_TRACE(1, ("--- %s CMPI SetInstance() failed : %s",
                _ClassName, CMGetCharPtr(rc.msg)));
        return rc;
    }

    data = CMGetKey(cop, "DeviceID", &rc);
    if (data.value.string == NULL) {
        CMSetStatusWithChars(_broker, &rc,
                CMPI_RC_ERR_FAILED, "Could not get fan ID." );
        _OSBASE_TRACE(1, ("--- %s CMPI SetInstance() failed : %s",
                _ClassName, CMGetCharPtr(rc.msg)));
    }
    device_id = CMGetCharPtr(data.value.string);
    if (device_id) {
        cmdrc = get_fan_data_by_id(device_id, &sptr);
    }
    if (cmdrc || !sptr) {
        CMSetStatusWithChars(_broker, &rc,
                CMPI_RC_ERR_NOT_FOUND, cim_fan_strerror(cmdrc));
        _OSBASE_TRACE(1, ("--- %s CMPI SetInstance() exited : %s",
                _ClassName,CMGetCharPtr(rc.msg)));
        return rc;
    }

    data = CMGetProperty(ci, "MinSpeed", &rc);
    if (!rc.rc && data.value.uint64 != (uint64_t) sptr->min_speed) {
        tmp = "MinSpeed";
        cfpv.min_speed = data.value.uint64;
        cmdrc = set_fan_prop_by_id(device_id, CIM_FAN_MIN_SPEED, &cfpv);
    }
    data = CMGetProperty(ci , "MaxSpeed", &rc);
    if (!cmdrc && !rc.rc && data.value.uint64 != (uint64_t) sptr->max_speed) {
        tmp = "MaxSpeed";
        cfpv.max_speed = data.value.uint64;
        set_fan_prop_by_id(device_id, CIM_FAN_MAX_SPEED, &cfpv);
    }
    data = CMGetProperty(ci, "Divisor", &rc);
    if (!cmdrc && !rc.rc && data.value.uint32 != sptr->divisor) {
        tmp = "Divisor";
        cfpv.divisor = data.value.uint32;
        set_fan_prop_by_id(device_id, CIM_FAN_DIV, &cfpv);
    }
    data = CMGetProperty(ci, "Pulses", &rc);
    if (!cmdrc && !rc.rc && data.value.uint32 != sptr->pulses) {
        tmp = "Pulses";
        cfpv.pulses = data.value.uint32;
        set_fan_prop_by_id(device_id, CIM_FAN_PULSES, &cfpv);
    }
    data = CMGetProperty(ci, "Beep", &rc);
    if (!cmdrc && !rc.rc && data.value.boolean != sptr->beep) {
        tmp = "Beep";
        cfpv.beep = data.value.uint32;
        set_fan_prop_by_id(device_id, CIM_FAN_BEEP, &cfpv);
    }

    if (cmdrc) {
        if (tmp && cmdrc == CIM_FAN_SEN_NO_ENTRY) {
            snprintf(buf, 200,
                "System interface for fan(name=\"%s\", chip=\"%s\") does not"
               " provide a way to set \"%s\".", sptr->name, sptr->chip_name,
               tmp);
            CMSetStatusWithChars(_broker, &rc,
                    CMPI_RC_ERR_FAILED, buf);
        }else {
            CMSetStatusWithChars(_broker, &rc,
                    CMPI_RC_ERR_FAILED, cim_fan_strerror(cmdrc))
        }
        _OSBASE_TRACE(2, ("--- %s CMPI SetInstance() exited : %s",
                _ClassName, CMGetCharPtr(rc.msg)));
    }else {