/* * Cache all of the most recently requested pmInDom */ static char * lookup(pmInDom indom, int inst) { static pmInDom last = PM_INDOM_NULL; static int numinst = -1; static int *instlist; static char **namelist; int i; if (indom != last) { if (numinst > 0) { free(instlist); free(namelist); } numinst = pmGetInDom(indom, &instlist, &namelist); last = indom; } for (i = 0; i < numinst; i++) { if (instlist[i] == inst) return namelist[i]; } return NULL; }
static void foo(FILE *f, char *fn, int i) { int sts; int j; int numinst; int *inst; char **name; char *tmp; if (desclist[i].indom == PM_INDOM_NULL) { fprintf(f, "%s: %s: singular\n", fn, namelist[i]); return; } if ((sts = pmGetInDom(desclist[i].indom, &inst, &name)) < 0) { fprintf(f, "%s: %s: pmGetInDom Error: %s\n", fn, namelist[i], pmErrStr(sts)); pthread_exit("botch"); } numinst = sts; fprintf(f, "%s: %s: indom contains %d instances: ", fn, namelist[i], numinst); for (j = 0; j < numinst; j++) { if ((sts = pmNameInDom(desclist[i].indom, inst[j], &tmp)) < 0) { fprintf(f, "\n%s: inst %d: pmNameInDom Error: %s\n", fn, inst[j], pmErrStr(sts)); pthread_exit("botch"); } if (strcmp(tmp, name[j]) != 0) { fprintf(f, "\n%s: inst %d: expecting \"%s\", got \"%s\"\n", fn, inst[j], name[j], tmp); pthread_exit("botch"); } fputc('i', f); free(tmp); } fputc(' ', f); for (j = 0; j < numinst; j++) { if ((sts = pmLookupInDom(desclist[i].indom, name[j])) < 0) { fprintf(f, "\n%s: inst \"%s\": pmLookupInDom Error: %s\n", fn, name[j], pmErrStr(sts)); pthread_exit("botch"); } if (sts != inst[j]) { fprintf(f, "\n%s: inst \"%s\": expecting %d, got %d\n", fn, name[j], inst[j], sts); pthread_exit("botch"); } fputc('n', f); } fputc('\n', f); free(inst); free(name); }
void zbx_module_pcp_add_metric(const char *name) { int sts; pmID pmid[1]; pmDesc desc[1]; char *metric; unsigned flags = 0; char *param = NULL; int *instlist; char **namelist; ZBX_METRIC *mptr = metrics; /* PCP preparations. */ sts = pmLookupName(1, (char **)&name, pmid); if (sts < 0) return; sts = pmLookupDesc(pmid[0], desc); if (sts < 0) return; /* Construct the Zabbix metric name. */ metric = (char *)malloc(strlen(ZBX_PCP_METRIC_PREFIX) + strlen(name) + 1); if (metric == NULL) return; strcpy(metric, ZBX_PCP_METRIC_PREFIX); strcat(metric, name); /* Pick a PCP metric instance for use with zabbix_agentd -p. */ if (desc[0].indom != PM_INDOM_NULL) { sts = pmGetInDom(desc[0].indom, &instlist, &namelist); if (sts < 0) { free(metric); return; } if (sts) { flags = CF_HAVEPARAMS; param = strdup(namelist[0]); free(instlist); free(namelist); } } /* Ready for Zabbix. */ metrics = (ZBX_METRIC *)realloc(mptr, (metric_count + 1) * sizeof(ZBX_METRIC)); if (metrics == NULL) { metrics = mptr; free(metric); free(param); return; } metrics[metric_count].key = metric; metrics[metric_count].flags = flags; metrics[metric_count].function = zbx_module_pcp_fetch_metric; metrics[metric_count].test_param = param; metric_count++; }
int get_instances(const char *purpose, int value, pmDesc *descs, int **ids, char ***insts) { int sts, i; if (descs[value].pmid == PM_ID_NULL) { /* we have no descriptor for this metric, thus no instances */ *insts = NULL; *ids = NULL; return 0; } sts = !rawreadflag ? pmGetInDom(descs[value].indom, ids, insts) : pmGetInDomArchive(descs[value].indom, ids, insts); if (sts == PM_ERR_INDOM_LOG) { /* metrics but no indom - expected sometimes, "no values" */ *insts = NULL; *ids = NULL; return 0; } if (sts < 0) { fprintf(stderr, "%s: %s instances: %s\n", pmProgname, purpose, pmErrStr(sts)); cleanstop(1); } if (pmDebug & DBG_TRACE_APPL1) { fprintf(stderr, "%s: got %d %s instances:\n", pmProgname, sts, purpose); for (i=0; i < sts; i++) fprintf(stderr, " [%d] %s\n", (*ids)[i], (*insts)[i]); } return sts; }
void doindom(pmResult *rp) { pmValueSet *vsp; int i; int j; int needti = 0; int need; metric_t *mp = NULL; int *instlist; char **namelist; int sts; for (i = 0; i < rp->numpmid; i++) { vsp = rp->vset[i]; if (vsp->numval <= 0) continue; /* * pmidlist[] and rp->vset[]->pmid may not be in 1:1 * correspondence because we come here after rewrite() has * been called ... search for matching pmid */ for (j = 0; j < numpmid; j++) { if (pmidlist[j] == vsp->pmid) { mp = &metriclist[j]; break; } } if (mp == NULL) { fprintf(stderr, "%s: doindom: Arrgh, unexpected PMID %s @ vset[%d]\n", pmProgname, pmIDStr(vsp->pmid), i); __pmDumpResult(stderr, rp); exit(1); } if (mp->idp == NULL) continue; if ((sts = pmGetInDom(mp->idp->indom, &instlist, &namelist)) < 0) { fprintf(stderr, "%s: doindom: pmGetInDom (%s) failed: %s\n", pmProgname, pmInDomStr(mp->idp->indom), pmErrStr(sts)); exit(1); } need = 1; /* * Need to output the indom if the number of instances changes * or the set of instance ids are not the same from the last * time. */ if (sts == mp->idp->numinst) { for (j = 0; j < mp->idp->numinst; j++) { if (mp->idp->inst[j] != instlist[j]) break; } if (j == mp->idp->numinst) { /* * Do we need to check the namelist elts as well, e.g. * using strcmp()? * Not at this stage ... if the instance ids are all the * same, then only a very odd (and non-compliant) PMDA * would change the mapping from id to name on the fly */ need = 0; } } if (need) { #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) { fprintf(stderr, "Add metadata: indom %s for metric %s\n", pmInDomStr(mp->idp->indom), pmIDStr(vsp->pmid)); } #endif if (mp->idp->name != NULL) free(mp->idp->name); if (mp->idp->inst != NULL) free(mp->idp->inst); mp->idp->name = namelist; mp->idp->inst = instlist; mp->idp->numinst = sts; if ((sts = __pmLogPutInDom(&logctl, mp->idp->indom, ¤t, mp->idp->numinst, mp->idp->inst, mp->idp->name)) < 0) { fprintf(stderr, "%s: Error: failed to add pmInDom: indom %s (for pmid %s): %s\n", pmProgname, pmInDomStr(mp->idp->indom), pmIDStr(vsp->pmid), pmErrStr(sts)); exit(1); } needti = 1; /* requires a temporal index update */ } else { free(instlist); free(namelist); } } if (needti) { fflush(logctl.l_mdfp); __pmLogPutIndex(&logctl, ¤t); } }
/* Fill in current instances into given Context. Instances sorted by instance identifier. */ static void initinsts(Context *x) { int *ip; char **np; InstPair *pp; int n; int e; int i; if (x->desc.indom == PM_INDOM_NULL) x->inum = 0; else { /* fill in instance ids for given profile */ if (! x->iall) { n = x->inum; np = x->inames; ip = (int *)malloc(n * sizeof(int)); if (ip == NULL) { __pmNoMem("pmval.ip", n * sizeof(int), PM_FATAL_ERR); } x->iids = ip; for (i = 0; i < n; i++) { if (opts.context == PM_CONTEXT_ARCHIVE) e = pmLookupInDomArchive(x->desc.indom, *np); else e = pmLookupInDom(x->desc.indom, *np); if (e < 0) { printf("%s: instance %s not available\n", pmProgname, *np); exit(EXIT_FAILURE); } *ip = e; np++; ip++; } ip = x->iids; np = x->inames; if ((e = pmAddProfile(x->desc.indom, x->inum, x->iids)) < 0) { fprintf(stderr, "%s: pmAddProfile: %s\n", pmProgname, pmErrStr(e)); exit(EXIT_FAILURE); } } /* find all available instances */ else { if (opts.context == PM_CONTEXT_ARCHIVE) n = pmGetInDomArchive(x->desc.indom, &ip, &np); else n = pmGetInDom(x->desc.indom, &ip, &np); if (n < 0) { fprintf(stderr, "%s: pmGetInDom(%s): %s\n", pmProgname, pmInDomStr(x->desc.indom), pmErrStr(n)); exit(EXIT_FAILURE); } x->inum = n; x->iids = ip; x->inames = np; } /* build InstPair list and sort */ pp = (InstPair *)malloc(n * sizeof(InstPair)); if (pp == NULL) { __pmNoMem("pmval.pp", n * sizeof(InstPair), PM_FATAL_ERR); } x->ipairs = pp; for (i = 0; i < n; i++) { pp->id = *ip; pp->name = *np; ip++; np++; pp++; } qsort(x->ipairs, (size_t)n, sizeof(InstPair), compare); } }
void test_instance(void) { int sts; int i; print_banner_start("instance"); if (indom == PM_INDOM_NULL) return; fflush(stdout); if ((child_pid=fork()) == 0) { /* child sleeps and then exits */ sleep(2*refresh+1); exit(0); } printf("cpid=%" FMT_PID "\n", child_pid); if (is_hotproc) { /* sleep so that hotprocs can update active list */ sleep(2*refresh); } printf("\n--- GetInDom ---\n"); sts = pmGetInDom(indom, &all_inst, &all_names); if (sts < 0) { printf("%s: pmGetInDom: %s\n", pmProgname, pmErrStr(sts)); exit(1); } else all_n = sts; /* print the instance id's (i.e. pids) match the first field in the name */ for (i=0; i < all_n; i++) { int inst; if (verbose) printf(" instance map [%d \"%s\"]\n", all_inst[i], all_names[i]); /* e.g. inst=0, name="00000 sched" */ if (sscanf(all_names[i], proc_fmt, &inst) != 1) { printf("%s: Error: cannot get PID from instname\n", pmProgname); printf("%s: <id,name> = <%ld,\"%s\">\n", pmProgname, (long)all_inst[i], all_names[i]); exit(1); } if (inst != all_inst[i]) { printf("%s: Error: instname is wrong\n", pmProgname); printf("%s: <id,name> = <%ld,\"%s\"> != %d (fmt=%s)\n", pmProgname, (long)all_inst[i], all_names[i], inst, proc_fmt); exit(1); } } /* parent waits for child to exit */ /* so that the the following lookups will NOT be able to find it */ wait(&sts); printf("\n--- LookupInDom ---\n"); for (i = 0; i < all_n; i++) { int inst, x; sts = pmLookupInDom(indom, all_names[i]); if (sts < 0) { if (sts == PM_ERR_INST) { if (all_inst[i] == child_pid) printf(" Death of child detected, pid=%" FMT_PID "\n", child_pid); /* ignore deaths */ continue; } else { printf("%s: pmLookupInDom: %s\n", pmProgname, pmErrStr(sts)); exit(1); } } inst = sts; if (verbose) printf(" instance lookup \"%s\" --> %d\n", all_names[i], inst); sscanf(all_names[i], proc_fmt, &x); if (x != inst) { printf("%s: Error: inst is wrong, expect: %d got: %d\n", pmProgname, inst, x); printf("%s: Expected=%d, Actual=%d\n", pmProgname, x, inst); exit(1); } }/*for*/ printf("\n--- NameInDom ---\n"); for (i = 0; i < all_n; i++) { char *name; char x[100]; sts = pmNameInDom(indom, all_inst[i], &name); if (sts < 0) { if (sts == PM_ERR_INST) { if (all_inst[i] == child_pid) printf(" Death of child detected\n"); /* ignore deaths */ continue; } else { printf("%s: pmNameInDom: %s\n", pmProgname, pmErrStr(sts)); exit(1); } } if (verbose) printf(" instance name %d --> \"%s\"\n", all_inst[i], name); sprintf(x, proc_fmt, all_inst[i]); if (strncmp(name, x, strlen(x)) != 0 || (name[strlen(x)] != '\0' && name[strlen(x)] != ' ')) { /* try w/out leading zeroes */ char *q; sprintf(x, "%d", all_inst[i]); for (q = name; *q && *q == '0'; q++) ; if (strncmp(q, x, strlen(x)) != 0 || (q[strlen(x)] != '\0' && q[strlen(x)] != ' ')) { printf("%s: Error: name is wrong\n", pmProgname); printf("%s: Expected=\"%s\", Actual=\"%s\"\n", pmProgname, x, name); exit(1); } } free(name); }/*for*/ print_banner_end("instance"); }
static void func(void) { int sts; char **children; char *p; if ((sts = pmUseContext(ctx)) < 0) { printf("pmUseContext(%d): %s\n", ctx, pmErrStr(sts)); pthread_exit(NULL); } /* * expect this to fail for the second thread through when * using PM_CONTEXT_LOCAL */ if ((sts = pmDupContext()) < 0) printf("pmDupContext: %s\n", pmErrStr(sts)); else printf("pmDupContext: -> %d\n", sts); if ((sts = pmUseContext(ctx)) < 0) { printf("pmUseContext(%d): %s\n", ctx, pmErrStr(sts)); pthread_exit(NULL); } else printf("pmUseContext(%d) -> %d\n", ctx, sts); if ((sts = pmLookupName(1, namelist, pmidlist)) < 0) printf("pmLookupName: %s\n", pmErrStr(sts)); else printf("pmLookupName: -> %s\n", pmIDStr(pmidlist[0])); pthread_barrier_wait(&barrier); if (pmidlist[0] == 0) pthread_exit("Loser failed to get pmid!"); if ((sts = pmGetPMNSLocation()) < 0) printf("pmGetPMNSLocation: %s\n", pmErrStr(sts)); else printf("pmGetPMNSLocation: -> %d\n", sts); /* leaf node, expect no children */ if ((sts = pmGetChildrenStatus(namelist[0], &children, NULL)) < 0) printf("pmGetChildrenStatus: %s\n", pmErrStr(sts)); else printf("pmGetChildrenStatus: -> %d\n", sts); if ((sts = pmLookupDesc(pmidlist[0], &desc)) < 0) printf("pmLookupDesc: %s\n", pmErrStr(sts)); else printf("pmLookupDesc: -> %s type=%s indom=%s\n", pmIDStr(desc.pmid), pmTypeStr(desc.type), pmInDomStr(desc.indom)); pthread_barrier_wait(&barrier); if (desc.pmid == 0) pthread_exit("Loser failed to get pmDesc!"); if ((sts = pmLookupText(pmidlist[0], PM_TEXT_ONELINE, &p)) < 0) printf("pmLookupText: %s\n", pmErrStr(sts)); else printf("pmLookupText: -> %s\n", p); if ((sts = pmGetInDom(desc.indom, &instance, &instname)) < 0) printf("pmGetInDom: %s: %s\n", pmInDomStr(desc.indom), pmErrStr(sts)); else printf("pmGetInDom: -> %d\n", sts); pthread_barrier_wait(&barrier); if (instance == NULL) pthread_exit("Loser failed to get indom!"); if ((sts = pmNameInDom(desc.indom, instance[0], &p)) < 0) printf("pmNameInDom: %s\n", pmErrStr(sts)); else printf("pmNameInDom: %d -> %s\n", instance[0], p); if ((sts = pmLookupInDom(desc.indom, instname[0])) < 0) printf("pmLookupInDom: %s\n", pmErrStr(sts)); else printf("pmLookupInDom: %s -> %d\n", instname[0], sts); if ((sts = pmFetch(1, pmidlist, &rp)) < 0) printf("pmFetch: %s\n", pmErrStr(sts)); else printf("pmFetch: -> OK\n"); pthread_barrier_wait(&barrier); if (rp == NULL) pthread_exit("Loser failed to get pmResult!"); if ((sts = pmStore(rp)) < 0) printf("pmStore: %s\n", pmErrStr(sts)); else printf("pmStore: -> OK\n"); pthread_exit(NULL); }
static void dometric(const char *name) { int n; pmID pmidlist[] = { PM_ID_NULL }; pmDesc desc; int *instlist = NULL; char **instname = NULL; pmResult *result; extern int pmDebug; _metrics++; /* cast const away as pmLookupName will not modify this string */ if ((n = pmLookupName(1, (char **)&name, pmidlist)) < 0) { printf("%s: pmLookupName: %s\n", name, pmErrStr(n)); return; } if ((n = pmLookupDesc(pmidlist[0], &desc)) < 0) { printf("%s: pmLookupDesc: %s\n", name, pmErrStr(n)); return; } if (desc.indom != PM_INDOM_NULL) { _indom++; if ((n = pmGetInDom(desc.indom, &instlist, &instname)) < 0) { printf("%s: pmGetInDom: %s\n", name, pmErrStr(n)); return; } if (instlist) free(instlist); if (instname) free(instname); } if ((n = pmFetch(1, pmidlist, &result)) < 0) { printf("%s: pmFetch: %s\n", name, pmErrStr(n)); return; } if (result->numpmid != 1) { printf("%s: pmFetch: numpmid=%d, not 1\n", name, result->numpmid); } else { if (result->vset[0]->numval == 0) printf("%s: pmFetch: no value available\n", name); else if (result->vset[0]->numval < 0) printf("%s: pmFetch: %s\n", name, pmErrStr(result->vset[0]->numval)); else { if (result->vset[0]->valfmt == PM_VAL_INSITU) { _insitu++; if (pmDebug && DBG_TRACE_APPL0) printf("%s: insitu type=%s\n", name, pmTypeStr(desc.type)); } else { _ptr++; if (pmDebug && DBG_TRACE_APPL0) printf("%s: ptr size=%d valtype=%d descrtype=%s\n", name, result->vset[0]->vlist[0].value.pval->vlen, result->vset[0]->vlist[0].value.pval->vtype, pmTypeStr(desc.type)); } } } pmFreeResult(result); }
static void get_indom(void) { static int onetrip = 1; if (instances != NULL) free(instances); if (instance_names != NULL) free(instance_names); if ((num_inst = pmGetInDom(proc_indom, &instances, &instance_names)) <= 0) { fprintf(stderr, "%s: Failed to find any proc instances : %s\n", pmProgname, pmErrStr(num_inst)); exit(1); } /* process the instance names * - find how long a pid is * - create pid label fmt based on pid length */ if (onetrip) { char *str = instance_names[0]; onetrip=0; /* get pid str up to first space */ pid_len = 0; while (*str != '\0' && *str != ' ') { pid_len++; str++; } if (*str == '\0') { /* shouldn't happen */ fprintf(stderr, "%s: Bad proc instance : %s\n", pmProgname, instance_names[0]); exit(1); } sprintf(pid_label_fmt, "%%%ds", pid_len); sprintf(pid_fmt, "%%%dd", pid_len); } rate_tab = realloc(rate_tab, sizeof(rate_entry_t)*num_inst); if (rate_tab == NULL) { fprintf(stderr, "%s: Failed to allocate rate table\n", pmProgname); exit(1); } val_tab = realloc(val_tab, sizeof(val_entry_t)*num_inst); if (val_tab == NULL) { fprintf(stderr, "%s: Failed to allocate value table\n", pmProgname); exit(1); } pmDelProfile(proc_indom, 0, NULL); pmAddProfile(proc_indom, num_inst, instances); }
/* create a pmValueSet large enough to contain the union of the current * instance domain of the specified metric and any previous instances from * the history list. */ static pmValueSet * build_vset(pmID pmid, int usehist) { __pmHashNode *hp; pmidhist_t *php = NULL; insthist_t *ihp; int need = 0; int i, numindom = 0; pmDesc desc; int have_desc; int *instlist = NULL; char **namelist = NULL; pmValueSet *vsp; if (usehist) { /* find the number of instances of the metric in the history (1 if * single-valued metric) */ for (hp = __pmHashSearch(pmid, &hist_hash); hp != NULL; hp = hp->next) if ((pmID)hp->key == pmid) break; if (hp != NULL) { php = (pmidhist_t *)hp->data; need = php->ph_numinst; } } /* * get the current instance domain, so that if the metric hasn't been * logged yet a sensible result is returned. */ if ((have_desc = pmLookupDesc(pmid, &desc)) < 0) goto no_info; if (desc.indom == PM_INDOM_NULL) need = 1; /* will be same in history */ else { int j; if ((numindom = pmGetInDom(desc.indom, &instlist, &namelist)) < 0) { have_desc = numindom; goto no_info; } /* php will be null if usehist is false or there is no history yet */ if (php == NULL) need = numindom; /* no history => use indom */ else for (i = 0; i < numindom; i++) { int inst = instlist[i]; for (j = 0; j < php->ph_numinst; j++) if (inst == php->ph_instlist[j].ih_inst) break; /* * if instance is in history but not instance domain, leave * extra space for it in vset, otherwise use the USEINDOM * flag to avoid another NxM comparison when building the vset * instances later. */ if (j >= php->ph_numinst) need++; else PMLC_SET_USEINDOM(php->ph_instlist[j].ih_flags, 1); } } no_info: need = sizeof(pmValueSet) + (need - 1) * sizeof(pmValue); vsp = (pmValueSet *)malloc(need); if (vsp == NULL) { __pmNoMem("build_vset for control/enquire", need, PM_FATAL_ERR); } vsp->pmid = pmid; if (have_desc < 0) { vsp->numval = have_desc; } else if (desc.indom == PM_INDOM_NULL) { vsp->vlist[0].inst = PM_IN_NULL; vsp->numval = 1; } else { int j; i = 0; /* get instances out of instance domain first */ if (numindom > 0) for (j = 0; j < numindom; j++) vsp->vlist[i++].inst = instlist[j]; /* then any not in instance domain from history */ if (php != NULL) { ihp = &php->ph_instlist[0]; for (j = 0; j < php->ph_numinst; j++, ihp++) if (PMLC_GET_USEINDOM(ihp->ih_flags)) /* it's already in the indom */ PMLC_SET_USEINDOM(ihp->ih_flags, 0); else vsp->vlist[i++].inst = ihp->ih_inst; } vsp->numval = i; } if (instlist) free(instlist); if (namelist) free(namelist); return vsp; }
/* reinitialize Metric - only for live host */ int /* 1: ok, 0: try again later, -1: fail */ reinitMetric(Metric *m) { char *hname = symName(m->hname); char *mname = symName(m->mname); char **inames; int *iids; int handle; int ret = 1; int sts; int i, j; /* set up temporary context */ if ((handle = newContext(hname)) < 0) return 0; host_state_changed(hname, STATE_RECONN); if ((sts = pmLookupName(1, &mname, &m->desc.pmid)) < 0) { ret = 0; goto end; } /* fill in performance metric descriptor */ if ((sts = pmLookupDesc(m->desc.pmid, &m->desc)) < 0) { ret = 0; goto end; } if (m->desc.type == PM_TYPE_STRING || m->desc.type == PM_TYPE_AGGREGATE || m->desc.type == PM_TYPE_AGGREGATE_STATIC || m->desc.type == PM_TYPE_EVENT || m->desc.type == PM_TYPE_HIGHRES_EVENT || m->desc.type == PM_TYPE_UNKNOWN) { fprintf(stderr, "%s: metric %s has non-numeric type\n", pmProgname, mname); ret = -1; } else if (m->desc.indom == PM_INDOM_NULL) { if (m->specinst != 0) { fprintf(stderr, "%s: metric %s has no instances\n", pmProgname, mname); ret = -1; } else m->m_idom = 1; } else { if ((sts = pmGetInDom(m->desc.indom, &iids, &inames)) < 0) { /* full profile */ ret = 0; } else { if (m->specinst == 0) { /* all instances */ m->iids = iids; m->m_idom = sts; m->inames = alloc(m->m_idom*sizeof(char *)); for (i = 0; i < m->m_idom; i++) { m->inames[i] = sdup(inames[i]); } } else { /* explicit instance profile */ m->m_idom = 0; for (i = 0; i < m->specinst; i++) { /* look for first matching instance name */ for (j = 0; j < sts; j++) { if (eqinst(m->inames[i], inames[j])) { m->iids[i] = iids[j]; m->m_idom++; break; } } if (j == sts) { m->iids[i] = PM_IN_NULL; ret = 0; } } if (sts > 0) { /* * pmGetInDom or pmGetInDomArchive returned some * instances above */ free(iids); } /* * if specinst != m_idom, then some not found ... move these * to the end of the list */ for (j = m->specinst-1; j >= 0; j--) { if (m->iids[j] != PM_IN_NULL) break; } for (i = 0; i < j; i++) { if (m->iids[i] == PM_IN_NULL) { /* need to swap */ char *tp; tp = m->inames[i]; m->inames[i] = m->inames[j]; m->iids[i] = m->iids[j]; m->inames[j] = tp; m->iids[j] = PM_IN_NULL; j--; } } } #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL1) { int numinst; fprintf(stderr, "reinitMetric: %s from %s: instance domain specinst=%d\n", mname, hname, m->specinst); if (m->m_idom < 1) fprintf(stderr, " %d instances!\n", m->m_idom); if (m->specinst == 0) numinst = m->m_idom; else numinst = m->specinst; for (i = 0; i < numinst; i++) { fprintf(stderr, " indom[%d]", i); if (m->iids[i] == PM_IN_NULL) fprintf(stderr, " ?missing"); else fprintf(stderr, " %d", m->iids[i]); fprintf(stderr, " \"%s\"\n", m->inames[i]); } } #endif if (sts > 0) { /* * pmGetInDom or pmGetInDomArchive returned some instances * above */ free(inames); } } } if (ret == 1) { /* compute conversion factor into canonical units - non-zero conversion factor flags initialized metric */ m->conv = scale(m->desc.units); /* automatic rate computation */ if (m->desc.sem == PM_SEM_COUNTER) { m->vals = (double *) ralloc(m->vals, m->m_idom * sizeof(double)); for (j = 0; j < m->m_idom; j++) m->vals[j] = 0; } } if (ret >= 0) { /* * re-shape, starting here are working up the expression until * we reach the top of the tree or the designated metrics * associated with the node are not the same */ Expr *x = m->expr; while (x) { /* * only re-shape expressions that may have set values */ if (x->op == CND_FETCH || x->op == CND_NEG || x->op == CND_ADD || x->op == CND_SUB || x->op == CND_MUL || x->op == CND_DIV || x->op == CND_SUM_HOST || x->op == CND_SUM_INST || x->op == CND_SUM_TIME || x->op == CND_AVG_HOST || x->op == CND_AVG_INST || x->op == CND_AVG_TIME || x->op == CND_MAX_HOST || x->op == CND_MAX_INST || x->op == CND_MAX_TIME || x->op == CND_MIN_HOST || x->op == CND_MIN_INST || x->op == CND_MIN_TIME || x->op == CND_EQ || x->op == CND_NEQ || x->op == CND_LT || x->op == CND_LTE || x->op == CND_GT || x->op == CND_GTE || x->op == CND_NOT || x->op == CND_AND || x->op == CND_OR || x->op == CND_RISE || x->op == CND_FALL || x->op == CND_INSTANT || x->op == CND_MATCH || x->op == CND_NOMATCH) { instFetchExpr(x); findEval(x); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL1) { fprintf(stderr, "reinitMetric: re-shaped ...\n"); dumpExpr(x); } #endif } if (x->parent) { x = x->parent; if (x->metrics == m) continue; } break; } } end: /* destroy temporary context */ pmDestroyContext(handle); return ret; }
/* initialize Metric */ int /* 1: ok, 0: try again later, -1: fail */ initMetric(Metric *m) { char *hname = symName(m->hname); char *mname = symName(m->mname); char **inames; int *iids; int handle; int ret = 1; int sts; int i, j; /* set up temporary context */ if ((handle = newContext(hname)) < 0) return 0; host_state_changed(hname, STATE_RECONN); if ((sts = pmLookupName(1, &mname, &m->desc.pmid)) < 0) { fprintf(stderr, "%s: metric %s not in namespace for %s\n" "pmLookupName failed: %s\n", pmProgname, mname, findsource(hname), pmErrStr(sts)); ret = 0; goto end; } /* fill in performance metric descriptor */ if ((sts = pmLookupDesc(m->desc.pmid, &m->desc)) < 0) { fprintf(stderr, "%s: metric %s not currently available from %s\n" "pmLookupDesc failed: %s\n", pmProgname, mname, findsource(hname), pmErrStr(sts)); ret = 0; goto end; } if (m->desc.type == PM_TYPE_STRING || m->desc.type == PM_TYPE_AGGREGATE || m->desc.type == PM_TYPE_AGGREGATE_STATIC || m->desc.type == PM_TYPE_EVENT || m->desc.type == PM_TYPE_HIGHRES_EVENT || m->desc.type == PM_TYPE_UNKNOWN) { fprintf(stderr, "%s: metric %s has non-numeric type\n", pmProgname, mname); ret = -1; } else if (m->desc.indom == PM_INDOM_NULL) { if (m->specinst != 0) { fprintf(stderr, "%s: metric %s has no instances\n", pmProgname, mname); ret = -1; } else m->m_idom = 1; } else { /* metric has instances, get full instance profile */ if (archives) { if ((sts = pmGetInDomArchive(m->desc.indom, &iids, &inames)) < 0) { fprintf(stderr, "Metric %s from %s - instance domain not " "available in archive\npmGetInDomArchive failed: %s\n", mname, findsource(hname), pmErrStr(sts)); ret = -1; } } else if ((sts = pmGetInDom(m->desc.indom, &iids, &inames)) < 0) { fprintf(stderr, "Instance domain for metric %s from %s not (currently) available\n" "pmGetIndom failed: %s\n", mname, findsource(hname), pmErrStr(sts)); ret = 0; } if (ret == 1) { /* got instance profile */ if (m->specinst == 0) { /* all instances */ m->iids = iids; m->m_idom = sts; m->inames = alloc(m->m_idom*sizeof(char *)); for (i = 0; i < m->m_idom; i++) { m->inames[i] = sdup(inames[i]); } } else { /* selected instances only */ m->m_idom = 0; for (i = 0; i < m->specinst; i++) { /* look for first matching instance name */ for (j = 0; j < sts; j++) { if (eqinst(m->inames[i], inames[j])) { m->iids[i] = iids[j]; m->m_idom++; break; } } if (j == sts) { __pmNotifyErr(LOG_ERR, "metric %s from %s does not " "(currently) have instance \"%s\"\n", mname, findsource(hname), m->inames[i]); m->iids[i] = PM_IN_NULL; ret = 0; } } if (sts > 0) { /* * pmGetInDom or pmGetInDomArchive returned some * instances above */ free(iids); } /* * if specinst != m_idom, then some not found ... move these * to the end of the list */ for (j = m->specinst-1; j >= 0; j--) { if (m->iids[j] != PM_IN_NULL) break; } for (i = 0; i < j; i++) { if (m->iids[i] == PM_IN_NULL) { /* need to swap */ char *tp; tp = m->inames[i]; m->inames[i] = m->inames[j]; m->iids[i] = m->iids[j]; m->inames[j] = tp; m->iids[j] = PM_IN_NULL; j--; } } } #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL1) { int numinst; fprintf(stderr, "initMetric: %s from %s: instance domain specinst=%d\n", mname, hname, m->specinst); if (m->m_idom < 1) fprintf(stderr, " %d instances!\n", m->m_idom); numinst = m->specinst == 0 ? m->m_idom : m->specinst; for (i = 0; i < numinst; i++) { fprintf(stderr, " indom[%d]", i); if (m->iids[i] == PM_IN_NULL) fprintf(stderr, " ?missing"); else fprintf(stderr, " %d", m->iids[i]); fprintf(stderr, " \"%s\"\n", m->inames[i]); } } #endif if (sts > 0) { /* * pmGetInDom or pmGetInDomArchive returned some instances * above */ free(inames); } } } if (ret == 1) { /* compute conversion factor into canonical units - non-zero conversion factor flags initialized metric */ m->conv = scale(m->desc.units); /* automatic rate computation */ if (m->desc.sem == PM_SEM_COUNTER) { m->vals = (double *) ralloc(m->vals, m->m_idom * sizeof(double)); for (j = 0; j < m->m_idom; j++) m->vals[j] = 0; } } end: /* destroy temporary context */ pmDestroyContext(handle); /* retry not meaningful for archives */ if (archives && (ret == 0)) ret = -1; return ret; }
static void report(void) { int i; int sts; pmDesc desc; pmResult *result = NULL; pmResult *xresult = NULL; pmValueSet *vsp = NULL; char *buffer; int all_count; int *all_inst; char **all_names; if (batchidx == 0) return; /* Lookup names. * Cull out names that were unsuccessfully looked up. * However, it is unlikely to fail because names come from a traverse PMNS. */ if (need_pmid) { if ((sts = pmLookupName(batchidx, namelist, pmidlist)) < 0) { int j = 0; for (i = 0; i < batchidx; i++) { if (pmidlist[i] == PM_ID_NULL) { printf("%s: pmLookupName: %s\n", namelist[i], pmErrStr(sts)); free(namelist[i]); } else { /* assert(j <= i); */ pmidlist[j] = pmidlist[i]; namelist[j] = namelist[i]; j++; } } batchidx = j; } } if (p_value || verify) { if (opts.context == PM_CONTEXT_ARCHIVE) { if ((sts = pmSetMode(PM_MODE_FORW, &opts.origin, 0)) < 0) { fprintf(stderr, "%s: pmSetMode failed: %s\n", pmProgname, pmErrStr(sts)); exit(1); } } if ((sts = pmFetch(batchidx, pmidlist, &result)) < 0) { for (i = 0; i < batchidx; i++) printf("%s: pmFetch: %s\n", namelist[i], pmErrStr(sts)); goto done; } } for (i = 0; i < batchidx; i++) { if (p_desc || p_value || verify) { if ((sts = pmLookupDesc(pmidlist[i], &desc)) < 0) { printf("%s: pmLookupDesc: %s\n", namelist[i], pmErrStr(sts)); continue; } } if (p_desc || p_help || p_value) /* Not doing verify, output separator */ putchar('\n'); if (p_value || verify) { vsp = result->vset[i]; if (p_force) { if (result->vset[i]->numval == PM_ERR_PROFILE) { /* indom is non-enumerable; try harder */ if ((all_count = pmGetInDom(desc.indom, &all_inst, &all_names)) > 0) { pmDelProfile(desc.indom, 0, NULL); pmAddProfile(desc.indom, all_count, all_inst); if (xresult != NULL) { pmFreeResult(xresult); xresult = NULL; } if (opts.context == PM_CONTEXT_ARCHIVE) { if ((sts = pmSetMode(PM_MODE_FORW, &opts.origin, 0)) < 0) { fprintf(stderr, "%s: pmSetMode failed: %s\n", pmProgname, pmErrStr(sts)); exit(1); } } if ((sts = pmFetch(1, &pmidlist[i], &xresult)) < 0) { printf("%s: pmFetch: %s\n", namelist[i], pmErrStr(sts)); continue; } vsp = xresult->vset[0]; /* leave the profile in the default state */ free(all_inst); free(all_names); pmDelProfile(desc.indom, 0, NULL); pmAddProfile(desc.indom, 0, NULL); } else if (all_count == 0) { printf("%s: pmGetIndom: No instances?\n", namelist[i]); continue; } else { printf("%s: pmGetIndom: %s\n", namelist[i], pmErrStr(all_count)); continue; } } } } if (verify) { if (desc.type == PM_TYPE_NOSUPPORT) printf("%s: Not Supported\n", namelist[i]); else if (vsp->numval < 0) printf("%s: %s\n", namelist[i], pmErrStr(vsp->numval)); else if (vsp->numval == 0) printf("%s: No value(s) available\n", namelist[i]); continue; } else /* not verify */ printf("%s", namelist[i]); if (p_mid) printf(" PMID: %s", pmIDStr(pmidlist[i])); if (p_fullmid) printf(" = %d = 0x%x", pmidlist[i], pmidlist[i]); if (p_oneline) { if ((sts = pmLookupText(pmidlist[i], PM_TEXT_ONELINE, &buffer)) == 0) { if (p_fullmid) printf("\n "); else putchar(' '); printf("[%s]", buffer); free(buffer); } else printf(" One-line Help: Error: %s\n", pmErrStr(sts)); } putchar('\n'); if (p_desc) __pmPrintDesc(stdout, &desc); if (p_help) { if ((sts = pmLookupText(pmidlist[i], PM_TEXT_HELP, &buffer)) == 0) { char *p; for (p = buffer; *p; p++) ; while (p > buffer && p[-1] == '\n') { p--; *p = '\0'; } if (*buffer != '\0') { printf("Help:\n"); printf("%s", buffer); putchar('\n'); } else printf("Help: <empty entry>\n"); free(buffer); } else printf("Full Help: Error: %s\n", pmErrStr(sts)); } if (p_value) { mydump(&desc, vsp, NULL); } } if (result != NULL) { pmFreeResult(result); result = NULL; } if (xresult != NULL) { pmFreeResult(xresult); xresult = NULL; } done: for (i = 0; i < batchidx; i++) free(namelist[i]); batchidx = 0; }