static void * func2(void *arg) { char *fn = "func2"; int i; int j; int sts; FILE *f; if ((f = fopen("/tmp/func2.out", "w")) == NULL) { perror("func2 fopen"); pthread_exit("botch"); } j = pmUseContext(ctx2); if ( j < 0) { fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx2, pmErrStr(j)); fclose(f); pthread_exit("botch"); } pthread_barrier_wait(&barrier); for (j = 0; j < 100; j++) { for (i = NMETRIC-1; i >= 0; i--) { if (ctx2 != ctx1) { /* * limit pmcd.control.register [1] in context 2 * - select 5 instances below */ int instlist[] = { 0, 1, 2, 4, 8 }; pthread_mutex_lock(&mymutex); if ((sts = pmDelProfile(desclist[1].indom, 0, NULL)) < 0) { fprintf(f, "Error: pmDelProfile(%s) -> %s\n", namelist[1], pmErrStr(sts)); fclose(f); pthread_exit("botch"); } if ((sts = pmAddProfile(desclist[1].indom, sizeof(instlist)/sizeof(instlist[0]), instlist)) < 0) { fprintf(f, "Error: pmAddProfile(%s) -> %s\n", namelist[1], pmErrStr(sts)); fclose(f); pthread_exit("botch"); } } foo(f, fn, i); if (ctx2 != ctx1) pthread_mutex_unlock(&mymutex); } } fclose(f); pthread_exit(NULL); }
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; }
/* * Tests 4. and 5. * Set up an explicit profile of ourself and our parent * If any of the metrics are not in the proc indom, we'll get no values back. * Checks if profile is being handled correctly. * Checks if fetch is using profile correctly. */ void test_prof_fetch(void) { int sts; int i; int pids[2]; pmResult *result1, *result2; print_banner_start("profile/fetch"); pids[0] = (int)getpid(); pids[1] = (int)getppid(); pmDelProfile(indom, 0, NULL); pmAddProfile(indom, 2, pids); printf("\n--- Check profile in context dump... ---\n"); if ((sts = pmWhichContext()) < 0) { printf("%s: pmWhichContext: %s\n", pmProgname, pmErrStr(sts)); exit(1); } __pmDumpContext(stdout, sts, PM_INDOM_NULL); printf("--- End Check profile in context dump... ---\n"); printf("\n--- Fetch Over Restricted Instance Domain ... ---\n"); for (i=0; i < iterations; i++) { int j,k; sts = pmFetch(nmetrics, pmids, &result1); if (sts < 0) { printf("%s: iteration %d : %s\n", pmProgname, i, pmErrStr(sts)); exit(1); } __pmDumpResult(stdout, result1); for (j = 0; j < result1->numpmid; j++) { pmValueSet *set = result1->vset[j]; if (set->numval != 2) { printf("%s: Error: num of inst == %d\n", pmProgname, set->numval); } for (k = 0; k < set->numval; k++) { pmValue *val = &set->vlist[k]; if (val->inst != pids[0] && val->inst != pids[1]) { printf("%s: Error: inst ids do not match pids\n", pmProgname); exit(1); } } } pmFreeResult(result1); } printf("--- End Fetch Over Restricted Instance Domain ... ---\n"); printf("\n--- Fetch Over Entire Instance Domain ... ---\n"); if (indom != PM_INDOM_NULL) { pmDelProfile(indom, 0, NULL); pmAddProfile(indom, all_n, all_inst); } sts = pmFetch(nmetrics, pmids, &result2); if (sts < 0) { printf("%s: fetch all %d instances : %s\n", pmProgname, all_n, pmErrStr(sts)); exit(1); } __pmDumpResult(stdout, result2); pmFreeResult(result2); printf("--- End Fetch Over Entire Instance Domain ... ---\n"); print_banner_end("profile/fetch"); }
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); }
static void * func3(void *arg) { char *fn = "func3"; int i; int j; int sts; FILE *f; if ((f = fopen("/tmp/func3.out", "w")) == NULL) { perror("func3 fopen"); pthread_exit("botch"); } j = pmUseContext(ctx3); if ( j < 0) { fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx3, pmErrStr(j)); fclose(f); pthread_exit("botch"); } pthread_barrier_wait(&barrier); for (j = 0; j < 100; j++) { for (i = 0; i < NMETRIC; i += 2) { if (ctx3 != ctx2) { /* * limit sampledso.bin [2] in context 3 * - exclude instances below, leaving 7 instances 200, ... 800 */ int instlist[] = { 100, 900 }; if ((sts = pmAddProfile(desclist[2].indom, 0, NULL)) < 0) { fprintf(f, "Error: pmAddProfile(%s) -> %s\n", namelist[2], pmErrStr(sts)); fclose(f); pthread_exit("botch"); } if ((sts = pmDelProfile(desclist[2].indom, sizeof(instlist)/sizeof(instlist[0]), instlist)) < 0) { fprintf(f, "Error: pmDelProfile(%s) -> %s\n", namelist[2], pmErrStr(sts)); fclose(f); pthread_exit("botch"); } } else { pthread_mutex_lock(&mymutex); if ((sts = pmAddProfile(desclist[1].indom, 0, NULL)) < 0) { fprintf(f, "Error: pmAddProfile(%s) -> %s\n", namelist[1], pmErrStr(sts)); fclose(f); pthread_exit("botch"); } } foo(f, fn, i); if (ctx3 == ctx2) pthread_mutex_unlock(&mymutex); } for (i = 1; i < NMETRIC; i += 2) { /* inherit instance profile from loop above */ if (ctx3 == ctx2) { pthread_mutex_lock(&mymutex); if ((sts = pmAddProfile(desclist[1].indom, 0, NULL)) < 0) { fprintf(f, "Error: pmAddProfile(%s) -> %s\n", namelist[1], pmErrStr(sts)); fclose(f); pthread_exit("botch"); } } foo(f, fn, i); if (ctx3 == ctx2) pthread_mutex_unlock(&mymutex); } } fclose(f); pthread_exit(NULL); }
/* find Profile for Metric */ static Profile * findProfile(Fetch *f, Metric *m) { Profile *p; int sts; /* find existing Profile */ p = f->profiles; while (p) { if (p->indom == m->desc.indom) { m->next = p->metrics; if (p->metrics) p->metrics->prev = m; p->metrics = m; break; } p = p->next; } /* create new Profile */ if (p == NULL) { m->next = NULL; p = newProfile(f, m->desc.indom); p->next = f->profiles; if (f->profiles) f->profiles->prev = p; f->profiles = p; p->metrics = m; } /* add instances required by Metric to Profile */ if ((sts = pmUseContext(f->handle)) < 0) { fprintf(stderr, "%s: pmUseContext failed: %s\n", pmProgname, pmErrStr(sts)); exit(1); } /* * If any rule requires all instances, then ignore restricted * instance lists from all other rules */ if (m->specinst == 0 && p->need_all == 0) { sts = pmDelProfile(p->indom, 0, (int *)0); if (sts < 0) { fprintf(stderr, "%s: pmDelProfile failed: %s\n", pmProgname, pmErrStr(sts)); exit(1); } sts = pmAddProfile(p->indom, 0, (int *)0); p->need_all = 1; } else if (m->specinst > 0 && p->need_all == 0) sts = pmAddProfile(p->indom, m->m_idom, m->iids); else sts = 0; if (sts < 0) { fprintf(stderr, "%s: pmAddProfile failed: %s\n", pmProgname, pmErrStr(sts)); exit(1); } m->profile = p; return p; }
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); }
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; }