static void dumpDesc(__pmContext *ctxp) { int i; int sts; char **names; __pmHashNode *hp; pmDesc *dp; printf("\nDescriptions for Metrics in the Log ...\n"); for (i = 0; i < ctxp->c_archctl->ac_log->l_hashpmid.hsize; i++) { for (hp = ctxp->c_archctl->ac_log->l_hashpmid.hash[i]; hp != NULL; hp = hp->next) { dp = (pmDesc *)hp->data; sts = pmNameAll(dp->pmid, &names); if (sts < 0) printf("PMID: %s (%s)\n", pmIDStr(dp->pmid), "<noname>"); else { printf("PMID: %s (", pmIDStr(dp->pmid)); __pmPrintMetricNames(stdout, sts, names, " or "); printf(")\n"); free(names); } __pmPrintDesc(stdout, dp); } } }
static void print_metric(FILE *f, pmID pmid) { int numnames; char **names; if ((numnames = pmNameAll(pmid, &names)) < 1) fprintf(f, "%s", pmIDStr(pmid)); else { __pmPrintMetricNames(f, numnames, names, " or "); free(names); } }
void _dbDumpResult(FILE *f, pmResult *resp, pmDesc *desc_list) { int i; int j; int n; char **names; fprintf(f, "pmResult dump from " PRINTF_P_PFX "%p timestamp: %d.%06d ", resp, (int)resp->timestamp.tv_sec, (int)resp->timestamp.tv_usec); pmPrintStamp(f, &resp->timestamp); fprintf(f, " numpmid: %d\n", resp->numpmid); for (i = 0; i < resp->numpmid; i++) { pmValueSet *vsp = resp->vset[i]; names = NULL; /* silence coverity */ n = pmNameAll(vsp->pmid, &names); if (n < 0) fprintf(f, " %s (%s):", pmIDStr(vsp->pmid), "<noname>"); else { fprintf(f, " %s (", pmIDStr(vsp->pmid)); __pmPrintMetricNames(f, n, names, " or "); fprintf(f, "):"); free(names); } if (vsp->numval == 0) { fprintf(f, " No values returned!\n"); continue; } else if (vsp->numval < 0) { fprintf(f, " %s\n", pmErrStr(vsp->numval)); continue; } fprintf(f, " numval: %d", vsp->numval); fprintf(f, " valfmt: %d vlist[]:\n", vsp->valfmt); for (j = 0; j < vsp->numval; j++) { pmValue *vp = &vsp->vlist[j]; if (vsp->numval > 1 || desc_list[i].indom != PM_INDOM_NULL) { fprintf(f, " inst [%d", vp->inst); fprintf(f, " or ???]"); fputc(' ', f); } else fprintf(f, " "); fprintf(f, "value "); pmPrintValue(f, vsp->valfmt, desc_list[i].type, vp, 1); fputc('\n', f); }/*for*/ }/*for*/ }/*_dbDumpResult*/
static void dump_parameter(pmValueSet *xvsp, int index, int *flagsp) { int sts, flags = *flagsp; pmDesc desc; char **names; if ((sts = pmNameAll(xvsp->pmid, &names)) >= 0) { if (index == 0) { if (xvsp->pmid == pmid_flags) { flags = *flagsp = xvsp->vlist[0].value.lval; printf(" flags 0x%x", flags); printf(" (%s) ---\n", pmEventFlagsStr(flags)); free(names); return; } printf(" ---\n"); } if ((flags & PM_EVENT_FLAG_MISSED) && index == 1 && (xvsp->pmid == pmid_missed)) { printf(" ==> %d missed event records\n", xvsp->vlist[0].value.lval); free(names); return; } printf(" %s (", pmIDStr(xvsp->pmid)); __pmPrintMetricNames(stdout, sts, names, " or "); printf("):"); free(names); } else printf(" PMID: %s:", pmIDStr(xvsp->pmid)); if ((sts = pmLookupDesc(xvsp->pmid, &desc)) < 0) { printf(" pmLookupDesc: %s\n", pmErrStr(sts)); return; } printf(" value "); pmPrintValue(stdout, xvsp->valfmt, desc.type, &xvsp->vlist[0], 1); putchar('\n'); }
static void dump_result(pmResult *resp) { int i; int j; int n; char **names; pmDesc desc; if (sflag) { int nbyte; nbyte = do_size(resp); printf("[%d bytes]\n", nbyte); } if (xflag) { char *ddmm; char *yr; ddmm = pmCtime(&resp->timestamp.tv_sec, timebuf); ddmm[10] = '\0'; yr = &ddmm[20]; printf("%s ", ddmm); __pmPrintStamp(stdout, &resp->timestamp); printf(" %4.4s", yr); if (xflag >= 2) printf(" (%.6f)", __pmtimevalSub(&resp->timestamp, &label.ll_start)); } else __pmPrintStamp(stdout, &resp->timestamp); if (resp->numpmid == 0) { printf(" <mark>\n"); return; } for (i = 0; i < resp->numpmid; i++) { pmValueSet *vsp = resp->vset[i]; if (i > 0) printf(" "); n = pmNameAll(vsp->pmid, &names); if (vsp->numval == 0) { printf(" %s (", pmIDStr(vsp->pmid)); __pmPrintMetricNames(stdout, n, names, " or "); printf("): No values returned!\n"); goto next; } else if (vsp->numval < 0) { printf(" %s (", pmIDStr(vsp->pmid)); __pmPrintMetricNames(stdout, n, names, " or "); printf("): %s\n", pmErrStr(vsp->numval)); goto next; } if (pmLookupDesc(vsp->pmid, &desc) < 0) { /* don't know, so punt on the most common cases */ desc.indom = PM_INDOM_NULL; if (vsp->valfmt == PM_VAL_INSITU) desc.type = PM_TYPE_32; else desc.type = PM_TYPE_AGGREGATE; } for (j = 0; j < vsp->numval; j++) { if (desc.type == PM_TYPE_EVENT || desc.type == PM_TYPE_HIGHRES_EVENT) dump_event(n, names, vsp, j, desc.indom, desc.type); else dump_metric(n, names, vsp, j, desc.indom, desc.type); } next: if (n > 0) free(names); } }
static void foo(FILE *f, char *fn, int i, void *closure) { int sts; int numnames; int j; int leaf; pmID pmids[NMETRIC]; char **names; char *name; int *stsset; char strbuf[20]; if ((sts = pmLookupName(NMETRIC-i, &namelist[i], pmids)) < 0) { if (sts != PM_ERR_NONLEAF) { fprintf(f, "%s: %s ...: pmLookupName Error: %s\n", fn, namelist[i], pmErrStr(sts)); pthread_exit("botch"); } } for (j = i; j < NMETRIC; j++) { if (pmids[j-i] != pmidlist[j]) { fprintf(f, "%s: %s: Botch: expecting %s", fn, namelist[j], pmIDStr_r(pmidlist[j], strbuf, sizeof(strbuf))); fprintf(f, ", got %s\n", pmIDStr_r(pmids[j-i], strbuf, sizeof(strbuf))); pthread_exit("botch"); } } fprintf(f, "%s: %s ... pmLookupName OK\n", fn, namelist[i]); fprintf(f, "%s: %s", fn, namelist[i]); if (pmidlist[i] != PM_ID_NULL) { /* leaf node in PMNS */ if ((numnames = pmNameAll(pmidlist[i], &names)) < 0) { fprintf(f, "\n%s: %s ...: pmNameAll Error: %s\n", fn, namelist[i], pmErrStr(numnames)); pthread_exit("botch"); } for (j = 0; j < numnames; j++) { if (strcmp(names[j], namelist[i]) == 0) break; } if (j == numnames) { fprintf(f, "\n%s: %s: Botch: expecting %s, got {", fn, pmIDStr_r(pmidlist[i], strbuf, sizeof(strbuf)), namelist[i]); __pmPrintMetricNames(f, numnames, names, ","); fprintf(f, "}\n"); pthread_exit("botch"); } fprintf(f, " pmNameAll OK"); if ((sts = pmNameID(pmidlist[i], &name)) < 0) { fprintf(f, "\n%s: %s ...: pmNameID Error: %s\n", fn, namelist[i], pmErrStr(sts)); pthread_exit("botch"); } for (j = 0; j < numnames; j++) { if (strcmp(name, names[j]) == 0) break; } if (j == numnames) { fprintf(f, "\n%s: %s: Botch: expecting one of {", fn, pmIDStr_r(pmidlist[i], strbuf, sizeof(strbuf))); __pmPrintMetricNames(f, numnames, names, ","); fprintf(f, "}, got %s\n", name); pthread_exit("botch"); } free(names); free(name); fprintf(f, " pmNameID OK"); } else { /* non-leaf node in PMNS */ int keep = 0; if ((sts = pmGetChildrenStatus(namelist[i], &names, &stsset)) < 0) { fprintf(f, "\n%s: %s ...: pmGetChildrenStatus Error: %s\n", fn, namelist[i], pmErrStr(sts)); pthread_exit("botch"); } leaf = 0; for (j = 0; j < sts; j++) { if (stsset[j] == PMNS_LEAF_STATUS) leaf++; } PM_LOCK(chn_lock); if (leaf_chn[i] == -1) { leaf_chn[i] = leaf; nonleaf_chn[i] = sts - leaf; chn[i] = names; keep = 1; } else { if (leaf != leaf_chn[i] || sts - leaf != nonleaf_chn[i]) { fprintf(f, "\n%s: %s: Botch: expecting %d leaf & %d non-leaf, got %d leaf & %d non-leaf\n", fn, namelist[i], leaf_chn[i], nonleaf_chn[i], leaf, sts - leaf); pthread_exit("botch"); } for (j = 0; j < sts; j++) { if (strcmp(chn[i][j], names[j]) != 0) { fprintf(f, "\n%s: %s: Botch: child[%d] expecting %s, got %s\n", fn, namelist[i], j, chn[i][j], names[j]); PM_UNLOCK(chn_lock); pthread_exit("botch"); } } } if (keep == 0) { free(names); names = NULL; /* silence coverity */ } free(stsset); fprintf(f, " pmGetChildrenStatus OK"); if ((sts = pmGetChildren(namelist[i], &names)) < 0) { fprintf(f, "\n%s: %s ...: pmGetChildren Error: %s\n", fn, namelist[i], pmErrStr(sts)); PM_UNLOCK(chn_lock); pthread_exit("botch"); } if (sts != leaf_chn[i] + nonleaf_chn[i]) { fprintf(f, "\n%s: %s: Botch: expecting %d children, got %d\n", fn, namelist[i], leaf_chn[i] + nonleaf_chn[i], sts); PM_UNLOCK(chn_lock); pthread_exit("botch"); } for (j = 0; j < sts; j++) { if (strcmp(chn[i][j], names[j]) != 0) { fprintf(f, "\n%s: %s: Botch: child[%d] expecting %s, got %s\n", fn, namelist[i], j, chn[i][j], names[j]); PM_UNLOCK(chn_lock); pthread_exit("botch"); } } PM_UNLOCK(chn_lock); free(names); fprintf(f, " pmGetChildren OK"); *((int *)closure) = 0; if ((sts = pmTraversePMNS_r(namelist[i], dometric, closure)) < 0) { fprintf(f, "\n%s: %s ...: pmTraversePMNS_r Error: %s\n", fn, namelist[i], pmErrStr(sts)); pthread_exit("botch"); } if (sum_traverse[i] != *((int *)closure)) { fprintf(f, "\n%s: %s: Botch: sum strlen(descendent names) expecting %d, got %d\n", fn, namelist[i], sum_traverse[i], *((int *)closure)); pthread_exit("botch"); } fprintf(f, " pmTraversePMNS_r OK"); } fputc('\n', f); }
static int do_control(__pmPDU *pb) { int sts; int control; int state; int delta; pmResult *request; pmResult *result; int siamised = 0; /* the verb from siamese (as in twins) */ int i; int j; int val; pmValueSet *vsp; optreq_t *rqp; task_t *tp; time_t now; int reqstate = 0; /* * TODO - encoding for logging interval in requests and results? */ if ((sts = __pmDecodeLogControl(pb, &request, &control, &state, &delta)) < 0) return sts; #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_LOG) { fprintf(stderr, "do_control: control=%d state=%d delta=%d request ...\n", control, state, delta); dumpcontrol(stderr, request, 0); } #endif if (control == PM_LOG_MANDATORY || control == PM_LOG_ADVISORY) { time(&now); fprintf(stderr, "\n%s", ctime(&now)); fprintf(stderr, "pmlc request from %s: %s", pmlc_host, control == PM_LOG_MANDATORY ? "mandatory" : "advisory"); if (state == PM_LOG_ON) { if (delta == 0) fprintf(stderr, " on once\n"); else fprintf(stderr, " on %.1f sec\n", (float)delta/1000); } else if (state == PM_LOG_OFF) fprintf(stderr, " off\n"); else fprintf(stderr, " maybe\n"); } /* * access control checks */ sts = 0; switch (control) { case PM_LOG_MANDATORY: if (denyops & PM_OP_LOG_MAND) sts = PM_ERR_PERMISSION; break; case PM_LOG_ADVISORY: if (denyops & PM_OP_LOG_ADV) sts = PM_ERR_PERMISSION; break; case PM_LOG_ENQUIRE: /* * Don't need to check [access] as you have to have _some_ * permission (at least one of PM_OP_LOG_ADV or PM_OP_LOG_MAND * and PM_OP_LOG_ENQ) to make a connection ... and if you * have either PM_OP_LOG_ADV or PM_OP_LOG_MAND it makes no * sense to deny PM_OP_LOG_ENQ operations. */ break; default: fprintf(stderr, "Bad control PDU type %d\n", control); sts = PM_ERR_IPC; break; } if (sts < 0) { fprintf(stderr, "Error: %s\n", pmErrStr(sts)); if ((sts = __pmSendError(clientfd, FROM_ANON, sts)) < 0) __pmNotifyErr(LOG_ERR, "do_control: error sending Error PDU to client: %s\n", pmErrStr(sts)); pmFreeResult(request); return sts; } /* handle everything except PM_LOG_ENQUIRE */ if (control == PM_LOG_MANDATORY || control == PM_LOG_ADVISORY) { /* update the logging status of metrics */ task_t *newtp = NULL; /* task for metrics/insts in request */ struct timeval tdelta = { 0 }; int newtask; int mflags; /* convert state and control to the bitmask used in pmlogger and values * returned in results. Remember that reqstate starts with nothing on. */ if (state == PM_LOG_ON) PMLC_SET_ON(reqstate, 1); else PMLC_SET_ON(reqstate, 0); if (control == PM_LOG_MANDATORY) { if (state == PM_LOG_MAYBE) /* mandatory+maybe => maybe+advisory+off */ PMLC_SET_MAYBE(reqstate, 1); else PMLC_SET_MAND(reqstate, 1); } /* try to find an existing task for the request * Never return a "once only" task, it may have gone off already and just * be hanging around like a bad smell. */ if (delta != 0) { tdelta.tv_sec = delta / 1000; tdelta.tv_usec = (delta % 1000) * 1000; newtp = find_task(reqstate, &tdelta); } newtask = (newtp == NULL); for (i = 0; i < request->numpmid; i++) { vsp = request->vset[i]; if (vsp->numval < 0) /* * request is malformed, as we cannot control logging * for an undefined instance ... there is no way to * return an error from here, so simply ignore this * metric */ continue; mflags = find_metric(vsp->pmid); if (mflags < 0) { /* only add new metrics if they are ON or MANDATORY OFF * Careful: mandatory+maybe is mandatory+maybe+off */ if (PMLC_GET_ON(reqstate) || (PMLC_GET_MAND(reqstate) && !PMLC_GET_MAYBE(reqstate))) add_metric(vsp, &newtp); } else /* already a specification for this metric */ update_metric(vsp, reqstate, mflags, &newtp); } /* schedule new logging task if new metric(s) specified */ if (newtask && newtp != NULL) { if (newtp->t_fetch == NULL) { /* the new task ended up with no fetch groups, throw it away */ if (newtp->t_pmidlist != NULL) free(newtp->t_pmidlist); free(newtp); } else { /* link new task into tasklist */ newtp->t_next = tasklist; tasklist = newtp; /* use only the MAND/ADV and ON/OFF bits of reqstate */ newtp->t_state = PMLC_GET_STATE(reqstate); if (PMLC_GET_ON(reqstate)) { newtp->t_delta = tdelta; newtp->t_afid = __pmAFregister(&tdelta, (void *)newtp, log_callback); } else newtp->t_delta.tv_sec = newtp->t_delta.tv_usec = 0; linkback(newtp); } } } #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) dumpit(); #endif /* just ignore advisory+maybe---the returned pmResult will have the metrics * in their original state indicating that the request could not be * satisfied. */ result = request; result->timestamp.tv_sec = result->timestamp.tv_usec = 0; /* for purify */ /* write the current state of affairs into the result _pmResult */ for (i = 0; i < request->numpmid; i++) { if (control == PM_LOG_MANDATORY || control == PM_LOG_ADVISORY) { char **names; sts = pmNameAll(request->vset[i]->pmid, &names); if (sts < 0) fprintf(stderr, " metric: %s", pmIDStr(request->vset[i]->pmid)); else { fprintf(stderr, " metric: "); __pmPrintMetricNames(stderr, sts, names, " or "); free(names); } } if (request->vset[i]->numval <= 0 && !siamised) { result = siamise_request(request); siamised = 1; } /* * pmids with numval <= 0 in the request have a null vset ptr in the * in the corresponding place in the siamised result. */ if (result->vset[i] != NULL) vsp = result->vset[i]; else { /* the result should also contain the history for an all instances * enquire request. Control requests just get the current indom * since the user of pmlc really wants to see what's being logged * now rather than in the past. */ vsp = build_vset(request->vset[i]->pmid, control == PM_LOG_ENQUIRE); result->vset[i] = vsp; } vsp->valfmt = PM_VAL_INSITU; for (j = 0; j < vsp->numval; j++) { rqp = findoptreq(vsp->pmid, vsp->vlist[j].inst); val = 0; if (rqp == NULL) { PMLC_SET_STATE(val, 0); PMLC_SET_DELTA(val, 0); } else { tp = rqp->r_fetch->f_aux; PMLC_SET_STATE(val, tp->t_state); PMLC_SET_DELTA(val, (tp->t_delta.tv_sec*1000 + tp->t_delta.tv_usec/1000)); } val |= gethistflags(vsp->pmid, vsp->vlist[j].inst); vsp->vlist[j].value.lval = val; if (control == PM_LOG_MANDATORY || control == PM_LOG_ADVISORY) { int expstate = 0; int statemask = 0; int expdelta; if (rqp != NULL && rqp->r_desc->indom != PM_INDOM_NULL) { char *p; if (j == 0) fputc('\n', stderr); if (pmNameInDom(rqp->r_desc->indom, vsp->vlist[j].inst, &p) >= 0) { fprintf(stderr, " instance: %s", p); free(p); } else fprintf(stderr, " instance: #%d", vsp->vlist[j].inst); } else { /* no pmDesc ... punt */ if (vsp->numval > 1 || vsp->vlist[j].inst != PM_IN_NULL) { if (j == 0) fputc('\n', stderr); fprintf(stderr, " instance: #%d", vsp->vlist[j].inst); } } if (state != PM_LOG_MAYBE) { if (control == PM_LOG_MANDATORY) PMLC_SET_MAND(expstate, 1); else PMLC_SET_MAND(expstate, 0); if (state == PM_LOG_ON) PMLC_SET_ON(expstate, 1); else PMLC_SET_ON(expstate, 0); PMLC_SET_MAND(statemask, 1); PMLC_SET_ON(statemask, 1); } else { PMLC_SET_MAND(expstate, 0); PMLC_SET_MAND(statemask, 1); } expdelta = PMLC_GET_ON(expstate) ? delta : 0; if ((PMLC_GET_STATE(val) & statemask) != expstate || PMLC_GET_DELTA(val) != expdelta) fprintf(stderr, " [request failed]"); fputc('\n', stderr); } } } #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_LOG) { __pmDumpResult(stderr, result); } #endif if ((sts = __pmSendResult(clientfd, FROM_ANON, result)) < 0) __pmNotifyErr(LOG_ERR, "do_control: error sending Error PDU to client: %s\n", pmErrStr(sts)); if (siamised) { for (i = 0; i < request->numpmid; i++) if (request->vset[i]->numval <= 0) free(result->vset[i]); free(result); } pmFreeResult(request); return 0; }
/* * Handle event records. * * Walk the packed array of events using similar logic to * pmUnpackEventRecords() but we don't need any allocations. * * For each embedded event parameter, make sure the metadata for * the associated metric is added to the archive. */ int do_events(pmValueSet *vsp) { pmEventArray *eap; char *base; pmEventRecord *erp; pmEventParameter *epp; int r; /* records */ int p; /* parameters in a record ... */ int i; /* instances ... */ int sts; pmDesc desc; for (i = 0; i < vsp->numval; i++) { if ((sts = __pmCheckEventRecords(vsp, i)) < 0) { __pmDumpEventRecords(stderr, vsp, i); return sts; } eap = (pmEventArray *)vsp->vlist[i].value.pval; if (eap->ea_nrecords == 0) return 0; base = (char *)&eap->ea_record[0]; for (r = 0; r < eap->ea_nrecords; r++) { erp = (pmEventRecord *)base; base += sizeof(erp->er_timestamp) + sizeof(erp->er_flags) + sizeof(erp->er_nparams); if (erp->er_flags & PM_EVENT_FLAG_MISSED) { /* * no event "parameters" here, just a missed records count * in er_nparams */ continue; } for (p = 0; p < erp->er_nparams; p++) { epp = (pmEventParameter *)base; base += sizeof(epp->ep_pmid) + PM_PDU_SIZE_BYTES(epp->ep_len); sts = __pmLogLookupDesc(&logctl, epp->ep_pmid, &desc); if (sts < 0) { int numnames; char **names; numnames = pmNameAll(epp->ep_pmid, &names); if (numnames < 0) { /* * Event parameter metric not defined in the PMNS. * This should not happen, but is probably not fatal, so * issue a warning and make up a name based on the pmid * event_param.<domain>.<cluster>.<item> */ char *name; size_t name_size = strlen("event_param")+3+1+4+1+4+1; names = (char **)malloc(sizeof(char*) + name_size); if (names == NULL) return -oserror(); name = (char *)&names[1]; names[0] = name; snprintf(name, name_size, "event_param.%s", pmIDStr(epp->ep_pmid)); fprintf(stderr, "Warning: metric %s has no name, using %s\n", pmIDStr(epp->ep_pmid), name); } sts = pmLookupDesc(epp->ep_pmid, &desc); if (sts < 0) { /* Event parameter metric does not have a pmDesc. * This should not happen, but is probably not entirely * fatal (although more serious than not having a metric * name), issue a warning and construct a minimalist * pmDesc */ desc.pmid = epp->ep_pmid; desc.type = PM_TYPE_AGGREGATE; desc.indom = PM_INDOM_NULL; desc.sem = PM_SEM_DISCRETE; memset(&desc.units, '\0', sizeof(desc.units)); fprintf(stderr, "Warning: metric %s (%s) has no descriptor, using a default one\n", names[0], pmIDStr(epp->ep_pmid)); } if ((sts = __pmLogPutDesc(&logctl, &desc, numnames, names)) < 0) { fprintf(stderr, "__pmLogPutDesc: %s\n", pmErrStr(sts)); exit(1); } free(names); } } } } return 0; }
int main(int argc, char **argv) { int sts; int c; int help = 0; int oneline = 0; char *pmnsfile = PM_NS_DEFAULT; int errflag = 0; int aflag = 0; int eflag = 0; int allpmid = 0; int allindom = 0; char *filename; char *tp; char *name; int id; int next_type; char *endnum; __pmSetProgname(argv[0]); while ((c = getopt(argc, argv, "D:eHin:Opv:?")) != EOF) { switch (c) { case 'D': /* debug flag */ sts = __pmParseDebug(optarg); if (sts < 0) { fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n", pmProgname, optarg); errflag++; } else pmDebug |= sts; break; case 'e': /* help text exists? */ eflag = 1; break; case 'H': /* help text */ help = 1; break; case 'i': aflag++; allindom = 1; break; case 'n': /* alternative namespace file */ pmnsfile = optarg; break; case 'O': /* oneline text */ oneline = 1; break; case 'p': aflag++; allpmid = 1; break; case 'v': /* version 2 only these days */ version = (int)strtol(optarg, &endnum, 10); if (*endnum != '\0') { fprintf(stderr, "%s: -v requires numeric argument\n", pmProgname); errflag++; } if (version != 2) { fprintf(stderr ,"%s: deprecated option - only version 2 is supported\n" , pmProgname); errflag++; } break; case '?': default: errflag++; break; } } if (optind == argc) { fprintf(stderr, "%s: missing helpfile argument\n\n", pmProgname); errflag = 1; } if (aflag && optind < argc-1) { fprintf(stderr, "%s: metricname arguments cannot be used with -i or -p\n\n", pmProgname); errflag = 1; } if (aflag == 0 && optind == argc-1 && oneline+help != 0) { fprintf(stderr, "%s: -O or -H require metricname arguments or -i or -p\n\n", pmProgname); errflag = 1; } if (eflag && (allpmid || allindom)) { fprintf(stderr, "%s: -e cannot be used with -i or -p\n\n", pmProgname); errflag = 1; } if (errflag || optind >= argc) { fprintf(stderr, "Usage: %s helpfile\n" " %s [options] helpfile [metricname ...]\n" "\n" "Options:\n" " -e exists check, only report metrics with no help text\n" " -H display verbose help text\n" " -i process all the instance domains\n" " -n pmnsfile use an alternative PMNS\n" " -O display the one line help summary\n" " -p process all the metrics (PMIDs)\n" " -v version deprecated (only version 2 format supported)\n" "\n" "No options implies silently check internal integrity of the helpfile.\n", pmProgname, pmProgname); exit(1); } filename = argv[optind++]; if ((handle = pmdaOpenHelp(filename)) < 0) { fprintf(stderr, "pmdaOpenHelp: failed to open \"%s\": ", filename); if (handle == -EINVAL) fprintf(stderr, "Bad format, not version %d PCP help text\n", version); else fprintf(stderr, "%s\n", pmErrStr(handle)); exit(1); } if ((sts = pmLoadASCIINameSpace(pmnsfile, 1)) < 0) { fprintf(stderr, "pmLoadASCIINameSpace(%s, 1): %s\n", pmnsfile, pmErrStr(sts)); exit(1); } if (help + oneline == 0 && (optind < argc || aflag)) /* if metric names, -p or -i => -O is default */ oneline = 1; if (optind == argc && aflag == 0) /* no metric names, process all entries */ aflag = 1; if (eflag) { if (optind == argc) { sts = pmTraversePMNS("", dometric); if (sts < 0) { fprintf(stderr, "Error: pmTraversePMNS(\"\", ...): %s\n", pmErrStr(sts)); } } else { for ( ; optind < argc; optind++) { sts = pmTraversePMNS(argv[optind], dometric); if (sts < 0) fprintf(stderr, "Error: pmTraversePMNS(\"%s\", ...): %s\n", argv[optind], pmErrStr(sts)); } } exit(0); } while (optind < argc || aflag) { if (aflag) { if (next(&id, &next_type) == 0) break; #ifdef PCP_DEBUG if ((pmDebug & DBG_TRACE_APPL0) && allindom+allpmid == 0) fprintf(stderr, "next_type=%d id=0x%x\n", next_type, id); #endif if (next_type == 2) { if (!allindom) continue; printf("\nInDom %s:", pmInDomStr((pmInDom)id)); } else { char **names; if (!allpmid) continue; printf("\nPMID %s", pmIDStr((pmID)id)); sts = pmNameAll(id, &names); if (sts > 0) { printf(" "); __pmPrintMetricNames(stdout, sts, names, " or "); free(names); } putchar(':'); } } else { next_type = 1; name = argv[optind++]; if ((sts = pmLookupName(1, &name, (pmID *)&id)) < 0) { printf("\n%s: %s\n", name, pmErrStr(sts)); continue; } if (id == PM_ID_NULL) { printf("\n%s: unknown metric\n", name); continue; } printf("\nPMID %s %s:", pmIDStr((pmID)id), name); } if (oneline) { if (next_type == 1) tp = pmdaGetHelp(handle, (pmID)id, PM_TEXT_ONELINE); else tp = pmdaGetInDomHelp(handle, (pmInDom)id, PM_TEXT_ONELINE); if (tp != NULL) printf(" %s", tp); putchar('\n'); } if (help) { if (next_type == 1) tp = pmdaGetHelp(handle, (pmID)id, PM_TEXT_HELP); else tp = pmdaGetInDomHelp(handle, (pmInDom)id, PM_TEXT_HELP); if (tp != NULL && *tp) printf("%s\n", tp); } } return 0; }