/** Clean up resources allocated by the channel map sub-system. */ void dnxChanMapRelease(void) { if (dnxInit) { int i; DNX_PT_MUTEX_LOCK(&chanMutex); for (i = 0; i < DNX_MAX_CHAN_MAP; i++) { xfree(gChannelMap[i].name); xfree(gChannelMap[i].url); } memset(gChannelMap, 0, sizeof gChannelMap); DNX_PT_MUTEX_UNLOCK(&chanMutex); DNX_PT_MUTEX_DESTROY(&chanMutex); // de-initialize transport module table i = elemcount(gTMList); while (i--) gTMList[i].txExit(); dnxInit = 0; } }
/** Initialize the channel map sub-system. * * @param[in] fileName - a persistent storage file for the channel map. * Not currently used. * * @return Zero on success, or a non-zero error value. */ int dnxChanMapInit(char * fileName) { int i; assert(!dnxInit); memset(gChannelMap, 0, sizeof gChannelMap); DNX_PT_MUTEX_INIT(&chanMutex); // initialize transport module table for (i = 0; i < elemcount(gTMList); i++) { int ret; if ((ret = gTMList[i].txInit(&gTMList[i].txAlloc)) != DNX_OK) { while (i--) gTMList[i].txExit(); DNX_PT_MUTEX_DESTROY(&chanMutex); return ret; } } /** @todo Load global channel map from file, if specified. */ dnxInit = 1; return DNX_OK; }
/** Set a channel map's transport object allocator in a based on URL scheme. * * @param[in] chanMap - the channel map on which to set the allocator. * @param[in] url - the URL to be parsed. * * @return Zero on success, or a non-zero error value. */ static int dnxChanMapUrlParse(DnxChanMap * chanMap, char * url) { char * ep; int i; assert(chanMap && url && strlen(url) <= DNX_MAX_URL); // locate end of scheme if ((ep = strstr(url, "://")) == 0) return DNX_ERR_BADURL; // set allocator for this transport based on the scheme string for (i = 0; i < elemcount(gTMList); i++) if (!strncmp(url, gTMList[i].scheme, ep - url)) { chanMap->txAlloc = gTMList[i].txAlloc; break; } return i < elemcount(gTMList) ? DNX_OK : DNX_ERR_BADURL; }
/** Return an allocated stats buffer for a given active node. * * The results are built in @p data->rsp; * * @param[in] node - the node in this iteration. * @param[in] data - the MgmtNodeStatsData structure. * * @return zero on success, non-zero on error. */ static int dnxBuildNodeStatsReply(DnxNodeData * node, void * data) { MgmtNodeStatsData * msd = (MgmtNodeStatsData *)data; char * req = msd->stats; char * rsp = 0; struct { char * str; unsigned * stat; } rs[] = { { "requests_received", &node->stats[REQUESTS_RECEIVED] }, { "requests_expired", &node->stats[REQUESTS_EXPIRED] }, { "dispatches_ok", &node->stats[DISPATCHES_OK] }, { "dispatches_failed", &node->stats[DISPATCHES_FAILED] }, { "results_ok", &node->stats[RESULTS_OK] }, { "results_failed", &node->stats[RESULTS_FAILED] }, { "results_timed_out", &node->stats[RESULTS_TIMED_OUT] }, }; msd->rsp = 0; // check for inactive node status - return empty if inactive if (node->stats[REQUESTS_RECEIVED] == 0) return DNX_OK; while (*req) { char * ep, * np; unsigned i; // find start of next string or end if ((np = strchr(req, ',')) == 0) np = req + strlen(req); // trim trailing ws ep = np; while (ep > req && isspace(ep[-1])) ep--; // search table for sub-string, append requested stat to rsp for (i = 0; i < elemcount(rs); i++) if (memcmp(req, rs[i].str, ep - req) == 0) { if (appendString(&rsp, "%u,", *rs[i].stat) != 0) return xfree(rsp), DNX_ERR_MEMORY; break; } // check for unknown stat if (i == elemcount(rs) && appendString(&rsp, "?,") != 0) return xfree(rsp), DNX_ERR_MEMORY; // move to next sub-string or end if (*(req = np)) req++; // trim leading ws while (isspace(*req)) req++; } // remove trailing comma in non-empty response if (rsp) { size_t len = strlen(rsp); if (len && rsp[len - 1] == ',') rsp[len - 1] = 0; } msd->rsp = rsp; return DNX_OK; }
/** Build an allocated response buffer for requested stats values. * * @param[in] req - The requested stats in comma-separated string format. * * @return A pointer to an allocated response buffer, or 0 if out of memory. */ static char * buildMgmtStatsReply(char * req) { char * rsp = 0; int nodes_registered = 0; unsigned stats[STATS_COUNT]; struct { char * str; unsigned * stat; } rs[] = { { "nodes_registered", &nodes_registered }, { "requests_received", &stats[REQUESTS_RECEIVED] }, { "requests_expired", &stats[REQUESTS_EXPIRED] }, { "dispatches_ok", &stats[DISPATCHES_OK] }, { "dispatches_failed", &stats[DISPATCHES_FAILED] }, { "results_ok", &stats[RESULTS_OK] }, { "results_failed", &stats[RESULTS_FAILED] }, { "results_timed_out", &stats[RESULTS_TIMED_OUT] }, { "jobs_handled", &stats[JOBS_HANDLED] }, { "jobs_rejected_no_slots", &stats[JOBS_REJECTED_NO_SLOTS] }, { "jobs_rejected_no_nodes", &stats[JOBS_REJECTED_NO_NODES] }, { "post_results_ok", &stats[POST_RESULTS_OK] }, { "post_results_failed", &stats[POST_RESULTS_FAILED] }, }; assert(req); // count number of registered nodes dnxStatsForEachNode(dnxCountNodes, &nodes_registered); // get a copy of the server stats dnxStatsGetServerStats(stats); // trim leading ws while (isspace(*req)) req++; while (*req) { char * ep, * np; unsigned i; // find start of next string or end if ((np = strchr(req, ',')) == 0) np = req + strlen(req); // trim trailing ws ep = np; while (ep > req && isspace(ep[-1])) ep--; // search table for sub-string, append requested stat to rsp for (i = 0; i < elemcount(rs); i++) if (memcmp(req, rs[i].str, ep - req) == 0) { if (appendString(&rsp, "%u,", *rs[i].stat) != 0) return xfree(rsp), (char *)0; break; } // check for unknown stat if (i == elemcount(rs) && appendString(&rsp, "?,") != 0) return xfree(rsp), (char *)0; // move to next sub-string or end if (*(req = np)) req++; // trim leading ws while (isspace(*req)) req++; } // remove trailing comma in non-empty response if (rsp) { size_t len = strlen(rsp); if (len && rsp[len - 1] == ',') rsp[len - 1] = 0; } return rsp; }