/* * 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); } if (archive) numinst = pmGetInDomArchive(indom, &instlist, &namelist); else numinst = pmGetInDom(indom, &instlist, &namelist); last = indom; } for (i = 0; i < numinst; i++) { if (instlist[i] == inst) return namelist[i]; } return NULL; }
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; }
/* 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); } }
/* 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; }