int enqRetry(RTElement * element, const CMPIContext * ctx, int repo) { _SFCB_ENTER(TRACE_INDPROVIDER, "enqRetry"); // Put this one on the retry queue if (pthread_mutex_lock(&RQlock) != 0) { // lock failed return 1; } if (RQhead == NULL) { // Queue is empty _SFCB_TRACE(1,("--- Adding indication to new retry queue.")); RQhead = element; RQtail = element; RQtail->next = element; RQtail->prev = element; } else { _SFCB_TRACE(1,("--- Adding indication to retry queue.")); element->next = RQtail->next; element->next->prev = element; RQtail->next = element; element->prev = RQtail; RQtail = element; } if (repo==1) { // If this needs to be persisted in the repo // (not the initial fill from refillRetryQ) _SFCB_TRACE(1,("--- Creating SFCB_IndicationElement instance.")); CMPIObjectPath * op=CMNewObjectPath(_broker,"root/interop","SFCB_IndicationElement",NULL); // Add the indID as the only key CMAddKey(op,"IndicationID",&element->instanceID,CMPI_uint32); // Create the instance //element->SFCBIndEle=op; element->SFCBIndEle=op->ft->clone(op,NULL); CMPIInstance * ci=CMNewInstance(_broker,op,NULL); // Set all the properties CMSetProperty(ci,"IndicationID",&element->instanceID,CMPI_uint32); CMSetProperty(ci,"RetryCount",&(RQtail->count),CMPI_uint32); CMSetProperty(ci,"LastDelivery",&(RQtail->lasttry),CMPI_sint32); CMSetProperty(ci,"ld",&(element->ref),CMPI_ref); CMSetProperty(ci,"ind",&element->ind,CMPI_ref); CMSetProperty(ci,"sub",&element->sub,CMPI_ref); CBCreateInstance(_broker, ctx, op, ci, NULL); CMRelease(op); CMRelease(ci); } if (pthread_mutex_unlock(&RQlock) != 0) { // lock failed return 1; } _SFCB_RETURN(0); }
static void TCPCOMM_createInstance(int socket, CONST CMPIBroker * broker, CONST CMPIContext * context) { CMPIStatus rc; CMPIObjectPath *cop, *result; CMPIInstance *instance; cop = (__sft)->deserialize_CMPIObjectPath(socket, broker); instance = (__sft)->deserialize_CMPIInstance(socket, broker); result = CBCreateInstance(broker, context, cop, instance, &rc); (__sft)->serialize_CMPIStatus(socket, &rc); (__sft)->serialize_CMPIObjectPath(socket, result); }
void ElementCapabilitiesInitInstances(const CMPIContext *ctx) { CMPIObjectPath *op = NULL, *opLeft = NULL, *opRight = NULL, *left = NULL, *right = NULL; CMPIValue val; CMPIEnumeration *enm = NULL; CMPIInstance *ci = NULL; CMPIContext *ctxLocal; ctxLocal = native_clone_CMPIContext(ctx); val.string = sfcb_native_new_CMPIString("$DefaultProvider$", NULL, 0); ctxLocal->ft->addEntry(ctxLocal, "rerouteToProvider", &val, CMPI_string); op = CMNewObjectPath(_broker, "root/interop", "SFCB_ElementCapabilities", NULL); ci = CMNewInstance(_broker, op, NULL); opLeft = CMNewObjectPath(_broker, "root/interop", "CIM_IndicationService", NULL); enm = CBEnumInstanceNames(_broker, ctx, opLeft, NULL); left = CMGetNext(enm, NULL).value.ref; opRight = CMNewObjectPath(_broker, "root/interop", "SFCB_IndicationServiceCapabilities", NULL); enm = CBEnumInstanceNames(_broker, ctx, opRight, NULL); right = CMGetNext(enm, NULL).value.ref; CMAddKey(op, "ManagedElement", &left, CMPI_ref); CMAddKey(op, "Capabilities", &right, CMPI_ref); CMSetProperty(ci, "ManagedElement", &left, CMPI_ref); CMSetProperty(ci, "Capabilities", &right, CMPI_ref); CBCreateInstance(_broker, ctxLocal, op, ci, NULL); CMRelease(ctxLocal); return; }
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); }