static CMPIStatus initialize(CMPIClassMI * mi, CMPIContext *ctx) { CMPIStatus st; char *p, c; /* * to set params, in providerRegister add line: parameters: -c10 -r15 */ static struct option const long_options[] = { {"base-class-cache", required_argument, 0, 'c'}, {"resolved-class-cache", required_argument, 0, 'r'}, {0, 0, 0, 0} }; char msg[] = "--- Invalid classProviderSf parameter -%c %s ignored \n"; CMPIData parms = ctx->ft->getEntry(ctx, "sfcbProviderParameters", &st); if (st.rc == 0) { argv = buildArgList((char *) parms.value.string->hdl, "classProviderSf", &argc); mlogf(M_INFO, M_SHOW, "--- %s parameters: %s\n", argv[0], (char *) parms.value.string->hdl); while ((c = getopt_long(argc, argv, "c:r:", long_options, 0)) != -1) { switch (c) { case 0: break; case 'c': if (isdigit(*optarg)) cSize = strtol(optarg, &p, 0); else mlogf(M_INFO, M_SHOW, msg, c, optarg); break; case 'r': if (isdigit(*optarg)) rSize = strtol(optarg, &p, 0); else mlogf(M_INFO, M_SHOW, msg, c, optarg); break; default: mlogf(M_INFO, M_SHOW, msg, c, optarg); } } } else { } // CJB if (nsHt==NULL) nsHt=buildClassRegisters(); CMReturn(CMPI_RC_OK); }
static char * keyType(CMPIType type) { switch (type) { case CMPI_chars: case CMPI_string: case CMPI_dateTime: return "string"; case CMPI_sint64: case CMPI_uint64: case CMPI_sint32: case CMPI_uint32: case CMPI_sint16: case CMPI_uint16: case CMPI_uint8: case CMPI_sint8: return "numeric"; case CMPI_boolean: return "boolean"; case CMPI_ref: return "*"; } mlogf(M_ERROR, M_SHOW, "%s(%d): invalid key data type %d %x\n", __FILE__, __LINE__, (int) type, (int) type); SFCB_ASM("int $3"); abort(); return "*??*"; }
int ipfix_ssl_setup_server_ctx( SSL_CTX **ssl_ctx, SSL_METHOD *method, ipfix_ssl_opts_t *ssl_details ) { SSL_CTX *ctx; if ( ipfix_ssl_setup_ctx( &ctx, method?method:SSLv23_method(), ssl_details ) <0 ) { return -1; } SSL_CTX_set_verify( ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ipfix_ssl_verify_callback ); SSL_CTX_set_verify_depth( ctx, 4 ); SSL_CTX_set_options( ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE); if (!dh512 || !dh1024) { init_dhparams(); } SSL_CTX_set_tmp_dh_callback( ctx, ipfix_ssl_tmp_dh_callback ); if (SSL_CTX_set_cipher_list( ctx, CIPHER_LIST) != 1) { mlogf( 0, "[ipfix] error setting cipher list (no valid ciphers)"); goto err; } *ssl_ctx = ctx; return 0; err: SSL_CTX_free( ctx ); return -1; }
int ipfix_ssl_setup_client_ctx( SSL_CTX **ssl_ctx, SSL_METHOD *method, ipfix_ssl_opts_t *ssl_details ) { SSL_CTX *ctx; if ( ipfix_ssl_setup_ctx( &ctx, method?method:SSLv23_method(), ssl_details ) <0 ) return -1; SSL_CTX_set_verify( ctx, SSL_VERIFY_PEER, ipfix_ssl_verify_callback); SSL_CTX_set_verify_depth( ctx, 4); SSL_CTX_set_options( ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2); if (SSL_CTX_set_cipher_list( ctx, CIPHER_LIST) != 1) { mlogf( 0, "[ipfix] Error setting cipher list (no valid ciphers)"); goto err; } *ssl_ctx = ctx; return 0; err: SSL_CTX_free( ctx ); return -1; }
static ClassRegister * getNsReg(const CMPIObjectPath * ref, int *rc) { char *ns; CMPIString *nsi = CMGetNameSpace(ref, NULL); ClassRegister *cReg; *rc = 0; pthread_once(&nsHt_once, nsHt_init); if (nsHt == NULL) { mlogf(M_ERROR, M_SHOW, "--- ClassProvider: namespace hash table not initialized\n"); *rc = 1; return NULL; } if (nsi && nsi->hdl) { ns = (char *) nsi->hdl; if (strcasecmp(ns, "root/pg_interop") == 0) cReg = nsHt->ft->get(nsHt, "root/interop"); else cReg = nsHt->ft->get(nsHt, ns); return cReg; } *rc = 1; return NULL; }
void handleSSLerror(const char *file, int lineno, const char *msg) { mlogf(M_ERROR, M_SHOW, "\n*** %s:%i %s -- exiting\n", file, lineno, msg); #ifdef SFCB_DEBUG ERR_print_errors_fp(stderr); #endif exit(-1); }
static int addProviderToHT(ProviderInfo *info, UtilHashTable *ht) { ProviderInfo *checkDummy; /* first we add the provider to the providerRegister with the classname * as a key*/ checkDummy = ht->ft->get(ht, info->className); if(checkDummy) { /* Another provider is in the register, but the newly found * wants to serve the same class - so we do not add it to the * register but append it to the one already found or to its master*/ if (strcmp(checkDummy->providerName, info->providerName) == 0) { if (checkDummy->type != info->type) { mlogf(M_ERROR,M_SHOW,"--- Conflicting registration types for class %s, provider %s\n", info->className, info->providerName); return 1; } /* FIXME: check location, user, group, parms, unload */ /* classname and provider name match, now check for namespace */ int idx = 0; while (checkDummy->ns[idx]) { if (strcmp(checkDummy->ns[idx], info->ns[0]) == 0) { /* double registration - discard */ freeInfoPtr(info); return 0; } ++idx; } /* additional namespace for existing classname and provider name */ mlogf(M_INFO,M_SHOW,"--- Collating namespaces for registration of class %s, provider %s; consider single providerRegister entry\n", info->className, info->providerName); checkDummy->ns=(char**)realloc(checkDummy->ns,sizeof(char*)*(idx+2)); checkDummy->ns[idx] = strdup(info->ns[0]); checkDummy->ns[++idx] = NULL; freeInfoPtr(info); } else { /* add info to the nIR linked list */ info->nextInRegister = checkDummy->nextInRegister; checkDummy->nextInRegister = info; } } else { ht->ft->put(ht, info->className, info); } return 0; }
static CMPIStatus __rft_returnData(const CMPIResult * result, const CMPIValue * val, CMPIType type) { // NativeResult *r = (NativeResult*) result; if (type==CMPI_ref) { mlogf(M_ERROR,M_SHOW,"--- CMPIResult does not yet support returning references\n"); abort(); } return returnData(result,val,type); }
int ipfix_ssl_verify_callback(int ok, X509_STORE_CTX *store) { char data[256]; if (!ok) { X509 *cert = X509_STORE_CTX_get_current_cert(store); int depth = X509_STORE_CTX_get_error_depth(store); int err = X509_STORE_CTX_get_error(store); mlogf( 1, "[%s] Error with certificate at depth: %i\n", __func__, depth); X509_NAME_oneline( X509_get_issuer_name(cert), data, 256); mlogf( 1, " issuer = %s\n", data); X509_NAME_oneline( X509_get_subject_name(cert), data, 256); mlogf( 1, " subject = %s\n", data); mlogf( 1, " err %i:%s\n", err, X509_verify_cert_error_string(err)); } return ok; }
/* name : prog_init * parameters : none, global parameters * description: some program initialisation * returns : 0 if ok, -1 on error * remarks : */ int prog_init ( void ) { /* daemon */ if ( (g_par.flags&PROBE_DAEMON) && (daemon ( 0, 0 ) < 0) ) { errorf ( "[%s] failed to run as daemon!\n\n", g_par.progname ); return -1; } #if 0 if ( chdir ( "/tmp" ) <0 ) mlogf( 0, "[%s] ERROR cannot change working dir: %s\n", g_par.progname, strerror(errno) ); #endif /* open logfile */ mlog_set_vlevel( g_par.vlevel ); if ( g_par.logfile ) (void) mlog_open( g_par.logfile, NULL ); mlogf( 1, "\nIPFIX probe (%s)\n\n", __DATE__ ); /* signal handler */ signal( SIGKILL, exit_func ); signal( SIGTERM, exit_func ); signal( SIGINT, exit_func ); /* init exporter */ if ( export_init( &g_probe ) <0 ) { return -1; } /* init pcap sniffing */ if ( input_init( &g_probe, g_par.flags ) <0 ) { return -1; } return 0; }
static int ipfix_ssl_setup_ctx( SSL_CTX **ssl_ctx, SSL_METHOD *method, ipfix_ssl_opts_t *ssl_details ) { SSL_CTX *ctx; char buffer[PATH_MAX]; if ( ((ctx=SSL_CTX_new(method)) ==NULL ) || (SSL_CTX_load_verify_locations( ctx, ssl_details->cafile, ssl_details->cadir ) != 1)) { mlogf( 0, "[ipfix] error loading ca file and/or directory " "(cwd=%s,file=%s): %s\n", getcwd(buffer, sizeof(buffer)), ssl_details->cafile, strerror(errno) ); goto err; } if ( SSL_CTX_set_default_verify_paths(ctx) != 1) { mlogf( 0, "[ipfix] error loading default CA file and/or dir\n"); goto err; } if ( SSL_CTX_use_certificate_chain_file(ctx, ssl_details->certfile) != 1) { mlogf( 0, "[ipfix] error loading certificate from file"); goto err; } if ( SSL_CTX_use_PrivateKey_file( ctx, ssl_details->keyfile, SSL_FILETYPE_PEM ) != 1) { mlogf( 0, "[ipfix] Error loading private key from file: %s\n", ssl_details->keyfile ); goto err; } *ssl_ctx = ctx; return 0; err: SSL_CTX_free( ctx ); return -1; }
/* name : cb_dispatch * remarks : */ void cb_dispatch( int fd, int mask, void *data ) { probe_t *p = (probe_t*)data; switch ( pcap_dispatch( p->pcap, p->cnt, cb_packet, data ) ) { case -1: mlogf( 0, "[%s] pcap_dispatch: %s\n", p->device, pcap_geterr(p->pcap)); break; case 0: if ( g_par.flags & PROBE_OFFLINE ) { mlogf( 1, "[%s] end of file detected, break ...\n", p->device ); mpoll_break(); } break;; default: return; } return; }
int ipfix_export_trecord_db( ipfixs_node_t *s, ipfixt_node_t *t, void *arg ) { ipfixe_data_db_t *data = (ipfixe_data_db_t*)arg; char *func = "export_trecord_db"; if ( !data->mysql ) return -1; /** build tablename */ strcpy( t->tablename, "" ); t->message_snr = s->last_message_snr-1; /*!!*/ if ( ipfix_db_get_tablename( data->mysql, t->tablename, MAXTABLENAMELEN, &(t->template_id), t->ipfixt, 1 ) <0 ) { /** todo! */ mlogf( 1, "[%s] cannot build table name for template %d\n", func, t->ipfixt->tid ); } mlogf( 4, "[%s] template %d use table %s\n", func, t->ipfixt->tid, t->tablename ); return 0; }
static void outf( FILE *fp, char fmt[], ... ) { va_list args; va_start( args, fmt ); (void) vsprintf(tmpbuf, fmt, args ); va_end( args ); if ( fp ) { fprintf( fp, "%s", tmpbuf ); } else { mlogf( 0, "%s", tmpbuf ); } }
int ipfix_export_newsrc_db( ipfixs_node_t *s, void *arg ) { ipfixe_data_db_t *data = (ipfixe_data_db_t*)arg; int32_t exporter_id =0; if ( !data->mysql ) { errno = EINVAL; return -1; } snprintf( query, MAXQUERYLEN, "SELECT %s FROM %s WHERE %s='%u' AND %s='%s'", IPFIX_DB_EXP_ID, IPFIX_DB_EXPORTERS, IPFIX_DB_EXP_ODID, s->odid, IPFIX_DB_EXP_ADDR, ipfix_col_input_get_ident( s->input ) ); if ( ipfix_db_get_int( data->mysql, query, &exporter_id ) !=0 ) { mlogf( 0, "[export_newsrc_db] query(%s) failed!\n", query ); return -1; } if ( exporter_id == 0 ) { snprintf( query, MAXQUERYLEN, "INSERT INTO %s SET %s='%u', %s='%s', %s='-'", IPFIX_DB_EXPORTERS, IPFIX_DB_EXP_ODID, s->odid, IPFIX_DB_EXP_ADDR, ipfix_col_input_get_ident( s->input ), IPFIX_DB_EXP_DESCR ); if ( mysql_query( data->mysql, query ) !=0 ) { mlogf( 0, "[export_newmsg_db] mysql_query(%s) failed: %s\n", query, mysql_error(data->mysql) ); return -1; } exporter_id = (int32_t)mysql_insert_id( data->mysql ); } s->exporterid = (unsigned int)exporter_id; return 0; }
/* name : exit_func */ void exit_func ( int signo ) { if ( signo ) mlogf( 0, "\n[%s] Got signo %d. Bye.\n\n", g_par.progname, signo ); /* export flows */ (void)export_ipflows( &g_probe, time(NULL), 1 ); /** clean up */ mlogf( 1, "[%s] clean up.\n", g_par.progname ); mpoll_fdrm( g_probe.fd ); if ( g_par.filter ) { free( g_par.filter ); #ifdef HAVE_PCAP_FREECODE pcap_freecode( &(g_probe.fprg) ); #endif } pcap_close( g_probe.pcap ); ipfix_delete_template( g_probe.ipfix, g_probe.templ ); ipfix_delete_template( g_probe.ipfix, g_probe.templ6 ); ipfix_close( g_probe.ipfix ); ipfix_cleanup(); if ( g_probe.device ) free( g_probe.device ); if ( export_tid ) mpoll_timerrm( export_tid ); flow_close( g_probe.ipflows ); mlog_close(); exit(0); }
static UtilHashTable * gatherNameSpaces(char *dn, UtilHashTable * ns, int first) { DIR *dir, *dir_test; struct dirent *de; char *n = NULL; int l; ClassRegister *cr; if (ns == NULL) { ns = UtilFactory->newHashTable(61, UtilHashTable_charKey | UtilHashTable_ignoreKeyCase); nsBaseLen = strlen(dn) + 1; } dir = opendir(dn); if (dir) while ((de = readdir(dir)) != NULL) { if (strcmp(de->d_name, ".") == 0) continue; if (strcmp(de->d_name, "..") == 0) continue; l = strlen(dn) + strlen(de->d_name) + 4; n = (char *) malloc(l + 8); strcpy(n, dn); strcat(n, "/"); strcat(n, de->d_name); dir_test = opendir(n); if (dir_test == NULL) { free(n); continue; } closedir(dir_test); cr = newClassRegister(n); if (cr) { ns->ft->put(ns, strdup(n + nsBaseLen), cr); gatherNameSpaces(n, ns, 0); } free(n); } else if (first) { mlogf(M_ERROR, M_SHOW, "--- Repository %s not found\n", dn); } closedir(dir); return ns; }
static char * dataType(CMPIType type) { switch (type & ~CMPI_ARRAY) { case CMPI_chars: case CMPI_string: return "string"; case CMPI_sint64: return "sint64"; case CMPI_uint64: return "uint64"; case CMPI_sint32: return "sint32"; case CMPI_uint32: return "uint32"; case CMPI_sint16: return "sint16"; case CMPI_uint16: return "uint16"; case CMPI_uint8: return "uint8"; case CMPI_sint8: return "sint8"; case CMPI_boolean: return "boolean"; case CMPI_char16: return "char16"; case CMPI_real32: return "real32"; case CMPI_real64: return "real64"; case CMPI_dateTime: return "datetime"; case CMPI_ref: return "*"; case CMPI_instance: return "%"; } mlogf(M_ERROR, M_SHOW, "%s(%d): invalid data type %d %x\n", __FILE__, __LINE__, (int) type, (int) type); SFCB_ASM("int $3"); abort(); return "*??*"; }
int ipfix_export_newmsg_db( ipfixs_node_t *s, ipfix_hdr_t *hdr, void *arg ) { ipfixe_data_db_t *data = (ipfixe_data_db_t*)arg; if ( data->mysql ) { snprintf( query, MAXQUERYLEN, "INSERT INTO %s SET %s='%u', %s='%lu'", IPFIX_DB_MESSAGETABLE, IPFIX_DB_MSGT_EXPID, s->exporterid, IPFIX_DB_MSGT_TIME, (hdr->version==IPFIX_VERSION_NF9)? (u_long)hdr->u.nf9.unixtime:(u_long)hdr->u.ipfix.exporttime ); if ( mysql_query( data->mysql, query ) !=0 ) { mlogf( 0, "[export_newmsg_db] mysql_query(%s) failed: %s\n", query, mysql_error(data->mysql) ); return -1; } s->last_msgid = (unsigned int) mysql_insert_id( data->mysql ); } return 0; }
static CMPIPredicate* __eft_getPredicateAt (const CMPISubCond* cond, unsigned int index, CMPIStatus* rc) { NativeSubCond *c = (NativeSubCond *)cond; CMPIValuePtr pvp={NULL,0}; CMPIPredicate *pr=NULL; CMPICount count=0; CMPIStatus irc={CMPI_RC_ERR_NOT_FOUND,NULL}; CMPIArray *conds=(CMPIArray*)c->cond.ptr; if (conds) { count=CMGetArrayCount(conds,NULL); if (index<count) pvp=CMGetArrayElementAt(conds,index,&irc).value.dataPtr; } else { mlogf(M_ERROR,M_SHOW,"### getPredicateAt, no conds\n"); } if (rc) *rc=irc; if (pvp.ptr) pr=TrackedCMPIPredicate(pvp,&irc); return pr; }
void * getBlob(const char *ns, const char *cls, const char *id, int *len) { int keyl = strlen(ns) + strlen(cls) + strlen(id) + strlen(BASE); BlobIndex *bi; char *buf; int rc = 0; // checking for qualifiers should be case-insensitive short ignorecase = (strcmp("qualifiers", cls)) ? 0 : 1; rc = getIndex(ns, cls, keyl + 64, 0, &bi); if (rc) { if (indxLocateCase(bi, id, ignorecase)) { bi->fd = fopen(bi->fnd, "rb"); if (bi->fd == NULL) { fdHandleError(bi); char *emsg = strerror(errno); mlogf(M_ERROR, M_SHOW, "Repository error: %s\n", emsg); exit(5); } fseek(bi->fd, bi->bofs, SEEK_SET); buf = malloc(bi->blen + 8); fread(buf, bi->blen, 1, bi->fd); if (len) *len = bi->blen; buf[bi->blen] = 0; freeBlobIndex(&bi, 1); return (void *) buf; } } freeBlobIndex(&bi, 1); return NULL; }
int ipfix_ssl_init_con( SSL *con ) { extern FILE *mlog_fp; // todo: see if this is working int i; char *str; long verify_error; char buf[100]; if ((i=SSL_accept(con)) <= 0) { if (BIO_sock_should_retry(i)) { mlogf( 0, "[ipfix_ssl_init] DELAY\n"); return -1; } mlogf( 0, "[ipfix_ssl_init] ERROR\n"); verify_error=SSL_get_verify_result( con ); if (verify_error != X509_V_OK) { mlogf( 0, "[ipfix_ssl_init] verify error: %s\n", X509_verify_cert_error_string(verify_error)); } else ERR_print_errors_fp( mlog_fp ); return -1; } if ( 1 <= mlog_get_vlevel() ) { PEM_write_SSL_SESSION( mlog_fp, SSL_get_session(con)); if ( SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL) { mlogf( 3, "[ipfix] Shared ciphers:%s\n", buf); } str=(char*)SSL_CIPHER_get_name( SSL_get_current_cipher(con) ); mlogf( 3, "[ipfix] CIPHER is %s\n",(str != NULL)?str:"(NONE)"); if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) & TLS1_FLAGS_TLS_PADDING_BUG) { mlogf( 1, "[ipfix] Peer has incorrect TLSv1 block padding\n"); } } return 0; }
static ClassRegister * newClassRegister(ClassSchema * cs, const char *ns) { ClassRegister *cr = malloc(sizeof(*cr) + sizeof(ClassBase)); ClassBase *cb = (ClassBase *) (cr + 1); long s, total = 0; ClObjectHdr *hdr; ClVersionRecord *vrp = (ClVersionRecord *) cs->versionRecord; ClassDir *cd = cs->classes; int first = 1; cr->hdl = cb; cr->ft = ClassRegisterFT; cr->vr = vrp; cr->assocs = cr->topAssocs = 0; cb->ht = UtilFactory->newHashTable(61, UtilHashTable_charKey | UtilHashTable_ignoreKeyCase); MRWInit(&cb->mrwLock); cr->fn = strdup(ns); if (vrp && vrp->size == sizeof(ClVersionRecord) << 24 && vrp->type == HDR_Version) { mlogf(M_ERROR, M_SHOW, "--- %s is in wrong endian format - namespace skipped\n", ns); return NULL; } while (cd && cd->hdr) { CMPIConstClass *cc = NULL; char *cn; hdr = cd->hdr; if (hdr->type != HDR_Class) { mlogf(M_ERROR, M_SHOW, "--- %s contains non-class record(s) - namespace skipped\n", ns); return NULL; } s = hdr->size; if (first) { int v = -1; first = 0; if (ClVerifyObjImplLevel(cr->vr)) continue; if (cr->vr) v = cr->vr->objImplLevel; mlogf(M_ERROR, M_SHOW, "--- %s contains unsupported object implementation format (%d) - namespace skipped\n", ns, v); return NULL; } cc = NEW(CMPIConstClass); cc->hdl = hdr; cc->ft = CMPIConstClassFT; cc->ft->relocate(cc); cn = (char *) cc->ft->getCharClassName(cc); if (strncmp(cn, "DMY_", 4) != 0) { total += s; cb->ht->ft->put(cb->ht, cn, cc); if (cc->ft->isAssociation(cc)) { cr->assocs++; if (cc->ft->getCharSuperClassName(cc) == NULL) cr->topAssocs++; } } else { mlogf(M_ERROR, M_SHOW, "--- %s contains invalid record(s) - namespace skipped\n", ns); return NULL; } first = 0; cd += 1; } if (cr->vr) { mlogf(M_INFO, M_SHOW, "--- ClassProvider for %s (%d.%d-%d) using %ld bytes\n", ns, cr->vr->version, cr->vr->level, cr->vr->objImplLevel, total); } else mlogf(M_INFO, M_SHOW, "--- ClassProvider for %s (no-version) using %ld bytes\n", ns, total); buildInheritanceTable(cr); return cr; }
ProviderRegister *newProviderRegister() { FILE *in; char *dir,*provuser = NULL; char fin[1024], *stmt = NULL; ProviderInfo *info = NULL; int err = 0, n = 0, i; CntlVals rv; int id=0; int provSFCB,provuid=-1; int interopFound=0; struct passwd *passwd; ProviderRegister *br = (ProviderRegister *) malloc(sizeof(ProviderRegister) + sizeof(ProviderBase)); ProviderBase *bb = (ProviderBase *) (br + 1); setupControl(configfile); // Get/check provider user info if (getControlBool("providerDefaultUserSFCB",&provSFCB)) { provSFCB = 1; } if (provSFCB) { // This indicates that we should use the SFCB user by default provuid = -1; } else { if (getControlChars("providerDefaultUser",&provuser)) { provuid = -1; } else { errno=0; passwd=getpwnam(provuser); if (passwd) { provuid=passwd->pw_uid; } else { mlogf(M_ERROR,M_SHOW,"--- Couldn't find username %s requested in SFCB config file. Errno: %d\n",provuser,errno); err=1; } } } if (getControlChars("registrationDir",&dir)) { dir = "/var/lib/sfcb/registration"; } strcpy(fin, dir); strcat(fin, "/providerRegister"); in = fopen(fin, "r"); if (in == NULL) mlogf(M_ERROR,M_SHOW, "--- %s not found\n", fin); else { br->hdl = bb; br->ft = ProviderRegisterFT; bb->fn = strdup(fin); bb->ht = UtilFactory->newHashTable(61, UtilHashTable_charKey | UtilHashTable_ignoreKeyCase); while (fgets(fin, 1024, in)) { n++; if (stmt) free(stmt); stmt = strdup(fin); switch (cntlParseStmt(fin, &rv)) { case 0: mlogf(M_ERROR,M_SHOW,"--- registration statement not recognized: \n\t%d: %s\n", n,stmt); err = 1; break; case 1: if (info) { if (classProvInfoPtr==NULL) { if (strcmp(info->className,"$ClassProvider$")==0) classProvInfoPtr=info; } else if (defaultProvInfoPtr==NULL) { if (strcmp(info->className,"$DefaultProvider$")==0) defaultProvInfoPtr=info; } else if (interOpProvInfoPtr==NULL) { if (strcmp(info->className,"$InterOpProvider$")==0) { if (exFlags & 2) interOpProvInfoPtr=info; else interopFound=1; } } else if (qualiProvInfoPtr==NULL) { if (strcmp(info->className,"$QualifierProvider$")==0) qualiProvInfoPtr=info; } err = addProviderToHT(info, ((ProviderBase *) br->hdl)->ht); if (err) break; } info = (ProviderInfo *) calloc(1, sizeof(ProviderInfo)); info->className = strdup(rv.id); info->id= ++id; // Set the default provider uid info->uid=provuid; if (!provSFCB) info->user=strdup(provuser); break; case 2: if (strcmp(rv.id, "provider") == 0) info->providerName = strdup(cntlGetVal(&rv)); else if (strcmp(rv.id, "location") == 0) info->location = strdup(cntlGetVal(&rv)); else if (strcmp(rv.id, "parameters") == 0) { info->parms = strdup(cntlGetStr(&rv)); for (i=strlen(info->parms); i>0 && info->parms[i]<=' '; i--) { info->parms[i]=0; } } else if (strcmp(rv.id, "user") == 0) { info->user = strdup(cntlGetVal(&rv)); errno=0; passwd=getpwnam(info->user); if (passwd) { info->uid=passwd->pw_uid; } else { mlogf(M_ERROR,M_SHOW,"--- Couldn't find username %s requested in providerRegister. Errno: %d\n",info->user,errno); err = 1; break; } } else if (strcmp(rv.id, "group") == 0) info->group = strdup(cntlGetVal(&rv)); else if (strcmp(rv.id, "unload") == 0) { char *u; info->unload = 0; while ((u = cntlGetVal(&rv)) != NULL) { if (strcmp(u, "never") == 0) { info->unload =-1; } else { mlogf(M_ERROR,M_SHOW,"--- invalid unload specification: \n\t%d: %s\n", n, stmt); err = 1; } } } else if (strcmp(rv.id, "type") == 0) { char *t; info->type = 0; while ((t = cntlGetVal(&rv)) != NULL) { if (strcmp(t, "instance") == 0) info->type |= INSTANCE_PROVIDER; else if (strcmp(t, "association") == 0) info->type |= ASSOCIATION_PROVIDER; else if (strcmp(t, "method") == 0) info->type |= METHOD_PROVIDER; else if (strcmp(t, "indication") == 0) info->type |= INDICATION_PROVIDER; else if (strcmp(t, "class") == 0) info->type |= CLASS_PROVIDER; else if (strcmp(t, "property") == 0) info->type |= PROPERTY_PROVIDER; else if (strcmp(t, "qualifier") == 0) info->type |= QUALIFIER_PROVIDER; else { mlogf(M_ERROR,M_SHOW,"--- invalid type specification: \n\t%d: %s\n", n, stmt); err = 1; } } } else if (strcmp(rv.id, "namespace") == 0) { int max=1,next=0; char *t; info->ns=(char**)malloc(sizeof(char*)*(max+1)); while ((t = cntlGetVal(&rv)) != NULL) { if (next==max) { max++; info->ns=(char**)realloc(info->ns,sizeof(char*)*(max+1)); } info->ns[next]=strdup(t); info->ns[++next]=NULL; } } else { mlogf(M_ERROR,M_SHOW,"--- invalid registration statement: \n\t%d: %s\n", n, stmt); err = 1; } break; case 3: break; } if (err) break; } if (info) { if (err == 0) { err = addProviderToHT(info, ((ProviderBase *) br->hdl)->ht); } else { freeInfoPtr(info); } } } if (in) { fclose(in); } if (classProvInfoPtr==NULL) { mlogf(M_ERROR,M_SHOW,"--- Class provider definition not found - sfcbd will terminate\n"); err=1; } if (defaultProvInfoPtr==NULL) mlogf(M_INFO,M_SHOW,"--- Default provider definition not found - no instance repository available\n"); if (qualiProvInfoPtr==NULL) mlogf(M_INFO,M_SHOW,"--- Qualifier provider definition not found - no qualifier support available\n"); if (interOpProvInfoPtr==NULL) { if (exFlags & 2 && interopFound==0) mlogf(M_INFO,M_SHOW,"--- InterOp provider definition not found - no InterOp support available\n"); else if (interopFound) mlogf(M_INFO,M_SHOW,"--- InterOp provider definition found but not started - no InterOp support available\n"); interOpProvInfoPtr=&forceNotFound; } if (err) { mlogf(M_ERROR,M_SHOW,"--- Broker terminated because of previous error(s)\n"); exit(5); } if (stmt) free(stmt); return br; }
static ClassRegister * newClassRegister(char *fname, char *ns) { ClassRegister *cr = (ClassRegister *) malloc(sizeof(ClassRegister) + sizeof(ClassBase)); ClassBase *cb = (ClassBase *) (cr + 1); FILE *in; char fin[1024]; long s, total = 0; ClObjectHdr hdr; ClVersionRecord *vrp = (ClVersionRecord *) & hdr; int vRec = 0, first = 1; cr->hdl = cb; // cr->ft = ClassRegisterFT; cr->vr = NULL; cr->assocs = cr->topAssocs = 0; strcpy(fin, fname); strcat(fin, "/classSchemas"); fprintf(stderr, "Opening %s\n", fname); in = fopen(fin, "r"); if (in == NULL) { fprintf(stderr, "-*- classSchema directory %s not found\n", fname); return NULL; } cr->fn = strdup(fin); cb->ht = UtilFactory->newHashTable(61, UtilHashTable_charKey | UtilHashTable_ignoreKeyCase); MRWInit(&cb->mrwLock); while ((s = fread(&hdr, 1, sizeof(hdr), in)) == sizeof(hdr)) { CMPIConstClass *cc = NULL; char *buf = NULL; char *cn; if (first) { if (vrp->size == sizeof(ClVersionRecord) && vrp->type == HDR_Version) vRec = 1; else if (vrp->size == sizeof(ClVersionRecord) << 24 && vrp->type == HDR_Version) { mlogf(M_ERROR, M_SHOW, "--- %s is in wrong endian format\n", fin); fclose(in); return NULL; } } if (vRec == 0 && hdr.type != HDR_Class) { mlogf(M_ERROR, M_SHOW, "--- %s contains non-class record(s)\n", fin); fclose(in); return NULL; } buf = (char *) malloc(hdr.size); if (buf == NULL) { mlogf(M_ERROR, M_SHOW, "--- %s contains record(s) that are too long\n", fin); fclose(in); return NULL; } s = hdr.size; *((ClObjectHdr *) buf) = hdr; if (fread(buf + sizeof(hdr), 1, hdr.size - sizeof(hdr), in) == hdr.size - sizeof(hdr)) { if (vRec) { cr->vr = (ClVersionRecord *) buf; vrp = NEW(ClVersionRecord); memcpy(vrp, cr->vr, sizeof(ClVersionRecord)); if (strcmp(cr->vr->id, "sfcb-rep")) { mlogf(M_ERROR, M_SHOW, "--- %s contains invalid version record - directory skipped\n", fin); fclose(in); free(cr); free(buf); free(vrp); return NULL; } vRec = 0; } else { vrp = NULL; } if (first) { int v = -1; first = 0; if (ClVerifyObjImplLevel(vrp)) continue; if (vrp) v = vrp->objImplLevel; mlogf(M_ERROR, M_SHOW, "--- %s contains unsupported object implementation format (%d) - directory skipped\n", fin, v); fclose(in); free(cr); free(buf); if (vrp) { free(vrp); } return NULL; } cc = NEW(CMPIConstClass); cc->hdl = buf; cc->ft = CMPIConstClassFT; cc->ft->relocate(cc); cn = (char *) cc->ft->getCharClassName(cc); if (strncmp(cn, "DMY_", 4) != 0) { total += s; cb->ht->ft->put(cb->ht, cn, cc); if (cc->ft->isAssociation(cc)) { cr->assocs++; if (cc->ft->getCharSuperClassName(cc) == NULL) cr->topAssocs++; } } } else { mlogf(M_ERROR, M_SHOW, "--- %s contains invalid record(s) - directory skipped\n", fin); fclose(in); free(cr); free(buf); return NULL; } } fclose(in); if (cr->vr) { mlogf(M_INFO, M_SHOW, "--- ClassProvider for %s (%d.%d) using %ld bytes\n", fname, cr->vr->version, cr->vr->level, total); } else mlogf(M_INFO, M_SHOW, "--- ClassProvider for %s (no-version) using %ld bytes\n", fname, total); buildClassSource(cr, ns); return cr; }
int ipfix_export_drecord_db( ipfixs_node_t *s, ipfixt_node_t *t, ipfix_datarecord_t *d, void *arg ) { ipfixe_data_db_t *data = (ipfixe_data_db_t*)arg; char *func = "export_drecord_db"; int i, nbytes, binary_f=0; if ( !data->mysql ) return -1; /* write data set into database * todo: log error if query buffer is too small */ snprintf( query, MAXQUERYLEN, "INSERT INTO %s SET %s='%u'", t->tablename, IPFIX_DB_DT_MSGID, s->last_msgid ); nbytes = strlen(query); for ( i=0; i<t->ipfixt->nfields; i++ ) { #ifdef IENAME_COLUMNS nbytes += snprintf( query+nbytes, sizeof(query)-nbytes, ", %s='", t->ipfixt->fields[i].elem->ft->name ); #else nbytes += snprintf( query+nbytes, sizeof(query)-nbytes, ", " IPFIX_DB_COLUMNNAME_FORMAT "='", t->ipfixt->fields[i].elem->ft->eno, t->ipfixt->fields[i].elem->ft->ftype ); #endif if ( nbytes >= sizeof(query) ) goto err; if ( t->ipfixt->fields[i].elem->ft->coding == IPFIX_CODING_BYTES ) { if ( ((d->lens[i]*2)+2) < (sizeof(query)-nbytes) ) { nbytes += mysql_real_escape_string( data->mysql, query+nbytes, d->addrs[i], d->lens[i] ); binary_f++; } } else { nbytes += t->ipfixt->fields[i].elem->snprint( query+nbytes, sizeof(query)-nbytes, d->addrs[i], d->lens[i] ); } if ( (nbytes+1) >= sizeof(query) ) goto err; nbytes += snprintf( query+nbytes, sizeof(query)-nbytes, "'" ); } mlogf( 4, "[%s] query: %s\n", func, query ); if ( mysql_real_query( data->mysql, query, nbytes ) !=0 ) { mlogf( 0, "[%s] mysql_query(%s) failed: %s\n", func, binary_f?"":query, mysql_error(data->mysql) ); return -1; } /** insert template id into mapping table (if not already done) */ if ( t->message_snr != s->last_message_snr ) { snprintf( query, MAXQUERYLEN, "INSERT INTO %s SET %s=%u, %s=%u ", IPFIX_DB_MAPPINGTABLE, IPFIX_DB_MT_MSGID, s->last_msgid, IPFIX_DB_MT_TMPLID, t->template_id ); mlogf( 4, "[%s] query: %s\n", func, query ); if ( mysql_query( data->mysql, query ) !=0 ) { mlogf( 0, "[%s] mysql_query(%s) failed: %s\n", func, query, mysql_error(data->mysql) ); return -1; } /** mark that message uses this template */ t->message_snr = s->last_message_snr; } return 0; err: return -1; }
static ClassRegister * newClassRegister(char *fname) { ClassRegister *cr = (ClassRegister *) calloc(1, sizeof(ClassRegister) + sizeof(ClassBase)); ClassBase *cb = (ClassBase *) (cr + 1); char fin[1024]; long s, total = 0; ClObjectHdr hdr; ClVersionRecord *vrp = (ClVersionRecord *) & hdr; int vRec = 0, first = 1; z_off_t pos = 0; ClassRecord *crec; cr->hdl = cb; cr->ft = ClassRegisterFT; cr->vr = NULL; cr->assocs = cr->topAssocs = 0; strcpy(fin, fname); strcat(fin, "/classSchemas"); cr->f = gzopen(fin, "r"); if (cr->f == NULL) { strcat(fin, ".gz"); cr->f = gzopen(fin, "r"); } cb->ht = UtilFactory->newHashTable(61, UtilHashTable_charKey | UtilHashTable_ignoreKeyCase); cb->it = UtilFactory->newHashTable(61, UtilHashTable_charKey | UtilHashTable_ignoreKeyCase); MRWInit(&cb->mrwLock); if (cr->f == NULL) return cr; cr->fn = strdup(fin); cr->vr = NULL; pos = gztell(cr->f); while ((s = gzread(cr->f, &hdr, sizeof(hdr))) == sizeof(hdr)) { CMPIConstClass *cc = NULL; char *buf = NULL; const char *cn, *pn; if (first) { if (vrp->size == sizeof(ClVersionRecord) && vrp->type == HDR_Version) vRec = 1; else if (vrp->size == sizeof(ClVersionRecord) << 24 && vrp->type == HDR_Version) { mlogf(M_ERROR, M_SHOW, "--- %s is in wrong endian format - directory skipped\n", fin); return NULL; } } if (vRec == 0 && hdr.type != HDR_Class && hdr.type != HDR_IncompleteClass) { mlogf(M_ERROR, M_SHOW, "--- %s contains non-class record(s) - directory skipped %d\n", fin, hdr.type); return NULL; } buf = (char *) malloc(hdr.size); if (buf == NULL) { mlogf(M_ERROR, M_SHOW, "--- %s contains record(s) that are too long - directory skipped\n", fin); return NULL; } s = hdr.size; *((ClObjectHdr *) buf) = hdr; if (gzread(cr->f, buf + sizeof(hdr), hdr.size - sizeof(hdr)) == hdr.size - sizeof(hdr)) { if (vRec) { cr->vr = (ClVersionRecord *) buf; if (strcmp(cr->vr->id, "sfcb-rep")) { mlogf(M_ERROR, M_SHOW, "--- %s contains invalid version record - directory skipped\n", fin); return NULL; } pos = gztell(cr->f); vRec = 0; } if (first) { int v = -1; first = 0; if (ClVerifyObjImplLevel(cr->vr)) continue; if (cr->vr) v = cr->vr->objImplLevel; mlogf(M_ERROR, M_SHOW, "--- %s contains unsupported object implementation format (%d) - directory skipped\n", fin, v); return NULL; } cc = NEW(CMPIConstClass); cc->hdl = buf; cc->ft = CMPIConstClassFT; cc->ft->relocate(cc); cn = (char *) cc->ft->getCharClassName(cc); if (strncmp(cn, "DMY_", 4) != 0) { total += sizeof(ClassRecord); crec = (ClassRecord *) calloc(1, sizeof(ClassRecord)); if ((pn = cc->ft->getCharSuperClassName(cc))) { crec->parent = strdup(pn); } crec->position = pos; crec->length = s; cr->ft->putClass(cr, strdup(cn), crec); if (cc->ft->isAssociation(cc)) { crec->flags |= CREC_isAssociation; cr->assocs++; if (pn == NULL) cr->topAssocs++; } } first = 0; } else { mlogf(M_ERROR, M_SHOW, "--- %s contains invalid record(s) - directory skipped\n", fin); return NULL; } pos = gztell(cr->f); free(buf); free(cc); } if (cr->vr) { mlogf(M_INFO, M_SHOW, "--- Caching ClassProviderSf for %s (%d.%d-%d) using %ld bytes\n", fin, cr->vr->version, cr->vr->level, cr->vr->objImplLevel, total); } else mlogf(M_INFO, M_SHOW, "--- Caching ClassProviderSf for %s (no-version) using %ld bytes\n", fin, total); buildInheritanceTable(cr); return cr; }
static CMPIStatus ClassProviderInvokeMethod(CMPIMethodMI * mi, const CMPIContext *ctx, const CMPIResult *rslt, const CMPIObjectPath * ref, const char *methodName, const CMPIArgs * in, CMPIArgs * out) { CMPIStatus st = { CMPI_RC_OK, NULL }; CMPIArray *ar; int rc; ClassRegister *cReg; _SFCB_ENTER(TRACE_PROVIDERS, "ClassProviderInvokeMethod"); cReg = getNsReg(ref, &rc); if (cReg == NULL) { CMPIStatus st = { CMPI_RC_ERR_INVALID_NAMESPACE, NULL }; _SFCB_RETURN(st); } if (strcasecmp(methodName, "getchildren") == 0) { CMPIData cn = CMGetArg(in, "class", NULL); _SFCB_TRACE(1, ("--- getchildren %s", (char *) cn.value.string->hdl)); cReg->ft->wLock(cReg); if (cn.type == CMPI_string && cn.value.string && cn.value.string->hdl) { char *child; int l = 0, i = 0; UtilList *ul = getChildren(cReg, (char *) cn.value.string->hdl); if (ul) l = ul->ft->size(ul); ar = CMNewArray(_broker, l, CMPI_string, NULL); if (ul) for (child = (char *) ul->ft->getFirst(ul); child; child = (char *) ul->ft->getNext(ul)) { CMSetArrayElementAt(ar, i++, child, CMPI_chars); } st = CMAddArg(out, "children", &ar, CMPI_stringA); } else { } cReg->ft->wUnLock(cReg); } else if (strcasecmp(methodName, "getallchildren") == 0) { int ignprov = 0; CMPIStatus st; CMPIData cn = CMGetArg(in, "class", &st); cReg->ft->wLock(cReg); if (st.rc != CMPI_RC_OK) { cn = CMGetArg(in, "classignoreprov", NULL); ignprov = 1; } _SFCB_TRACE(1, ("--- getallchildren %s", (char *) cn.value.string->hdl)); if (cn.type == CMPI_string && cn.value.string && cn.value.string->hdl) { int n = 0, i = 0; loopOnChildCount(cReg, (char *) cn.value.string->hdl, &n, ignprov); _SFCB_TRACE(1, ("--- count %d", n)); ar = CMNewArray(_broker, n, CMPI_string, NULL); if (n) { _SFCB_TRACE(1, ("--- loop %s", (char *) cn.value.string->hdl)); loopOnChildChars(cReg, (char *) cn.value.string->hdl, ar, &i, ignprov); } st = CMAddArg(out, "children", &ar, CMPI_stringA); } else { } cReg->ft->wUnLock(cReg); } else if (strcasecmp(methodName, "getassocs") == 0) { ar = CMNewArray(_broker, cReg->topAssocs, CMPI_string, NULL); ClassBase *cb = (ClassBase *) (cReg + 1); UtilHashTable *ct = cb->ht; HashTableIterator *i; char *cn; ClassRecord *crec; int n; cReg->ft->wLock(cReg); for (n = 0, i = ct->ft->getFirst(ct, (void **) &cn, (void **) &crec); i; i = ct->ft->getNext(ct, i, (void **) &cn, (void **) &crec)) { if (crec->flags & CREC_isAssociation && crec->parent == NULL) { /* * add top-level association class */ CMSetArrayElementAt(ar, n++, cn, CMPI_chars); } } CMAddArg(out, "assocs", &ar, CMPI_stringA); cReg->ft->wUnLock(cReg); } else if (strcasecmp(methodName, "ischild") == 0) { char *parent = (char *) CMGetClassName(ref, NULL)->hdl; char *chldn = (char *) CMGetArg(in, "child", NULL).value.string->hdl; st.rc = traverseChildren(cReg, parent, chldn); } else if (strcasecmp(methodName, "_startup") == 0) { /* let providerMgr know that we're odne init'ing */ semRelease(sfcbSem,INIT_CLASS_PROV_ID); st.rc = CMPI_RC_OK; } else { mlogf(M_ERROR, M_SHOW, "--- ClassProvider: Invalid invokeMethod request %s\n", methodName); st.rc = CMPI_RC_ERR_METHOD_NOT_FOUND; } _SFCB_RETURN(st); }
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); }