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); }
static void get_sample(info_t *ip) { static pmResult *crp = NULL; /* current */ static pmResult *prp = NULL; /* prior */ static int first = 1; static int numpmid; static pmID *pmidlist; static pmDesc *desclist; static int inst1; static int inst15; static pmUnits mbyte_scale; int sts; int i; float u; pmAtomValue tmp; pmAtomValue atom; double dt; if (first) { /* first time initialization */ mbyte_scale.dimSpace = 1; mbyte_scale.scaleSpace = PM_SPACE_MBYTE; numpmid = sizeof(pmclient_sample) / sizeof(char *); if ((pmidlist = (pmID *)malloc(numpmid * sizeof(pmidlist[0]))) == NULL) { fprintf(stderr, "%s: get_sample: malloc: %s\n", pmProgname, osstrerror()); exit(1); } if ((desclist = (pmDesc *)malloc(numpmid * sizeof(desclist[0]))) == NULL) { fprintf(stderr, "%s: get_sample: malloc: %s\n", pmProgname, osstrerror()); exit(1); } if ((sts = pmLookupName(numpmid, pmclient_sample, pmidlist)) < 0) { printf("%s: pmLookupName: %s\n", pmProgname, pmErrStr(sts)); for (i = 0; i < numpmid; i++) { if (pmidlist[i] == PM_ID_NULL) fprintf(stderr, "%s: metric \"%s\" not in name space\n", pmProgname, pmclient_sample[i]); } exit(1); } for (i = 0; i < numpmid; i++) { if ((sts = pmLookupDesc(pmidlist[i], &desclist[i])) < 0) { fprintf(stderr, "%s: cannot retrieve description for metric \"%s\" (PMID: %s)\nReason: %s\n", pmProgname, pmclient_sample[i], pmIDStr(pmidlist[i]), pmErrStr(sts)); exit(1); } } } /* fetch the current metrics */ if ((sts = pmFetch(numpmid, pmidlist, &crp)) < 0) { fprintf(stderr, "%s: pmFetch: %s\n", pmProgname, pmErrStr(sts)); exit(1); } /* * minor gotcha ... for archives, it helps to do the first fetch of * real data before interrogating the instance domains ... this * forces us to be "after" the first batch of instance domain info * in the meta data files */ if (first) { /* * from now on, just want the 1 minute and 15 minute load averages, * so limit the instance profile for this metric */ pmDelProfile(desclist[LOADAV].indom, 0, NULL); /* all off */ if ((inst1 = pmLookupInDom(desclist[LOADAV].indom, "1 minute")) < 0) { fprintf(stderr, "%s: cannot translate instance for 1 minute load average\n", pmProgname); exit(1); } pmAddProfile(desclist[LOADAV].indom, 1, &inst1); if ((inst15 = pmLookupInDom(desclist[LOADAV].indom, "15 minute")) < 0) { fprintf(stderr, "%s: cannot translate instance for 15 minute load average\n", pmProgname); exit(1); } pmAddProfile(desclist[LOADAV].indom, 1, &inst15); first = 0; } /* if the second or later sample, pick the results apart */ if (prp != NULL) { dt = __pmtimevalSub(&crp->timestamp, &prp->timestamp); ip->cpu_util = 0; ip->peak_cpu_util = -1; /* force re-assignment at first CPU */ for (i = 0; i < ncpu; i++) { pmExtractValue(crp->vset[CPU_USR]->valfmt, &crp->vset[CPU_USR]->vlist[i], desclist[CPU_USR].type, &atom, PM_TYPE_FLOAT); u = atom.f; pmExtractValue(prp->vset[CPU_USR]->valfmt, &prp->vset[CPU_USR]->vlist[i], desclist[CPU_USR].type, &atom, PM_TYPE_FLOAT); u -= atom.f; pmExtractValue(crp->vset[CPU_SYS]->valfmt, &crp->vset[CPU_SYS]->vlist[i], desclist[CPU_SYS].type, &atom, PM_TYPE_FLOAT); u += atom.f; pmExtractValue(prp->vset[CPU_SYS]->valfmt, &prp->vset[CPU_SYS]->vlist[i], desclist[CPU_SYS].type, &atom, PM_TYPE_FLOAT); u -= atom.f; /* * really should use pmConvertValue, but I _know_ the times * are in msec! */ u = u / (1000 * dt); if (u > 1.0) /* small errors are possible, so clip the utilization at 1.0 */ u = 1.0; ip->cpu_util += u; if (u > ip->peak_cpu_util) { ip->peak_cpu_util = u; ip->peak_cpu = i; } } ip->cpu_util /= ncpu; /* freemem - expect just one value */ pmExtractValue(crp->vset[FREEMEM]->valfmt, crp->vset[FREEMEM]->vlist, desclist[FREEMEM].type, &tmp, PM_TYPE_FLOAT); /* convert from today's units at the collection site to Mbytes */ pmConvScale(PM_TYPE_FLOAT, &tmp, &desclist[FREEMEM].units, &atom, &mbyte_scale); ip->freemem = atom.f; /* disk IOPS - expect just one value, but need delta */ pmExtractValue(crp->vset[DKIOPS]->valfmt, crp->vset[DKIOPS]->vlist, desclist[DKIOPS].type, &atom, PM_TYPE_U32); ip->dkiops = atom.ul; pmExtractValue(prp->vset[DKIOPS]->valfmt, prp->vset[DKIOPS]->vlist, desclist[DKIOPS].type, &atom, PM_TYPE_U32); ip->dkiops -= atom.ul; ip->dkiops = ((float)(ip->dkiops) + 0.5) / dt; /* load average ... process all values, matching up the instances */ for (i = 0; i < crp->vset[LOADAV]->numval; i++) { pmExtractValue(crp->vset[LOADAV]->valfmt, &crp->vset[LOADAV]->vlist[i], desclist[LOADAV].type, &atom, PM_TYPE_FLOAT); if (crp->vset[LOADAV]->vlist[i].inst == inst1) ip->load1 = atom.f; else if (crp->vset[LOADAV]->vlist[i].inst == inst15) ip->load15 = atom.f; } /* free very old result */ pmFreeResult(prp); } ip->timestamp = crp->timestamp; /* swizzle result pointers */ prp = crp; }
/* 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); }
int zbx_module_pcp_fetch_metric(AGENT_REQUEST *request, AGENT_RESULT *result) { int sts; char *metric[] = { request->key + strlen(ZBX_PCP_METRIC_PREFIX) }; char *inst; pmID pmid[1]; pmDesc desc[1]; pmResult *rp; pmAtomValue atom; int iid = 0; int i; /* Parameter is the instance. */ switch(request->nparam) { case 0: inst = NULL; break; case 1: inst = get_rparam(request, 0); break; default: SET_MSG_RESULT(result, strdup("Extraneous instance specification.")); return SYSINFO_RET_FAIL; break; } /* Preparations and sanity checks. */ sts = pmLookupName(1, metric, pmid); if (sts < 0) return SYSINFO_RET_FAIL; sts = pmLookupDesc(pmid[0], desc); if (sts < 0) return SYSINFO_RET_FAIL; if (inst != NULL && desc[0].indom == PM_INDOM_NULL) { SET_MSG_RESULT(result, strdup("Extraneous instance specification.")); return SYSINFO_RET_FAIL; } if ((inst == NULL && desc[0].indom != PM_INDOM_NULL) || (request->nparam == 1 && !strlen(inst))) { SET_MSG_RESULT(result, strdup("Missing instance specification.")); return SYSINFO_RET_FAIL; } if (desc[0].indom != PM_INDOM_NULL) { iid = pmLookupInDom(desc[0].indom, inst); if (iid < 0) { SET_MSG_RESULT(result, strdup("Instance not available.")); return SYSINFO_RET_FAIL; } } /* Fetch the metric values. */ sts = pmFetch(1, pmid, &rp); if (sts < 0) return SYSINFO_RET_FAIL; if (rp->vset[0]->numval < 1) { pmFreeResult(rp); SET_MSG_RESULT(result, strdup("No value available.")); return SYSINFO_RET_FAIL; } /* Locate the correct instance. */ for (i = 0; desc[0].indom != PM_INDOM_NULL && i < rp->vset[0]->numval; i++) { if (rp->vset[0]->vlist[i].inst == iid) { break; } } if (i == rp->vset[0]->numval) { pmFreeResult(rp); return SYSINFO_RET_FAIL; } /* Extract the wanted value. */ sts = pmExtractValue(rp->vset[0]->valfmt, &rp->vset[0]->vlist[i], desc[0].type, &atom, desc[0].type); pmFreeResult(rp); if (sts < 0) return SYSINFO_RET_FAIL; /* Hand it to the caller. */ switch(desc[0].type) { case PM_TYPE_32: SET_UI64_RESULT(result, atom.l); break; case PM_TYPE_U32: SET_UI64_RESULT(result, atom.ul); break; case PM_TYPE_64: SET_UI64_RESULT(result, atom.ll); break; case PM_TYPE_U64: SET_UI64_RESULT(result, atom.ull); break; case PM_TYPE_FLOAT: SET_DBL_RESULT(result, atom.f); break; case PM_TYPE_DOUBLE: SET_DBL_RESULT(result, atom.d); break; case PM_TYPE_STRING: SET_STR_RESULT(result, strdup(atom.cp)); break; default: SET_MSG_RESULT(result, strdup("Unsupported metric value type.")); return SYSINFO_RET_FAIL; break; } /* Success. */ return SYSINFO_RET_OK; }
int main(int argc, char **argv) { int sts; int n; int c; int i; char *p; char *source; char *namelist[1]; pmID pmidlist[1]; pmResult *result; char **instnames = NULL; int numinst = 0; int force = 0; pmDesc desc; pmAtomValue nav; pmValueSet *vsp; char *subopt; while ((c = pmGetOptions(argc, argv, &opts)) != EOF) { switch (c) { case 'f': force++; break; case 'i': /* list of instances */ #define WHITESPACE ", \t\n" subopt = strtok(opts.optarg, WHITESPACE); while (subopt != NULL) { numinst++; n = numinst * sizeof(char *); instnames = (char **)realloc(instnames, n); if (instnames == NULL) __pmNoMem("pmstore.instnames", n, PM_FATAL_ERR); instnames[numinst-1] = subopt; subopt = strtok(NULL, WHITESPACE); } #undef WHITESPACE break; default: opts.errors++; break; } } if (opts.errors || opts.optind != argc - 2) { pmUsageMessage(&opts); exit(1); } if (opts.context == PM_CONTEXT_HOST) source = opts.hosts[0]; else if (opts.context == PM_CONTEXT_LOCAL) source = NULL; else { opts.context = PM_CONTEXT_HOST; source = "local:"; } if ((sts = pmNewContext(opts.context, source)) < 0) { if (opts.context == PM_CONTEXT_LOCAL) fprintf(stderr, "%s: Cannot make standalone local connection: %s\n", pmProgname, pmErrStr(sts)); else fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, source, pmErrStr(sts)); exit(1); } namelist[0] = argv[opts.optind++]; if ((n = pmLookupName(1, namelist, pmidlist)) < 0) { printf("%s: pmLookupName: %s\n", namelist[0], pmErrStr(n)); exit(1); } if (pmidlist[0] == PM_ID_NULL) { printf("%s: unknown metric\n", namelist[0]); exit(1); } if ((n = pmLookupDesc(pmidlist[0], &desc)) < 0) { printf("%s: pmLookupDesc: %s\n", namelist[0], pmErrStr(n)); exit(1); } if (desc.type == PM_TYPE_AGGREGATE || desc.type == PM_TYPE_AGGREGATE_STATIC) { fprintf(stderr, "%s: Cannot modify values for PM_TYPE_AGGREGATE metrics\n", pmProgname); exit(1); } if (desc.type == PM_TYPE_EVENT || desc.type == PM_TYPE_HIGHRES_EVENT) { fprintf(stderr, "%s: Cannot modify values for event type metrics\n", pmProgname); exit(1); } if (instnames != NULL) { pmDelProfile(desc.indom, 0, NULL); for (i = 0; i < numinst; i++) { if ((n = pmLookupInDom(desc.indom, instnames[i])) < 0) { printf("pmLookupInDom %s[%s]: %s\n", namelist[0], instnames[i], pmErrStr(n)); exit(1); } if ((sts = pmAddProfile(desc.indom, 1, &n)) < 0) { printf("pmAddProfile %s[%s]: %s\n", namelist[0], instnames[i], pmErrStr(sts)); exit(1); } } } if ((n = pmFetch(1, pmidlist, &result)) < 0) { printf("%s: pmFetch: %s\n", namelist[0], pmErrStr(n)); exit(1); } /* value is argv[opts.optind] */ mkAtom(&nav, desc.type, argv[opts.optind]); vsp = result->vset[0]; if (vsp->numval < 0) { printf("%s: Error: %s\n", namelist[0], pmErrStr(vsp->numval)); exit(1); } if (vsp->numval == 0) { if (!force) { printf("%s: No value(s) available!\n", namelist[0]); exit(1); } else { pmAtomValue tmpav; mkAtom(&tmpav, PM_TYPE_STRING, "(none)"); vsp->numval = 1; vsp->valfmt = __pmStuffValue(&tmpav, &vsp->vlist[0], PM_TYPE_STRING); } } for (i = 0; i < vsp->numval; i++) { pmValue *vp = &vsp->vlist[i]; printf("%s", namelist[0]); if (desc.indom != PM_INDOM_NULL) { if ((n = pmNameInDom(desc.indom, vp->inst, &p)) < 0) printf(" inst [%d]", vp->inst); else { printf(" inst [%d or \"%s\"]", vp->inst, p); free(p); } } printf(" old value="); pmPrintValue(stdout, vsp->valfmt, desc.type, vp, 1); vsp->valfmt = __pmStuffValue(&nav, &vsp->vlist[i], desc.type); printf(" new value="); pmPrintValue(stdout, vsp->valfmt, desc.type, vp, 1); putchar('\n'); } if ((n = pmStore(result)) < 0) { printf("%s: pmStore: %s\n", namelist[0], pmErrStr(n)); exit(1); } pmFreeResult(result); exit(0); }