static void dump_metric(int numnames, char **names, pmValueSet *vsp, int index, int indom, int type) { pmValue *vp = &vsp->vlist[index]; char *iname; if (index == 0) { printf(" %s (", pmIDStr(vsp->pmid)); __pmPrintMetricNames(stdout, numnames, names, " or "); printf("):"); if (vsp->numval > 1) { putchar('\n'); printf(" "); } } else printf(" "); if (indom != PM_INDOM_NULL) { printf(" inst ["); if (pmNameInDom(indom, vp->inst, &iname) < 0) printf("%d or ???]", vp->inst); else { printf("%d or \"%s\"]", vp->inst, iname); free(iname); } } printf(" value "); pmPrintValue(stdout, vsp->valfmt, type, vp, 1); putchar('\n'); }
static void newHashInst(pmValue *vp, checkData *checkdata, /* updated by this function */ int valfmt, struct timeval *timestamp, /* timestamp for this sample */ int pos) /* position of this inst in instlist */ { int sts; size_t size; pmAtomValue av; if ((sts = pmExtractValue(valfmt, vp, checkdata->desc.type, &av, PM_TYPE_DOUBLE)) < 0) { fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol); print_stamp(stderr, timestamp); fprintf(stderr, "] "); print_metric(stderr, checkdata->desc.pmid); fprintf(stderr, ": pmExtractValue failed: %s\n", pmErrStr(sts)); fprintf(stderr, "%s: possibly corrupt archive?\n", pmProgname); exit(EXIT_FAILURE); } size = (pos+1)*sizeof(instData*); checkdata->instlist = (instData**) realloc(checkdata->instlist, size); if (!checkdata->instlist) __pmNoMem("newHashInst.instlist", size, PM_FATAL_ERR); size = sizeof(instData); checkdata->instlist[pos] = (instData*) malloc(size); if (!checkdata->instlist[pos]) __pmNoMem("newHashInst.instlist[pos]", size, PM_FATAL_ERR); checkdata->instlist[pos]->inst = vp->inst; checkdata->instlist[pos]->lastval = av.d; checkdata->instlist[pos]->lasttime = *timestamp; checkdata->listsize++; #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL1) { char *name; fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol); print_stamp(stderr, timestamp); fprintf(stderr, "] "); print_metric(stderr, checkdata->desc.pmid); if (vp->inst == PM_INDOM_NULL) fprintf(stderr, ": new singular metric\n"); else { fprintf(stderr, ": new metric-instance pair "); if (pmNameInDom(checkdata->desc.indom, vp->inst, &name) < 0) fprintf(stderr, "%d\n", vp->inst); else { fprintf(stderr, "\"%s\"\n", name); free(name); } } } #endif }
/* Print event performance metric values */ void printevents(Context *x, pmValueSet *vset, int cols) { int i, sts, highres = (x->desc.type != PM_TYPE_EVENT); unsigned inst; for (i = 0; i < vset->numval; i++) { inst = (unsigned int)vset->vlist[i].inst; if (inst == PM_IN_NULL) printf("%s:", x->metric); else { int k; char *iname = NULL; if (x->inum > 0) { for (k = 0; k < x->inum; k++) { if (x->iids[k] == inst) { iname = x->inames[k]; break; } } } else { /* all instances selected */ __pmHashNode *hnp; hnp = __pmHashSearch(inst, &x->ihash); if (hnp == NULL) { if (archive) sts = pmNameInDomArchive(x->desc.indom, inst, &iname); else sts = pmNameInDom(x->desc.indom, inst, &iname); if (sts < 0) { fprintf(stderr, "%s: pmNameInDom: %s[%u]: %s\n", pmProgname, x->metric, inst, pmErrStr(sts)); exit(EXIT_FAILURE); } if ((sts = __pmHashAdd(inst, (void *)iname, &x->ihash)) < 0) { fprintf(stderr, "%s: __pmHashAdd: %s[%s (%u)]: %s\n", pmProgname, x->metric, iname, inst, pmErrStr(sts)); exit(EXIT_FAILURE); } } else iname = (char *)hnp->data; } if (iname == NULL) continue; printf("%s[%s]:", x->metric, iname); } myeventdump(vset, i, highres); } }
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 double unwrap(double current, struct timeval *curtime, checkData *checkdata, int index) { double outval = current; int wrapflag = 0; char *str = NULL; if ((current - checkdata->instlist[index]->lastval) < 0.0 && checkdata->instlist[index]->lasttime.tv_sec > 0) { switch (checkdata->desc.type) { case PM_TYPE_32: case PM_TYPE_U32: outval += (double)UINT_MAX+1; wrapflag = 1; break; case PM_TYPE_64: case PM_TYPE_U64: outval += (double)ULONGLONG_MAX+1; wrapflag = 1; break; default: wrapflag = 0; } } if (wrapflag) { fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol); print_stamp(stderr, curtime); fprintf(stderr, "]: "); print_metric(stderr, checkdata->desc.pmid); if (pmNameInDom(checkdata->desc.indom, checkdata->instlist[index]->inst, &str) < 0) fprintf(stderr, ": %s wrap", typeStr(checkdata->desc.type)); else { fprintf(stderr, "[%s]: %s wrap", str, typeStr(checkdata->desc.type)); free(str); } fprintf(stderr, "\n\tvalue %.0f at ", checkdata->instlist[index]->lastval); print_stamp(stderr, &checkdata->instlist[index]->lasttime); fprintf(stderr, "\n\tvalue %.0f at ", current); print_stamp(stderr, curtime); fputc('\n', stderr); } return outval; }
static void dump_event(int numnames, char **names, pmValueSet *vsp, int index, int indom, int type) { int r; /* event records */ int p; /* event parameters */ int flags; int nrecords; int nmissed = 0; int highres = (type == PM_TYPE_HIGHRES_EVENT); char *iname; pmValue *vp = &vsp->vlist[index]; if (index > 0) printf(" "); printf(" %s (", pmIDStr(vsp->pmid)); __pmPrintMetricNames(stdout, numnames, names, " or "); if (indom != PM_INDOM_NULL) { putchar('['); if (pmNameInDom(indom, vp->inst, &iname) < 0) printf("%d or ???])", vp->inst); else { printf("%d or \"%s\"])", vp->inst, iname); free(iname); } } else { printf(")"); } printf(": "); if (highres) { pmHighResResult **hr; if ((nrecords = pmUnpackHighResEventRecords(vsp, index, &hr)) < 0) return; if (nrecords == 0) { printf("No event records\n"); pmFreeHighResEventResult(hr); return; } setup_event_derived_metrics(); for (r = 0; r < nrecords; r++) { if (hr[r]->numpmid == 2 && hr[r]->vset[0]->pmid == pmid_flags && (hr[r]->vset[0]->vlist[0].value.lval & PM_EVENT_FLAG_MISSED) && hr[r]->vset[1]->pmid == pmid_missed) { nmissed += hr[r]->vset[1]->vlist[0].value.lval; } } dump_nrecords(nrecords, nmissed); for (r = 0; r < nrecords; r++) { printf(" --- event record [%d] timestamp ", r); __pmPrintHighResStamp(stdout, &hr[r]->timestamp); if (dump_nparams(hr[r]->numpmid) < 0) continue; flags = 0; for (p = 0; p < hr[r]->numpmid; p++) dump_parameter(hr[r]->vset[p], p, &flags); } pmFreeHighResEventResult(hr); } else { pmResult **res; if ((nrecords = pmUnpackEventRecords(vsp, index, &res)) < 0) return; if (nrecords == 0) { printf("No event records\n"); pmFreeEventResult(res); return; } setup_event_derived_metrics(); for (r = 0; r < nrecords; r++) { if (res[r]->numpmid == 2 && res[r]->vset[0]->pmid == pmid_flags && (res[r]->vset[0]->vlist[0].value.lval & PM_EVENT_FLAG_MISSED) && res[r]->vset[1]->pmid == pmid_missed) { nmissed += res[r]->vset[1]->vlist[0].value.lval; } } dump_nrecords(nrecords, nmissed); for (r = 0; r < nrecords; r++) { printf(" --- event record [%d] timestamp ", r); __pmPrintStamp(stdout, &res[r]->timestamp); if (dump_nparams(res[r]->numpmid) < 0) continue; flags = 0; for (p = 0; p < res[r]->numpmid; p++) dump_parameter(res[r]->vset[p], p, &flags); } pmFreeEventResult(res); } }
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); }
/* Return (in result) a list of active pmlogger ports on the specified machine. * The return value of the function is the number of elements in the array. * The caller must NOT free any part of the result stucture, it's storage is * managed here. Subsequent calls will overwrite the data so the caller should * copy it if persistence is required. */ int __pmLogFindPort(const char *host, int pid, __pmLogPort **lpp) { int ctx, oldctx; char *ctxhost; int sts, numval; int i, j; int findone = pid != PM_LOG_ALL_PIDS; int localcon = 0; /* > 0 for local connection */ pmDesc desc; pmResult *res; char *namelist[] = {"pmcd.pmlogger.port"}; pmID pmid; if (PM_MULTIPLE_THREADS(PM_SCOPE_LOGPORT)) return PM_ERR_THREAD; *lpp = NULL; /* pass null back in event of error */ localcon = __pmIsLocalhost(host); if (localcon > 0) /* do the work here instead of making PMCD do it */ return __pmLogFindLocalPorts(pid, lpp); else if (localcon < 0) return localcon; /* note: there may not be a current context */ ctx = 0; oldctx = pmWhichContext(); /* * Enclose ctxhost in [] in case it is an ipv6 address. This prevents * the first colon from being taken as a port separator by pmNewContext * and does no harm otherwise. */ ctxhost = malloc(strlen(host) + 2 + 1); if (ctxhost == NULL) { sts = -ENOMEM; goto ctxErr; } sprintf(ctxhost, "[%s]", host); ctx = pmNewContext(PM_CONTEXT_HOST, ctxhost); free(ctxhost); if (ctx < 0) return ctx; if ((sts = pmLookupName(1, namelist, &pmid)) < 0) goto ctxErr; if ((sts = pmLookupDesc(pmid, &desc)) < 0) goto ctxErr; if ((sts = pmFetch(1, &pmid, &res) < 0)) goto ctxErr; if ((sts = numval = res->vset[0]->numval) < 0) goto resErr; j = 0; if (numval) { if (resize_logports(findone ? 1 : numval) < 0) { sts = -oserror(); goto resErr; } /* scan the pmResult, copying matching pid(s) to logport */ for (i = j = 0; i < numval; i++) { __pmLogPort *p = &logport[j]; pmValue *vp = &res->vset[0]->vlist[i]; if (vp->inst == 1) /* old vcr instance (pseudo-init) */ continue; if (findone && vp->inst != pid) continue; p->pid = vp->inst; p->port = vp->value.lval; sts = pmNameInDom(desc.indom, p->pid, &p->name); if (sts < 0) { p->name = NULL; goto resErr; } j++; if (findone) /* found one, stop searching */ break; } *lpp = logport; } sts = j; /* the number actually added */ resErr: pmFreeResult(res); ctxErr: if (oldctx >= 0) pmUseContext(oldctx); if (ctx >= 0) pmDestroyContext(ctx); return sts; }
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; }
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); }