int pmFetchArchive(pmResult **result) { int n; __pmContext *ctxp; int ctxp_mode; if ((n = pmWhichContext()) >= 0) { ctxp = __pmHandleToPtr(n); if (ctxp == NULL) n = PM_ERR_NOCONTEXT; else { ctxp_mode = (ctxp->c_mode & __PM_MODE_MASK); if (ctxp->c_type != PM_CONTEXT_ARCHIVE) n = PM_ERR_NOTARCHIVE; else if (ctxp_mode == PM_MODE_INTERP) /* makes no sense! */ n = PM_ERR_MODE; else { /* assume PM_CONTEXT_ARCHIVE and BACK or FORW */ n = __pmLogFetch(ctxp, 0, NULL, result); if (n >= 0) { ctxp->c_origin.tv_sec = (__int32_t)(*result)->timestamp.tv_sec; ctxp->c_origin.tv_usec = (__int32_t)(*result)->timestamp.tv_usec; } } PM_UNLOCK(ctxp->c_lock); } } return n; }
void disconnect(int sts) { time_t now; #if CAN_RECONNECT int ctx; __pmContext *ctxp; #endif time(&now); if (sts != 0) fprintf(stderr, "%s: Error: %s\n", pmProgname, pmErrStr(sts)); fprintf(stderr, "%s: Lost connection to PMCD on \"%s\" at %s", pmProgname, pmcd_host, ctime(&now)); #if CAN_RECONNECT if (primary) { fprintf(stderr, "This is fatal for the primary logger."); exit(1); } close(pmcdfd); __pmFD_CLR(pmcdfd, &fds); pmcdfd = -1; numfds = maxfd() + 1; if ((ctx = pmWhichContext()) >= 0) ctxp = __pmHandleToPtr(ctx); if (ctx < 0 || ctxp == NULL) { fprintf(stderr, "%s: disconnect botch: cannot get context: %s\n", pmProgname, pmErrStr(ctx)); exit(1); } ctxp->c_pmcd->pc_fd = -1; PM_UNLOCK(ctxp->c_lock); #else exit(1); #endif }
/* Initialize API and fill in internal description for given Context. */ static void initapi(Context *x) { int e; x->handle = pmWhichContext(); if ((e = pmLookupName(1, &(x->metric), &(x->pmid))) < 0) { fprintf(stderr, "%s: pmLookupName(%s): %s\n", pmProgname, x->metric, pmErrStr(e)); exit(EXIT_FAILURE); } if ((e = pmLookupDesc(x->pmid, &(x->desc))) < 0) { fprintf(stderr, "%s: pmLookupDesc: %s\n", pmProgname, pmErrStr(e)); exit(EXIT_FAILURE); } if (x->desc.sem == PM_SEM_COUNTER) { if (x->desc.units.dimTime == 0) x->scale = 1.0; else { if (x->desc.units.scaleTime > PM_TIME_SEC) x->scale = pow(60, (PM_TIME_SEC - x->desc.units.scaleTime)); else x->scale = pow(1000, (PM_TIME_SEC - x->desc.units.scaleTime)); } } }
int reconnect(void) { int sts; int ctx; __pmContext *ctxp; if ((ctx = pmWhichContext()) >= 0) ctxp = __pmHandleToPtr(ctx); if (ctx < 0 || ctxp == NULL) { fprintf(stderr, "%s: reconnect botch: cannot get context: %s\n", pmProgname, pmErrStr(ctx)); exit(1); } sts = pmReconnectContext(ctx); if (sts >= 0) { time_t now; time(&now); fprintf(stderr, "%s: re-established connection to PMCD on \"%s\" at %s\n", pmProgname, pmcd_host, ctime(&now)); pmcdfd = ctxp->c_pmcd->pc_fd; __pmFD_SET(pmcdfd, &fds); numfds = maxfd() + 1; } PM_UNLOCK(ctxp->c_lock); return sts; }
void disconnect(int sts) { time_t now; int ctx; __pmContext *ctxp; time(&now); if (sts != 0) fprintf(stderr, "%s: Error: %s\n", pmProgname, pmErrStr(sts)); fprintf(stderr, "%s: Lost connection to PMCD on \"%s\" at %s", pmProgname, pmcd_host, ctime(&now)); if (pmcdfd != -1) { close(pmcdfd); __pmFD_CLR(pmcdfd, &fds); pmcdfd = -1; } numfds = maxfd() + 1; if ((ctx = pmWhichContext()) >= 0) ctxp = __pmHandleToPtr(ctx); if (ctx < 0 || ctxp == NULL) { fprintf(stderr, "%s: disconnect botch: cannot get context: %s\n", pmProgname, pmErrStr(ctx)); exit(1); } ctxp->c_pmcd->pc_fd = -1; PM_UNLOCK(ctxp->c_lock); }
static void EndLocalContext(void) { int i; __pmDSO *dp; int ctx = pmWhichContext(); if (PM_MULTIPLE_THREADS(PM_SCOPE_DSO_PMDA)) /* * Local context requires single-threaded applications * ... should not really get here, so do nothing! */ return; for (i = 0; i < numdso; i++) { dp = &dsotab[i]; if (dp->domain != -1 && dp->dispatch.comm.pmda_interface >= PMDA_INTERFACE_5 && dp->dispatch.version.four.ext->e_endCallBack != NULL) { #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_CONTEXT) { fprintf(stderr, "NotifyEndLocalContext: DSO PMDA %s (%d) notified of context %d close\n", dp->name, dp->domain, ctx); } #endif (*(dp->dispatch.version.four.ext->e_endCallBack))(ctx); } } }
int reconnect(void) { int sts; int ctx; time_t now; __pmContext *ctxp; if ((ctx = pmWhichContext()) >= 0) ctxp = __pmHandleToPtr(ctx); if (ctx < 0 || ctxp == NULL) { fprintf(stderr, "%s: reconnect botch: cannot get context: %s\n", pmProgname, pmErrStr(ctx)); exit(1); } sts = pmReconnectContext(ctx); if (sts >= 0) { pmcdfd = ctxp->c_pmcd->pc_fd; __pmFD_SET(pmcdfd, &fds); numfds = maxfd() + 1; } PM_UNLOCK(ctxp->c_lock); if (sts < 0) return sts; time(&now); fprintf(stderr, "%s: re-established connection to PMCD on \"%s\" at %s", pmProgname, pmcd_host, ctime(&now)); /* * Metrics may have changed while PMCD was unreachable, so we * need to recheck each metric to make sure that its PMID and * semantics have not changed. We cannot recover if there is * an incompatible change - must defer to controlling scripts * or processes (a new-named archive will have to be created, * from a new pmlogger process, and pmlogrewrite/pmlogextract * will need to become involved if they need to be merged). */ validate_metrics(); /* * All metrics have been validated, however, this state change * represents a potential gap in the stream of metrics. So we * must store a <mark> record at this point. */ if ((sts = putmark()) < 0) { fprintf(stderr, "putmark: %s\n", pmErrStr(sts)); exit(1); } return 0; }
int pmSetMode(int mode, const struct timeval *when, int delta) { int n; __pmContext *ctxp; int l_mode = (mode & __PM_MODE_MASK); if ((n = pmWhichContext()) >= 0) { ctxp = __pmHandleToPtr(n); if (ctxp == NULL) return PM_ERR_NOCONTEXT; if (ctxp->c_type == PM_CONTEXT_HOST) { if (l_mode != PM_MODE_LIVE) n = PM_ERR_MODE; else { ctxp->c_origin.tv_sec = ctxp->c_origin.tv_usec = 0; ctxp->c_mode = mode; ctxp->c_delta = delta; n = 0; } } else if (ctxp->c_type == PM_CONTEXT_LOCAL) { n = PM_ERR_MODE; } else { /* assume PM_CONTEXT_ARCHIVE */ if (l_mode == PM_MODE_INTERP || l_mode == PM_MODE_FORW || l_mode == PM_MODE_BACK) { if (when != NULL) { /* * special case of NULL for timestamp * => do not update notion of "current" time */ ctxp->c_origin.tv_sec = (__int32_t)when->tv_sec; ctxp->c_origin.tv_usec = (__int32_t)when->tv_usec; } ctxp->c_mode = mode; ctxp->c_delta = delta; __pmLogSetTime(ctxp); __pmLogResetInterp(ctxp); n = 0; } else n = PM_ERR_MODE; } PM_UNLOCK(ctxp->c_lock); } return n; }
/* Initialize API and fill in internal description for given Context. */ static void initapi(Context *x, pmMetricSpec *msp, int argc, char **argv) { int e; x->metric = msp->metric; if (msp->ninst > 0) { x->inum = msp->ninst; x->iall = (x->inum == 0); x->inames = &msp->inst[0]; } x->handle = pmWhichContext(); if ((e = pmLookupName(1, &(x->metric), &(x->pmid))) < 0) { fprintf(stderr, "%s: pmLookupName(%s): %s\n", pmProgname, x->metric, pmErrStr(e)); exit(EXIT_FAILURE); } if ((e = pmLookupDesc(x->pmid, &(x->desc))) < 0) { fprintf(stderr, "%s: pmLookupDesc: %s\n", pmProgname, pmErrStr(e)); exit(EXIT_FAILURE); } if (x->desc.indom == PM_INDOM_NULL && msp->ninst > 0) { fprintf(stderr, "%s: %s: singular metrics do not have instances\n", pmProgname, msp->metric); exit(EXIT_FAILURE); } if (x->desc.type == PM_TYPE_EVENT || x->desc.type == PM_TYPE_HIGHRES_EVENT) { amode = PM_MODE_FORW; /* do no interpolate events */ rawArchive = archive; rawEvents = 1; } if (x->desc.sem == PM_SEM_COUNTER) { if (x->desc.units.dimTime == 0) x->scale = 1.0; else { if (x->desc.units.scaleTime > PM_TIME_SEC) x->scale = pow(60, (PM_TIME_SEC - x->desc.units.scaleTime)); else x->scale = pow(1000, (PM_TIME_SEC - x->desc.units.scaleTime)); } } }
/* send pmDescriptor for the given Expr as a binary PDU */ static void sendDesc(Expr *x, pmValueSet *vset) { pmDesc d; d.pmid = vset->pmid; d.indom = PM_INDOM_NULL; switch (x->sem) { case PM_SEM_COUNTER: case PM_SEM_INSTANT: case PM_SEM_DISCRETE: /* these map directly to PMAPI semantics */ d.type = PM_TYPE_DOUBLE; d.sem = x->sem; d.units = x->units; break; case SEM_NUMVAR: case SEM_NUMCONST: case SEM_BOOLEAN: /* map to a numeric value */ d.type = PM_TYPE_DOUBLE; d.sem = PM_SEM_INSTANT; d.units = x->units; break; default: fprintf(stderr, "sendDesc(%s): botch sem=%d?\n", pmIDStr(d.pmid), x->sem); /* FALLTHROUGH */ case SEM_UNKNOWN: case SEM_CHAR: case SEM_REGEX: /* no mapping is possible */ d.type = PM_TYPE_NOSUPPORT; d.sem = PM_SEM_INSTANT; d.units = noUnits; break; } __pmSendDesc(STDOUT_FILENO, pmWhichContext(), &d); }
/* * main */ int main(int argc, char **argv) { int sts; set_proc_fmt(); printf("pid=%" FMT_PID " ppid=%" FMT_PID "\n", getpid(), getppid()); getargs(argc, argv); if (pmnsfile != PM_NS_DEFAULT) { if ((sts = pmLoadNameSpace(pmnsfile)) < 0) { printf("%s: Cannot load pmnsfile from \"%s\": %s\n", pmProgname, pmnsfile, pmErrStr(sts)); exit(1); } } if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) { printf("%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, host, pmErrStr(sts)); exit(1); } test_PMNS(); test_desc(); test_instance(); test_prof_fetch(); if (!is_hotproc) test_store(); if ((sts = pmWhichContext()) < 0) { printf("%s: pmWhichContext: %s\n", pmProgname, pmErrStr(sts)); exit(1); } pmDestroyContext(sts); exit(0); }
void QmcSource::retryConnect(int type, QString &source) { int oldTZ; int oldContext; int offset; int sts; char *tzs; QString name; QString hostSpec; switch (type) { case PM_CONTEXT_LOCAL: my.desc = "Local context"; my.host = my.source = localHost; my.proxy = ""; break; case PM_CONTEXT_HOST: my.desc = "host \""; my.desc.append(source); my.desc.append(QChar('\"')); my.host = source; my.proxy = getenv("PMPROXY_HOST"); if ((offset = my.host.indexOf('?')) >= 0) { my.attrs = my.host; my.attrs.remove(0, offset+1); my.host.truncate(offset); name = my.attrs.section(QString("container="), -1); if (name != QString::null && (offset = name.indexOf(',')) > 0) name.truncate(offset); my.context_container = name; } if ((offset = my.host.indexOf('@')) >= 0) { my.proxy = my.host; my.proxy.remove(0, offset+1); } my.source = my.host; break; case PM_CONTEXT_ARCHIVE: my.desc = "archive \""; my.desc.append(source); my.desc.append(QChar('\"')); my.source = source; my.proxy = ""; break; } oldContext = pmWhichContext(); hostSpec = source; my.status = pmNewContext(type | my.flags, (const char *)hostSpec.toAscii()); if (my.status >= 0) { my.handles.append(my.status); // Fetch the server-side host name for this context, properly as of pcp 3.8.3+. my.context_hostname = pmGetContextHostName(my.status); // NB: may leak memory if (my.context_hostname == "") // may be returned for errors or PM_CONTEXT_LOCAL my.context_hostname = localHost; if (my.type == PM_CONTEXT_ARCHIVE) { pmLogLabel lp; sts = pmGetArchiveLabel(&lp); if (sts < 0) { pmprintf("%s: Unable to obtain log label for \"%s\": %s\n", pmProgname, (const char *)my.desc.toAscii(), pmErrStr(sts)); my.host = "unknown?"; my.status = sts; goto done; } else { my.host = lp.ll_hostname; my.start = lp.ll_start; } sts = pmGetArchiveEnd(&my.end); if (sts < 0) { pmprintf("%s: Unable to determine end of \"%s\": %s\n", pmProgname, (const char *)my.desc.toAscii(), pmErrStr(sts)); my.status = sts; goto done; } } else { gettimeofday(&my.start, NULL); my.end = my.start; } if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcSource::QmcSource: Created context " << my.handles.last() << " to " << my.desc << endl; } oldTZ = pmWhichZone(&tzs); my.tz = pmNewContextZone(); if (my.tz < 0) pmprintf("%s: Warning: Unable to obtain timezone for %s: %s\n", pmProgname, (const char *)my.desc.toAscii(), pmErrStr(my.tz)); else { sts = pmWhichZone(&tzs); if (sts >= 0) my.timezone = tzs; else pmprintf("%s: Warning: Unable to obtain timezone for %s: %s\n", pmProgname, (const char *)my.desc.toAscii(), pmErrStr(sts)); } if (oldTZ >= 0) { sts = pmUseZone(oldTZ); if (sts < 0) { pmprintf("%s: Warning: Unable to switch timezones." " Using timezone for %s: %s\n", pmProgname, (const char *)my.desc.toAscii(), pmErrStr(sts)); } } } else if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcSource::QmcSource: Context to " << source << " failed: " << pmErrStr(my.status) << endl; } done: sourceList.append(this); if (oldContext >= 0) { sts = pmUseContext(oldContext); if (sts < 0) { pmprintf("%s: Warning: Unable to switch contexts." " Using context to %s: %s\n", pmProgname, (const char *)my.desc.toAscii(), pmErrStr(sts)); } } }
int main(int argc, char **argv) { int c; char *p; int ctx; int sts; char *configfile = NULL; int fflag = 0; int iflag = 0; int lflag = 0; pmSetProgname(argv[0]); while ((c = pmGetOptions(argc, argv, &opts)) != EOF) { switch (c) { case 'c': /* my configfile */ if (configfile != NULL) { fprintf(stderr, "%s: at most one -c option allowed\n", pmGetProgname()); exit(EXIT_FAILURE); } configfile = opts.optarg; break; case 'f': /* my flag */ fflag++; break; case 'i': /* my instances */ iflag++; /* TODO extract instances from opts.optarg */ break; case 'l': /* my logfile */ if (lflag) { fprintf(stderr, "%s: at most one -l option allowed\n", pmGetProgname()); exit(EXIT_FAILURE); } pmOpenLog(pmGetProgname(), opts.optarg, stderr, &sts); if (sts != 1) { fprintf(stderr, "%s: Could not open logfile \"%s\"\n", pmGetProgname(), opts.optarg); exit(EXIT_FAILURE); } lflag++; break; } } if (opts.flags & PM_OPTFLAG_EXIT) { pmflush(); pmUsageMessage(&opts); exit(0); } if (opts.narchives == 1) { if ((ctx = pmNewContext(PM_CONTEXT_ARCHIVE, opts.archives[0])) < 0) { fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n", pmGetProgname(), opts.archives[0], pmErrStr(ctx)); exit(EXIT_FAILURE); } if ((sts = pmGetContextOptions(ctx, &opts)) < 0) { pmflush(); fprintf(stderr, "%s: pmGetContextOptions(%d, ...) failed: %s\n", pmGetProgname(), pmWhichContext(), pmErrStr(sts)); exit(EXIT_FAILURE); } } else if (opts.narchives > 0) { fprintf(stderr, "%s: at most one archive allowed\n", pmGetProgname()); exit(EXIT_FAILURE); } if (opts.nhosts == 1) { if ((ctx = pmNewContext(PM_CONTEXT_HOST, opts.hosts[0])) < 0) { fprintf(stderr, "%s: Cannot connect to pmcd on host \"%s\": %s\n", pmGetProgname(), opts.hosts[0], pmErrStr(ctx)); exit(EXIT_FAILURE); } } else if (opts.nhosts > 0) { fprintf(stderr, "%s: at most one host allowed\n", pmGetProgname()); exit(EXIT_FAILURE); } if (opts.errors) { pmUsageMessage(&opts); exit(EXIT_FAILURE); } if (opts.align_optarg != NULL) printf("Got -A \"%s\"\n", opts.align_optarg); if (opts.guiflag) printf("Got -g\n"); if (opts.nsflag) printf("Loaded PMNS\n"); if (opts.guiport) printf("Got -p \"%s\"\n", opts.guiport_optarg); if (opts.align_optarg != NULL || opts.start_optarg != NULL || opts.finish_optarg != NULL || opts.origin_optarg != NULL) { printf("Start time: "); pmPrintStamp(stdout, &opts.start); putchar('\n'); printf("Origin time: "); pmPrintStamp(stdout, &opts.origin); putchar('\n'); printf("Finish time: "); pmPrintStamp(stdout, &opts.finish); putchar('\n'); } if (sflag) printf("Got -s \"%d\"\n", opts.samples); if (opts.interval.tv_sec > 0 || opts.interval.tv_usec > 0) printf("Got -t %d.%06d (secs)\n", (int)opts.interval.tv_sec, (int)opts.interval.tv_usec); p = getenv("PCP_CONTAINER"); if (p != NULL) printf("Got --container=\"%s\"\n", p); if (opts.timezone != NULL) printf("Got -Z \"%s\"\n", opts.timezone); if (opts.tzflag) printf("Got -z\n"); if (opts.Lflag) printf("Got -L\n"); /* non-flag args are argv[optind] ... argv[argc-1] */ while (opts.optind < argc) { printf("extra argument[%d]: %s\n", opts.optind, argv[opts.optind]); opts.optind++; } while (!sflag || opts.samples-- > 0) { /* put real stuff here */ break; } return 0; }
int main(int argc, char *argv[]) { int c; int sts; int ctx; int i; int lflag = 0; /* no label by default */ int nfile; int n; char *p; struct dirent **namelist; __pmContext *ctxp; char *archpathname; /* from the command line */ char *archdirname; /* after dirname() */ char archname[MAXPATHLEN]; /* full pathname to base of archive name */ while ((c = pmGetOptions(argc, argv, &opts)) != EOF) { switch (c) { case 'l': /* display the archive label */ lflag = 1; break; case 'v': /* bump verbosity */ vflag++; break; } } if (!opts.errors && opts.optind >= argc) { pmprintf("Error: no archive specified\n\n"); opts.errors++; } if (opts.errors) { pmUsageMessage(&opts); exit(EXIT_FAILURE); } sep = __pmPathSeparator(); setlinebuf(stderr); __pmAddOptArchive(&opts, argv[opts.optind]); opts.flags &= ~PM_OPTFLAG_DONE; __pmEndOptions(&opts); archpathname = argv[opts.optind]; archbasename = strdup(basename(strdup(archpathname))); /* * treat foo, foo.index, foo.meta, foo.NNN as all equivalent * to "foo" */ p = strrchr(archbasename, '.'); if (p != NULL) { if (strcmp(p, ".index") == 0 || strcmp(p, ".meta") == 0) *p = '\0'; else { char *q = p; q++; if (isdigit(*q)) { /* * foo.<digit> ... if archpathname does exist, then * safe to strip digits, else leave as is for the * case of, e.g. archive-20150415.041154 which is the * pmmgr basename for an archive with a first volume * named archive-20150415.041154.0 */ if (access(archpathname, F_OK) == 0) { q++; while (*q && isdigit(*q)) q++; if (*q == '\0') *p = '\0'; } } } } archdirname = dirname(strdup(archpathname)); if (vflag) fprintf(stderr, "Scanning for components of archive \"%s\"\n", archpathname); nfile = scandir(archdirname, &namelist, filter, NULL); if (nfile < 1) { fprintf(stderr, "%s: no PCP archive files match \"%s\"\n", pmProgname, archpathname); exit(EXIT_FAILURE); } /* * Pass 0 for data, metadata and index files ... check physical * archive record structure, then label record */ sts = STS_OK; for (i = 0; i < nfile; i++) { char path[MAXPATHLEN]; if (strcmp(archdirname, ".") == 0) { /* skip ./ prefix */ strncpy(path, namelist[i]->d_name, sizeof(path)); } else { snprintf(path, sizeof(path), "%s%c%s", archdirname, sep, namelist[i]->d_name); } if (pass0(path) == STS_FATAL) /* unrepairable or unrepaired error */ sts = STS_FATAL; } if (meta_state == STATE_MISSING) { fprintf(stderr, "%s%c%s.meta: missing metadata file\n", archdirname, sep, archbasename); sts = STS_FATAL; } if (log_state == STATE_MISSING) { fprintf(stderr, "%s%c%s.0 (or similar): missing log file \n", archdirname, sep, archbasename); sts = STS_FATAL; } if (sts == STS_FATAL) { if (vflag) fprintf(stderr, "Due to earlier errors, cannot continue ... bye\n"); exit(EXIT_FAILURE); } if ((sts = ctx = pmNewContext(PM_CONTEXT_ARCHIVE, archpathname)) < 0) { fprintf(stderr, "%s: cannot open archive \"%s\": %s\n", pmProgname, archpathname, pmErrStr(sts)); fprintf(stderr, "Checking abandoned.\n"); exit(EXIT_FAILURE); } if (pmGetContextOptions(ctx, &opts) < 0) { pmflush(); /* runtime errors only at this stage */ exit(EXIT_FAILURE); } if (lflag) dumpLabel(); /* * Note: ctxp->c_lock remains locked throughout ... __pmHandleToPtr() * is only called once, and a single context is used throughout * ... so there is no PM_UNLOCK(ctxp->c_lock) anywhere in the * pmchecklog code. * This works because ctxp->c_lock is a recursive lock and * pmchecklog is single-threaded. */ if ((n = pmWhichContext()) >= 0) { if ((ctxp = __pmHandleToPtr(n)) == NULL) { fprintf(stderr, "%s: botch: __pmHandleToPtr(%d) returns NULL!\n", pmProgname, n); exit(EXIT_FAILURE); } } else { fprintf(stderr, "%s: botch: %s!\n", pmProgname, pmErrStr(PM_ERR_NOCONTEXT)); exit(EXIT_FAILURE); } if (strcmp(archdirname, ".") == 0) /* skip ./ prefix */ strncpy(archname, archbasename, sizeof(archname) - 1); else snprintf(archname, sizeof(archname), "%s%c%s", archdirname, sep, archbasename); sts = pass1(ctxp, archname); if (index_state == STATE_BAD) { /* prevent subsequent use of bad temporal index */ ctxp->c_archctl->ac_log->l_numti = 0; } sts = pass2(ctxp, archname); sts = pass3(ctxp, archname, &opts); if (vflag) { if (result_count > 0) fprintf(stderr, "Processed %d pmResult records\n", result_count); if (mark_count > 0) fprintf(stderr, "Processed %d <mark> records\n", mark_count); } return 0; }
/* 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; }
/* evaluate Task */ static void eval(Task *task) { Symbol *s; pmValueSet *vset; int i; /* fetch metrics */ taskFetch(task); /* evaluate rule expressions */ s = task->rules; for (i = 0; i < task->nrules; i++) { curr = symValue(*s); if (curr->op < NOP) { (curr->eval)(curr); perf->eval_actual++; } s++; } if (verbose) { /* send binary values */ if (agent) { int sts; s = task->rules; for (i = 0; i < task->nrules; i++) { vset = task->rslt->vset[i]; fillVSet(symValue(*s), vset); s++; } __pmOverrideLastFd(PDU_OVERRIDE2); sts = __pmSendResult(STDOUT_FILENO, pmWhichContext(), task->rslt); if (sts < 0) { fprintf(stderr, "Error: __pmSendResult to summary agent failed: %s\n", pmErrStr(sts)); exit(0); } } /* send values to applet */ else if (applet) { s = task->rules; for (i = 0; i < task->nrules; i++) { showValue(stdout, symValue(*s)); putchar(' '); s++; } putchar('\n'); } /* print values in ASCII */ else { s = task->rules; for (i = 0; i < task->nrules; i++) { printf("%s", symName(*s)); if (archives || showTimeFlag) { printf(" ("); showTime(stdout, now); putchar(')'); } printf(": "); switch (verbose) { case 1: showValue(stdout, symValue(*s)); break; case 2: showAnnotatedValue(stdout, symValue(*s)); break; case 3: showSatisfyingValue(stdout, symValue(*s)); break; } putchar('\n'); s++; } putchar('\n'); } } }
int pmFetch(int numpmid, pmID pmidlist[], pmResult **result) { int n; if (numpmid < 1) { n = PM_ERR_TOOSMALL; goto done; } if ((n = pmWhichContext()) >= 0) { __pmContext *ctxp = __pmHandleToPtr(n); int newcnt; pmID *newlist = NULL; int have_dm; if (ctxp == NULL) { n = PM_ERR_NOCONTEXT; goto done; } if (ctxp->c_type == PM_CONTEXT_LOCAL && PM_MULTIPLE_THREADS(PM_SCOPE_DSO_PMDA)) { /* Local context requires single-threaded applications */ n = PM_ERR_THREAD; PM_UNLOCK(ctxp->c_lock); goto done; } /* for derived metrics, may need to rewrite the pmidlist */ have_dm = newcnt = __pmPrepareFetch(ctxp, numpmid, pmidlist, &newlist); if (newcnt > numpmid) { /* replace args passed into pmFetch */ numpmid = newcnt; pmidlist = newlist; } if (ctxp->c_type == PM_CONTEXT_HOST) { /* * Thread-safe note * * Need to be careful here, because the PMCD changed protocol * may mean several PDUs are returned, but __pmDecodeResult() * may request more info from PMCD if pmDebug is set. * * So unlock ctxp->c_pmcd->pc_lock as soon as possible. */ PM_LOCK(ctxp->c_pmcd->pc_lock); if ((n = request_fetch(n, ctxp, numpmid, pmidlist)) >= 0) { int changed = 0; do { __pmPDU *pb; int pinpdu; pinpdu = n = __pmGetPDU(ctxp->c_pmcd->pc_fd, ANY_SIZE, ctxp->c_pmcd->pc_tout_sec, &pb); if (n == PDU_RESULT) { PM_UNLOCK(ctxp->c_pmcd->pc_lock); n = __pmDecodeResult(pb, result); } else if (n == PDU_ERROR) { __pmDecodeError(pb, &n); if (n > 0) /* PMCD state change protocol */ changed = n; else PM_UNLOCK(ctxp->c_pmcd->pc_lock); } else { PM_UNLOCK(ctxp->c_pmcd->pc_lock); if (n != PM_ERR_TIMEOUT) n = PM_ERR_IPC; } if (pinpdu > 0) __pmUnpinPDUBuf(pb); } while (n > 0); if (n == 0) n |= changed; } else PM_UNLOCK(ctxp->c_pmcd->pc_lock); } else if (ctxp->c_type == PM_CONTEXT_LOCAL) { n = __pmFetchLocal(ctxp, numpmid, pmidlist, result); } else { /* assume PM_CONTEXT_ARCHIVE */ n = __pmLogFetch(ctxp, numpmid, pmidlist, result); if (n >= 0 && (ctxp->c_mode & __PM_MODE_MASK) != PM_MODE_INTERP) { ctxp->c_origin.tv_sec = (__int32_t)(*result)->timestamp.tv_sec; ctxp->c_origin.tv_usec = (__int32_t)(*result)->timestamp.tv_usec; } } /* process derived metrics, if any */ if (have_dm) { __pmFinishResult(ctxp, n, result); if (newlist != NULL) free(newlist); } PM_UNLOCK(ctxp->c_lock); } done: #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_FETCH) { fprintf(stderr, "pmFetch returns ...\n"); if (n > 0) { fprintf(stderr, "PMCD state changes: agent(s)"); if (n & PMCD_ADD_AGENT) fprintf(stderr, " added"); if (n & PMCD_RESTART_AGENT) fprintf(stderr, " restarted"); if (n & PMCD_DROP_AGENT) fprintf(stderr, " dropped"); fputc('\n', stderr); } if (n >= 0) __pmDumpResult(stderr, *result); else { char errmsg[PM_MAXERRMSGLEN]; fprintf(stderr, "Error: %s\n", pmErrStr_r(n, errmsg, sizeof(errmsg))); } } #endif return n; }
/* * 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"); }