int QmcGroup::setArchiveMode(int mode, const struct timeval *when, int interval) { int sts, result = 0; for (unsigned int i = 0; i < numContexts(); i++) { if (my.contexts[i]->source().type() != PM_CONTEXT_ARCHIVE) continue; sts = pmUseContext(my.contexts[i]->handle()); if (sts < 0) { pmprintf("%s: Error: Unable to switch to context for %s: %s\n", pmProgname, my.contexts[i]->source().sourceAscii(), pmErrStr(sts)); result = sts; continue; } sts = pmSetMode(mode, when, interval); if (sts < 0) { pmprintf("%s: Error: Unable to set context mode for %s: %s\n", pmProgname, my.contexts[i]->source().sourceAscii(), pmErrStr(sts)); result = sts; } } sts = useContext(); if (sts < 0) result = sts; return result; }
QmcGroup::QmcGroup(bool restrictArchives) { my.restrictArchives = restrictArchives; my.mode = PM_CONTEXT_HOST; my.use = -1; my.localSource = 0; my.tzFlag = unknownTZ; my.tzDefault = -1; my.tzUser = -1; my.tzGroupIndex = 0; my.timeEndReal = 0.0; // Get timezone from environment if (tzLocalInit == false) { localHost = QmcSource::getLocalHost(); char *tz = __pmTimezone(); if (tz == NULL) pmprintf("%s: Warning: Unable to get timezone from environment\n", pmProgname); else { tzLocal = pmNewZone(tz); if (tzLocal < 0) pmprintf("%s: Warning: Timezone for localhost: %s\n", pmProgname, pmErrStr(tzLocal)); else { tzLocalString = tz; my.tzDefault = tzLocal; my.tzFlag = localTZ; } } tzLocalInit = true; } }
void __pmConfig(__pmConfigCallback formatter) { /* * Scan ${PCP_CONF-$PCP_DIR/etc/pcp.conf} and put all PCP config * variables found therein into the environment. */ FILE *fp; char confpath[32]; char dir[MAXPATHLEN]; char var[MAXPATHLEN]; char *prefix; char *conf; char *val; char *p; PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); prefix = getenv("PCP_DIR"); if ((conf = getenv("PCP_CONF")) == NULL) { strncpy(confpath, "/etc/pcp.conf", sizeof(confpath)); if (prefix == NULL) conf = __pmNativePath(confpath); else { snprintf(dir, sizeof(dir), "%s%s", prefix, __pmNativePath(confpath)); conf = dir; } } if (access((const char *)conf, R_OK) < 0 || (fp = fopen(conf, "r")) == (FILE *)NULL) { char errmsg[PM_MAXERRMSGLEN]; pmprintf("FATAL PCP ERROR: could not open config file \"%s\" : %s\n", conf, osstrerror_r(errmsg, sizeof(errmsg))); pmprintf("You may need to set PCP_CONF or PCP_DIR in your environment.\n"); pmflush(); PM_UNLOCK(__pmLock_libpcp); exit(1); } while (fgets(var, sizeof(var), fp) != NULL) { if (var[0] == '#' || (p = strchr(var, '=')) == NULL) continue; *p = '\0'; val = p+1; if ((p = strrchr(val, '\n')) != NULL) *p = '\0'; if ((p = getenv(var)) != NULL) val = p; else formatter(var, prefix, val); if (pmDebug & DBG_TRACE_CONFIG) fprintf(stderr, "pmGetConfig: (init) %s=%s\n", var, val); } fclose(fp); PM_UNLOCK(__pmLock_libpcp); }
static int traverse(const char *str, double scale) { pmMetricSpec *theMetric; char *msg; int sts = 0; sts = pmParseMetricSpec((char *)str, 0, (char *)0, &theMetric, &msg); if (sts < 0) { pmprintf("%s: Error: Unable to parse metric spec:\n%s\n", pmProgname, msg); free(msg); return sts; } // If the metric has instances, then it cannot be traversed if (theMetric->ninst) { QmcMetric *metric = group->addMetric(theMetric, scale); if (metric->status() >= 0) { checkUnits(metric); metrics.append(metric); numValues += metric->numValues(); } else sts = -1; } else { if (theMetric->isarch == 0) doMetricType = PM_CONTEXT_HOST; else if (theMetric->isarch == 1) doMetricType = PM_CONTEXT_ARCHIVE; else if (theMetric->isarch == 2) doMetricType = PM_CONTEXT_LOCAL; else { pmprintf("%s: Error: invalid metric source (%d): %s\n", pmProgname, theMetric->isarch, theMetric->metric); sts = -1; } doMetricSource = theMetric->source; if (sts >= 0) sts = group->use(doMetricType, doMetricSource); if (sts >= 0) { doMetricScale = scale; sts = pmTraversePMNS(theMetric->metric, dometric); if (sts >= 0 && doMetricFlag == false) sts = -1; else if (sts < 0) { pmprintf("%s: Error: %s: %s\n", pmProgname, theMetric->metric, pmErrStr(sts)); } } } free(theMetric); return sts; }
/* * use pmprintf for fatal messages as we're usually run from * pmLoadNameSpace() in libpcp */ static void err(char *msg) { fflush(stdout); if (currfile != NULL) { if (currfile->lineno > 0) pmprintf("pmcpp: %s[%d]: %s", currfile->fname, currfile->lineno, ibuf); else pmprintf("pmcpp: %s:\n", currfile->fname); } pmprintf("pmcpp: Error: %s\n", msg); pmflush(); exit(1); }
QmcMetric::QmcMetric(QmcGroup *group, const char *string, double scale, bool active) { pmMetricSpec *metricSpec; char *msg; my.status = 0; my.group = group; my.scale = scale; my.idIndex = UINT_MAX; my.indomIndex = UINT_MAX; my.contextIndex = UINT_MAX; my.explicitInst = false; my.active = active; my.status = pmParseMetricSpec(string, 0, NULL, &metricSpec, &msg); if (my.status < 0) { pmprintf("%s: Error: Unable to parse metric spec:\n%s\n", pmProgname, msg); my.name = QString::null; free(msg); } else { my.name = QString(metricSpec->metric); setup(group, metricSpec); free(metricSpec); } }
/* * Set the origin position and interval for PMAPI context fetching */ static int setup_origin(pmOptions *opts) { int sts = 0; curtime = origin = opts->origin; /* initial archive mode, position and delta */ if (opts->context == PM_CONTEXT_ARCHIVE) { if (opts->interval.tv_sec || opts->interval.tv_usec) interval = opts->interval; setup_step_mode(); if ((sts = pmSetMode(fetchmode, &curtime, fetchstep)) < 0) { pmprintf( "%s: pmSetMode failure: %s\n", pmProgname, pmErrStr(sts)); opts->flags |= PM_OPTFLAG_RUNTIME_ERR; opts->errors++; } } return sts; }
/* * PMAPI context creation and initial command line option handling. */ static int setup_context(pmOptions *opts) { char *source; int sts, ctx; if (opts->context == PM_CONTEXT_ARCHIVE) source = opts->archives[0]; else 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 = ctx = pmNewContext(opts->context, source)) < 0) { if (opts->context == PM_CONTEXT_HOST) pmprintf( "%s: Cannot connect to pmcd on host \"%s\": %s\n", pmProgname, source, pmErrStr(sts)); else if (opts->context == PM_CONTEXT_LOCAL) pmprintf( "%s: Cannot make standalone connection on localhost: %s\n", pmProgname, pmErrStr(sts)); else pmprintf( "%s: Cannot open archive \"%s\": %s\n", pmProgname, source, pmErrStr(sts)); } else if ((sts = pmGetContextOptions(ctx, opts)) == 0) sts = setup_origin(opts); if (sts < 0) { pmflush(); cleanstop(1); } return ctx; }
int QmcGroup::useContext() { int sts = 0; if ((context()->status() == 0) && (sts = pmUseContext(context()->handle())) < 0) pmprintf("%s: Error: Unable to reuse context to %s: %s\n", pmProgname, context()->source().sourceAscii(), pmErrStr(sts)); return sts; }
void store(char const* name, char const* inst) { char buf[128]; sprintf(buf, "pmstore %s %s > /dev/null\n", name, inst); cout << name << ' ' << inst << endl; if (system(buf) < 0) { pmprintf("%s: cannot run system(%s)\n", pmProgname, buf); pmflush(); exit(1); } }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void SceneFileObj::finishedAdd () { SoSeparator *sp; BaseObj::addBase (_root); if ((sp = readSceneFile())) { _root->addChild (sp); // To make sure the viewer will display a scene with a single // IV scenegraph treat all IV scenegraphs as "modulated" objects. ViewObj::theNumModObjects++; } else { pmprintf("Warning: Failed to read scene file \"%s\"\n", _sceneFileName); } }
void QmcGroup::createLocalContext() { if (numContexts() == 0) { QTextStream cerr(stderr); QmcSource *localSource = QmcSource::getSource(PM_CONTEXT_HOST, localHost, 0, false); if (localSource->status() < 0 && pmDebug & DBG_TRACE_PMC) cerr << "QmcGroup::createLocalContext: Default context to " << localSource->desc() << " failed: " << pmErrStr(localSource->status()) << endl; else if (pmDebug & DBG_TRACE_PMC) cerr << "QmcGroup::createLocalContext: Default context to " << localSource->desc() << endl; QmcContext *newContext = new QmcContext(localSource); if (newContext->handle() < 0) { pmprintf("%s: Error: %s: %s\n", pmProgname, (const char *)localHost.toAscii(), pmErrStr(newContext->handle())); } my.contexts.append(newContext); my.use = my.contexts.size() - 1; } }
static int mailq_histogram(char *option) { struct timeval tv; char *errmsg; char *q; int sts; q = strtok(option, ","); while (q != NULL) { if ((sts = pmParseInterval((const char *)q, &tv, &errmsg)) < 0) { pmprintf("%s: bad historgram bins argument:\n%s\n", pmProgname, errmsg); free(errmsg); return -EINVAL; } numhisto++; histo = (histo_t *)realloc(histo, numhisto * sizeof(histo[0])); if (histo == NULL) __pmNoMem("histo", numhisto * sizeof(histo[0]), PM_FATAL_ERR); histo[numhisto-1].delay = tv.tv_sec; q = strtok(NULL, ","); } return 0; }
/* Register an anonymous metric */ int __pmRegisterAnon(const char *name, int type) { char *msg; char buf[21]; /* anon(PM_TYPE_XXXXXX) */ PM_FAULT_CHECK(PM_FAULT_PMAPI); switch (type) { case PM_TYPE_32: snprintf(buf, sizeof(buf), "anon(PM_TYPE_32)"); break; case PM_TYPE_U32: snprintf(buf, sizeof(buf), "anon(PM_TYPE_U32)"); break; case PM_TYPE_64: snprintf(buf, sizeof(buf), "anon(PM_TYPE_64)"); break; case PM_TYPE_U64: snprintf(buf, sizeof(buf), "anon(PM_TYPE_U64)"); break; case PM_TYPE_FLOAT: snprintf(buf, sizeof(buf), "anon(PM_TYPE_FLOAT)"); break; case PM_TYPE_DOUBLE: snprintf(buf, sizeof(buf), "anon(PM_TYPE_DOUBLE)"); break; default: return PM_ERR_TYPE; } if ((msg = pmRegisterDerived(name, buf)) != NULL) { pmprintf("__pmRegisterAnon(%s, %d): @ \"%s\" Error: %s\n", name, type, msg, pmDerivedErrStr()); pmflush(); return PM_ERR_GENERIC; } return 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 QmcSource::dupContext() { int sts = 0; if (my.status < 0) return my.status; if (my.dupFlag == false && my.handles.size() == 1) { sts = pmUseContext(my.handles[0]); if (sts >= 0) { sts = my.handles[0]; my.dupFlag = true; if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcSource::dupContext: Using original context for " << my.desc << endl; } } else pmprintf("%s: Error: Unable to switch to context for \"%s\": %s\n", pmProgname, (const char *)my.desc.toAscii(), pmErrStr(sts)); } else if (my.handles.size()) { sts = pmUseContext(my.handles[0]); if (sts >= 0) { sts = pmDupContext(); if (sts >= 0) { my.handles.append(sts); if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcSource::dupContext: " << my.desc << " duplicated, handle[" << my.handles.size() - 1 << "] = " << sts << endl; } } else pmprintf("%s: Error: " "Unable to duplicate context to \"%s\": %s\n", pmProgname, (const char *)my.desc.toAscii(), pmErrStr(sts)); } else pmprintf("%s: Error: Unable to switch to context for \"%s\": %s\n", pmProgname, (const char *)my.desc.toAscii(), pmErrStr(sts)); } // No active contexts, create a new context else { sts = pmNewContext(my.type, sourceAscii()); if (sts >= 0) { my.handles.append(sts); if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcSource::dupContext: new context to " << my.desc << " created, handle = " << sts << endl; } } } if (sts < 0 && pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcSource::dupContext: context to " << my.desc << " failed: " << pmErrStr(my.status) << endl; } return sts; }
void QmcMetric::dumpErr(const char *inst) const { pmprintf("%s: Error: %s[%s]: %s\n", pmProgname, (const char *)spec(true).toLatin1(), inst, pmErrStr(my.status)); }
int main(int argc, char* argv[]) { int fail = 0, sts = 0; int c; char buf[MAXHOSTNAMELEN]; QString source; pmSetProgname(argv[0]); while ((c = getopt(argc, argv, "D:?")) != EOF) { switch (c) { case 'D': sts = pmSetDebug(optarg); if (sts < 0) { pmprintf("%s: unrecognized debug options specification (%s)\n", pmGetProgname(), optarg); fail = 1; } break; case '?': default: sts = 1; break; } } if (fail) { pmprintf("Usage: %s\n", pmGetProgname()); pmflush(); exit(1); } (void)gethostname(buf, MAXHOSTNAMELEN); buf[MAXHOSTNAMELEN-1] = '\0'; fprintf(stderr, "*** Simple connection ***\n"); source = QString("oview-short"); QmcSource *src1 = QmcSource::getSource(PM_CONTEXT_ARCHIVE, source, false); if (src1->status() < 0) { pmprintf("%s: Error: Unable to create context to \"%s\": %s\n", pmGetProgname(), (const char *)source.toLatin1(), pmErrStr(src1->status())); pmflush(); fail = 1; } QmcContext context1(src1); if (context1.handle() < 0) { pmflush(); fail = 1; } context1.dump(cout); pmID pmid; uint32_t indomIndex; fprintf(stderr, "\n*** Cacheing of descriptors and indoms ***\n"); QmcDesc *desc; QmcIndom *indom = NULL; sts = context1.lookupInDom("hinv.ncpu", indomIndex); if (sts < 0) { pmprintf("%s: Error: hinv.ncpu: %s\n", pmGetProgname(), pmErrStr(sts)); pmflush(); fail = 1; } else { sts = context1.lookupPMID("hinv.ncpu", pmid); if (sts < 0) { pmprintf("%s: Error: hinv.ncpu PMID: %s\n", pmGetProgname(), pmErrStr(sts)); pmflush(); fail = 1; } desc = &context1.desc(pmid); if (desc->status() < 0) { pmprintf("%s: Error: hinv.ncpu descriptor: %s\n", pmGetProgname(), pmErrStr(desc->status())); pmflush(); fail = 1; } else if (indomIndex < UINT_MAX) { pmprintf("%s: Error: hinv.ncpu indom is not NULL\n", pmGetProgname()); pmflush(); fail = 1; } } sts = context1.lookupInDom("hinv.cputype", indomIndex); if (sts < 0) { pmprintf("%s: Error: hinv.cputype: %s\n", pmGetProgname(), pmErrStr(sts)); pmflush(); fail = 1; } else { sts = context1.lookupPMID("hinv.cputype", pmid); if (sts < 0) { pmprintf("%s: Error: hinv.cputype PMID: %s\n", pmGetProgname(), pmErrStr(sts)); pmflush(); fail = 1; } desc = &context1.desc(pmid); indom = &context1.indom(indomIndex); if (desc->status() < 0) { pmprintf("%s: Error: hinv.cputype descriptor: %s\n", pmGetProgname(), pmErrStr(desc->status())); pmflush(); fail = 1; } else if (indom->status() < 0) { pmprintf("%s: Error: hinv.cputype indom: %s\n", pmGetProgname(), pmErrStr(indom->status())); pmflush(); fail = 1; } } QmcIndom *indom2; sts = context1.lookupInDom("hinv.map.cpu", indomIndex); if (sts < 0) { pmprintf("%s: Error: hinv.map.cpu: %s\n", pmGetProgname(), pmErrStr(sts)); pmflush(); fail = 1; } else { sts = context1.lookupPMID("hinv.map.cpu", pmid); if (sts < 0) { pmprintf("%s: Error: hinv.map.cpu PMID: %s\n", pmGetProgname(), pmErrStr(sts)); pmflush(); fail = 1; } desc = &context1.desc(pmid); indom2 = &context1.indom(indomIndex); if (desc->status() < 0) { pmprintf("%s: Error: hinv.map.cpu descriptor: %s\n", pmGetProgname(), pmErrStr(desc->status())); pmflush(); fail = 1; } else if (indom2->status() < 0) { pmprintf("%s: Error: hinv.map.cpu indom: %s\n", pmGetProgname(), pmErrStr(indom2->status())); pmflush(); fail = 1; } else if (indom != indom2) { pmprintf("%s: Error: hinv.cputype and hinv.map.cpu indoms are not the same\n", pmGetProgname()); pmflush(); fail = 1; } } sts = context1.lookupInDom("hinv.ncpu", indomIndex); if (sts < 0) { pmprintf("%s: Error: hinv.ncpu: %s\n", pmGetProgname(), pmErrStr(sts)); pmflush(); fail = 1; } else { sts = context1.lookupPMID("hinv.ncpu", pmid); if (sts < 0) { pmprintf("%s: Error: hinv.ncpu PMID: %s\n", pmGetProgname(), pmErrStr(sts)); pmflush(); fail = 1; } desc = &context1.desc(pmid); if (desc->status() < 0) { pmprintf("%s: Error: hinv.ncpu descriptor: %s\n", pmGetProgname(), pmErrStr(desc->status())); pmflush(); fail = 1; } else if (indomIndex < UINT_MAX) { pmprintf("%s: Error: hinv.ncpu indom is not NULL\n", pmGetProgname()); pmflush(); fail = 1; } } context1.dump(cout); fprintf(stderr, "\n*** Bad Context ***\n"); source = QString("no-such-host"); QmcSource *src2 = QmcSource::getSource(PM_CONTEXT_HOST, source); if (src2->status() >= 0) { pmprintf("%s: Error: Able to create context to \"%s\": %s\n", pmGetProgname(), (const char *)source.toLatin1(), pmErrStr(src1->status())); pmflush(); fail = 1; } QmcContext context2(src2); if (context2.handle() >= 0) { pmprintf("%s: Error: Created a valid context to an invalid host\n", pmGetProgname()); fail = 1; } pmflush(); context2.dump(cout); fprintf(stderr, "\n*** Exiting ***\n"); pmflush(); return fail; }
void QmcMetric::setupDesc(QmcGroup* group, pmMetricSpec *metricSpec) { int contextType = PM_CONTEXT_HOST; int descType; char *src = NULL; char *name = NULL; if (metricSpec->isarch == 1) contextType = PM_CONTEXT_ARCHIVE; else if (metricSpec->isarch == 2) contextType = PM_CONTEXT_LOCAL; QString source = QString(metricSpec->source); my.status = group->use(contextType, source); if (my.status >= 0) { my.contextIndex = group->contextIndex(); contextType = context()->source().type(); my.status = context()->lookupPMID(metricSpec->metric, my.pmid); if (my.status >= 0) my.status = context()->lookupInDom(my.pmid, my.indomIndex); if (my.status < 0) { name = strdup(nameAscii()); src = strdup(context()->source().sourceAscii()); pmprintf("%s: Error: %s%c%s: %s\n", pmProgname, contextType == PM_CONTEXT_LOCAL ? "@" : src, contextType == PM_CONTEXT_ARCHIVE ? '/' : ':', name, pmErrStr(my.status)); } } else { // do nothing, error already reported via pmprintf from // QmcGroup::use() ; } if (my.status >= 0) { descType = desc().desc().type; if (descType == PM_TYPE_NOSUPPORT) { my.status = PM_ERR_CONV; name = strdup(nameAscii()); src = strdup(context()->source().sourceAscii()); pmprintf("%s: Error: %s%c%s is not supported on %s\n", pmProgname, contextType == PM_CONTEXT_LOCAL ? "@" : src, (contextType == PM_CONTEXT_ARCHIVE ? '/' : ':'), name, context()->source().hostAscii()); } else if (descType == PM_TYPE_AGGREGATE || descType == PM_TYPE_AGGREGATE_STATIC || descType == PM_TYPE_UNKNOWN) { my.status = PM_ERR_CONV; name = strdup(nameAscii()); src = strdup(context()->source().sourceAscii()); pmprintf("%s: Error: %s%c%s has type \"%s\"," " which is not a number or a string\n", pmProgname, contextType == PM_CONTEXT_LOCAL ? "@" : src, (contextType == PM_CONTEXT_ARCHIVE ? '/' : ':'), name, pmTypeStr(descType)); } } if (name) free(name); if (src) free(src); }
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 local 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 __pmLogFindLocalPorts(int pid, __pmLogPort **result) { char dir[MAXPATHLEN]; int lendir; int i, j, n; int nf; /* number of port files found */ struct dirent **files = NULL; /* array of port file dirents */ char *p; int len; char namebuf[MAXPATHLEN]; int (*scanfn)(const_dirent *dep); FILE *pfile; char buf[MAXPATHLEN]; if (PM_MULTIPLE_THREADS(PM_SCOPE_LOGPORT)) return PM_ERR_THREAD; if (result == NULL) return -EINVAL; if ((p = pmGetOptionalConfig("PCP_TMP_DIR")) == NULL) return PM_ERR_GENERIC; lendir = snprintf(dir, sizeof(dir), "%s%cpmlogger", p, __pmPathSeparator()); /* Set up the appropriate function to select files from the control port * directory. Anticipate that this will usually be an exact match for * the primary logger control port. */ scanfn = is_match; switch (pid) { case PM_LOG_PRIMARY_PID: /* primary logger control (single) */ strcpy(match, "primary"); break; case PM_LOG_ALL_PIDS: /* find all ports */ scanfn = is_portfile; break; default: /* a specific pid (single) */ if (!__pmProcessExists((pid_t)pid)) { #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_LOG) { fprintf(stderr, "__pmLogFindLocalPorts() -> 0, " "pid(%d) doesn't exist\n", pid); } #endif *result = NULL; return 0; } snprintf(match, sizeof(match), "%d", pid); break; } nf = scandir(dir, &files, scanfn, alphasort); #ifdef PCP_DEBUG if (nf < 1 && (pmDebug & DBG_TRACE_LOG)) { fprintf(stderr, "__pmLogFindLocalPorts: scandir() -> %d %s\n", nf, pmErrStr(oserror())); } #endif if (nf == -1 && oserror() == ENOENT) nf = 0; else if (nf == -1) { char errmsg[PM_MAXERRMSGLEN]; pmprintf("__pmLogFindLocalPorts: scandir: %s\n", osstrerror_r(errmsg, sizeof(errmsg))); pmflush(); return -oserror(); } if (resize_logports(nf) < 0) { for (i=0; i < nf; i++) free(files[i]); free(files); return -oserror(); } if (nf == 0) { #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_LOG) { fprintf(stderr, "__pmLogFindLocalPorts() -> 0, " "num files = 0\n"); } #endif *result = NULL; free(files); return 0; } /* make a buffer for the longest complete pathname found */ len = (int)strlen(files[0]->d_name); for (i = 1; i < nf; i++) if ((j = (int)strlen(files[i]->d_name)) > len) len = j; /* +1 for trailing path separator, +1 for null termination */ len += lendir + 2; /* namebuf is the complete pathname, p points to the trailing filename * within namebuf. */ strcpy(namebuf, dir); p = namebuf + lendir; *p++ = __pmPathSeparator(); /* open the file, try to read the port number and add the port to the * logport array if successful. */ for (i = 0; i < nf; i++) { char *fname = files[i]->d_name; int err = 0; __pmLogPort *lpp = &logport[nlogports]; strcpy(p, fname); if ((pfile = fopen(namebuf, "r")) == NULL) { char errmsg[PM_MAXERRMSGLEN]; pmprintf("__pmLogFindLocalPorts: pmlogger port file %s: %s\n", namebuf, osstrerror_r(errmsg, sizeof(errmsg))); free(files[i]); pmflush(); continue; } if (!err && fgets(buf, MAXPATHLEN, pfile) == NULL) { if (feof(pfile)) { clearerr(pfile); pmprintf("__pmLogFindLocalPorts: pmlogger port file %s empty!\n", namebuf); } else { char errmsg[PM_MAXERRMSGLEN]; pmprintf("__pmLogFindLocalPorts: pmlogger port file %s: %s\n", namebuf, osstrerror_r(errmsg, sizeof(errmsg))); } err = 1; } else { char *endp; lpp->port = (int)strtol(buf, &endp, 10); if (*endp != '\n') { pmprintf("__pmLogFindLocalPorts: pmlogger port file %s: no port number\n", namebuf); err = 1; } else { lpp->pid = (int)strtol(fname, &endp, 10); if (*endp != '\0') { if (strcmp(fname, "primary") == 0) lpp->pid = PM_LOG_PRIMARY_PORT; else { pmprintf("__pmLogFindLocalPorts: unrecognised pmlogger port file %s\n", namebuf); err = 1; } } } } if (err) { pmflush(); fclose(pfile); } else { if (fgets(buf, MAXPATHLEN, pfile) == NULL) { pmprintf("__pmLogFindLocalPorts: pmlogger port file %s: no PMCD host name\n", namebuf); pmflush(); } else { char *q = strchr(buf, '\n'); if (q != NULL) *q = '\0'; lpp->pmcd_host = strdup(buf); if (fgets(buf, MAXPATHLEN, pfile) == NULL) { pmprintf("__pmLogFindLocalPorts: pmlogger port file %s: no archive base pathname\n", namebuf); pmflush(); } else { char *q = strchr(buf, '\n'); if (q != NULL) *q = '\0'; lpp->archive = strdup(buf); } } fclose(pfile); if ((lpp->name = strdup(fname)) != NULL) nlogports++; else { if (lpp->pmcd_host != NULL) { free(lpp->pmcd_host); lpp->pmcd_host = NULL; } if (lpp->archive != NULL) { free(lpp->archive); lpp->archive = NULL; } break; } } free(files[i]); } if (i == nf) { /* all went well */ n = nlogports; *result = logport; } else { /* strdup error on fname, clean up */ *result = NULL; for (j = i; j < nf; j++) free(files[j]); n = -oserror(); } free(files); return n; }
int main(int argc, char **argv) { int c; int sts; int sep = __pmPathSeparator(); int use_localtime = 0; int isdaemon = 0; char *pmnsfile = PM_NS_DEFAULT; char *username; char *logfile = "pmlogger.log"; /* default log (not archive) file name */ char *endnum; int i; task_t *tp; optcost_t ocp; __pmFdSet readyfds; char *p; char *runtime = NULL; int ctx; /* handle corresponding to ctxp below */ __pmContext *ctxp; /* pmlogger has just this one context */ int niter; pid_t target_pid = 0; __pmGetUsername(&username); /* * Warning: * If any of the pmlogger options change, make sure the * corresponding changes are made to pmnewlog when pmlogger * options are passed through from the control file */ while ((c = pmgetopt_r(argc, argv, &opts)) != EOF) { switch (c) { case 'c': /* config file */ if (access(opts.optarg, F_OK) == 0) configfile = opts.optarg; else { /* does not exist as given, try the standard place */ char *sysconf = pmGetConfig("PCP_VAR_DIR"); int sz = strlen(sysconf)+strlen("/config/pmlogger/")+strlen(opts.optarg)+1; if ((configfile = (char *)malloc(sz)) == NULL) __pmNoMem("config file name", sz, PM_FATAL_ERR); snprintf(configfile, sz, "%s%c" "config%c" "pmlogger%c" "%s", sysconf, sep, sep, sep, opts.optarg); if (access(configfile, F_OK) != 0) { /* still no good, error handling happens below */ free(configfile); configfile = opts.optarg; } } break; case 'D': /* debug flag */ sts = __pmParseDebug(opts.optarg); if (sts < 0) { pmprintf("%s: unrecognized debug flag specification (%s)\n", pmProgname, opts.optarg); opts.errors++; } else pmDebug |= sts; break; case 'h': /* hostname for PMCD to contact */ pmcd_host_conn = opts.optarg; break; case 'l': /* log file name */ logfile = opts.optarg; break; case 'L': /* linger if not primary logger */ linger = 1; break; case 'm': /* note for port map file */ note = opts.optarg; isdaemon = ((strcmp(note, "pmlogger_check") == 0) || (strcmp(note, "pmlogger_daily") == 0)); break; case 'n': /* alternative name space file */ pmnsfile = opts.optarg; break; case 'p': target_pid = (int)strtol(opts.optarg, &endnum, 10); if (*endnum != '\0') { pmprintf("%s: invalid process identifier (%s)\n", pmProgname, opts.optarg); opts.errors++; } else if (!__pmProcessExists(target_pid)) { pmprintf("%s: PID error - no such process (%d)\n", pmProgname, target_pid); opts.errors++; } break; case 'P': /* this is the primary pmlogger */ primary = 1; isdaemon = 1; break; case 'r': /* report sizes of pmResult records */ rflag = 1; break; case 's': /* exit size */ sts = ParseSize(opts.optarg, &exit_samples, &exit_bytes, &exit_time); if (sts < 0) { pmprintf("%s: illegal size argument '%s' for exit size\n", pmProgname, opts.optarg); opts.errors++; } else if (exit_time.tv_sec > 0) { __pmAFregister(&exit_time, NULL, run_done_callback); } break; case 'T': /* end time */ runtime = opts.optarg; break; case 't': /* change default logging interval */ if (pmParseInterval(opts.optarg, &delta, &p) < 0) { pmprintf("%s: illegal -t argument\n%s", pmProgname, p); free(p); opts.errors++; } break; case 'U': /* run as named user */ username = opts.optarg; isdaemon = 1; break; case 'u': /* flush output buffers after each fetch */ /* * all archive write I/O is unbuffered now, so maintain -u * for backwards compatibility only */ break; case 'v': /* volume switch after given size */ sts = ParseSize(opts.optarg, &vol_switch_samples, &vol_switch_bytes, &vol_switch_time); if (sts < 0) { pmprintf("%s: illegal size argument '%s' for volume size\n", pmProgname, opts.optarg); opts.errors++; } else if (vol_switch_time.tv_sec > 0) { vol_switch_afid = __pmAFregister(&vol_switch_time, NULL, vol_switch_callback); } break; case 'V': archive_version = (int)strtol(opts.optarg, &endnum, 10); if (*endnum != '\0' || archive_version != PM_LOG_VERS02) { pmprintf("%s: -V requires a version number of %d\n", pmProgname, PM_LOG_VERS02); opts.errors++; } break; case 'x': /* recording session control fd */ rsc_fd = (int)strtol(opts.optarg, &endnum, 10); if (*endnum != '\0' || rsc_fd < 0) { pmprintf("%s: -x requires a non-negative numeric argument\n", pmProgname); opts.errors++; } else { time(&rsc_start); } break; case 'y': use_localtime = 1; break; case '?': default: opts.errors++; break; } } if (primary && pmcd_host != NULL) { pmprintf( "%s: -P and -h are mutually exclusive; use -P only when running\n" "%s on the same (local) host as the PMCD to which it connects.\n", pmProgname, pmProgname); opts.errors++; } if (!opts.errors && opts.optind != argc - 1) { pmprintf("%s: insufficient arguments\n", pmProgname); opts.errors++; } if (opts.errors) { pmUsageMessage(&opts); exit(1); } if (rsc_fd != -1 && note == NULL) { /* add default note to indicate running with -x */ static char xnote[10]; snprintf(xnote, sizeof(xnote), "-x %d", rsc_fd); note = xnote; } /* if we are running as a daemon, change user early */ if (isdaemon) __pmSetProcessIdentity(username); __pmOpenLog("pmlogger", logfile, stderr, &sts); if (sts != 1) { fprintf(stderr, "%s: Warning: log file (%s) creation failed\n", pmProgname, logfile); /* continue on ... writing to stderr */ } /* base name for archive is here ... */ archBase = argv[opts.optind]; if (pmcd_host_conn == NULL) pmcd_host_conn = "local:"; /* initialise access control */ if (__pmAccAddOp(PM_OP_LOG_ADV) < 0 || __pmAccAddOp(PM_OP_LOG_MAND) < 0 || __pmAccAddOp(PM_OP_LOG_ENQ) < 0) { fprintf(stderr, "%s: access control initialisation failed\n", pmProgname); exit(1); } if (pmnsfile != PM_NS_DEFAULT) { if ((sts = pmLoadASCIINameSpace(pmnsfile, 1)) < 0) { fprintf(stderr, "%s: Cannot load namespace from \"%s\": %s\n", pmProgname, pmnsfile, pmErrStr(sts)); exit(1); } } if ((ctx = pmNewContext(PM_CONTEXT_HOST, pmcd_host_conn)) < 0) { fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, pmcd_host_conn, pmErrStr(ctx)); exit(1); } pmcd_host = (char *)pmGetContextHostName(ctx); if (strlen(pmcd_host) == 0) { fprintf(stderr, "%s: pmGetContextHostName(%d) failed\n", pmProgname, ctx); exit(1); } if (rsc_fd == -1) { /* no -x, so register client id with pmcd */ __pmSetClientIdArgv(argc, argv); } /* * discover fd for comms channel to PMCD ... */ if ((ctxp = __pmHandleToPtr(ctx)) == NULL) { fprintf(stderr, "%s: botch: __pmHandleToPtr(%d) returns NULL!\n", pmProgname, ctx); exit(1); } pmcdfd = ctxp->c_pmcd->pc_fd; PM_UNLOCK(ctxp->c_lock); if (configfile != NULL) { if ((yyin = fopen(configfile, "r")) == NULL) { fprintf(stderr, "%s: Cannot open config file \"%s\": %s\n", pmProgname, configfile, osstrerror()); exit(1); } } else { /* **ANY** Lex would read from stdin automagically */ configfile = "<stdin>"; } __pmOptFetchGetParams(&ocp); ocp.c_scope = 1; __pmOptFetchPutParams(&ocp); /* prevent early timer events ... */ __pmAFblock(); if (yyparse() != 0) exit(1); if (configfile != NULL) fclose(yyin); yyend(); #ifdef PCP_DEBUG fprintf(stderr, "Config parsed\n"); #endif fprintf(stderr, "Starting %slogger for host \"%s\" via \"%s\"\n", primary ? "primary " : "", pmcd_host, pmcd_host_conn); #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_LOG) { fprintf(stderr, "optFetch Cost Parameters: pmid=%d indom=%d fetch=%d scope=%d\n", ocp.c_pmid, ocp.c_indom, ocp.c_fetch, ocp.c_scope); fprintf(stderr, "\nAfter loading config ...\n"); for (tp = tasklist; tp != NULL; tp = tp->t_next) { if (tp->t_numvalid == 0) continue; fprintf(stderr, " state: %sin log, %savail, %s, %s", PMLC_GET_INLOG(tp->t_state) ? "" : "not ", PMLC_GET_AVAIL(tp->t_state) ? "" : "un", PMLC_GET_MAND(tp->t_state) ? "mand" : "adv", PMLC_GET_ON(tp->t_state) ? "on" : "off"); fprintf(stderr, " delta: %ld usec", (long)1000 * tp->t_delta.tv_sec + tp->t_delta.tv_usec); fprintf(stderr, " numpmid: %d\n", tp->t_numpmid); for (i = 0; i < tp->t_numpmid; i++) { fprintf(stderr, " %s (%s):\n", pmIDStr(tp->t_pmidlist[i]), tp->t_namelist[i]); } __pmOptFetchDump(stderr, tp->t_fetch); } } #endif if (!primary && tasklist == NULL && !linger) { fprintf(stderr, "Nothing to log, and not the primary logger instance ... good-bye\n"); exit(1); } if ((sts = __pmLogCreate(pmcd_host, archBase, archive_version, &logctl)) < 0) { fprintf(stderr, "__pmLogCreate: %s\n", pmErrStr(sts)); exit(1); } else { /* * try and establish $TZ from the remote PMCD ... * Note the label record has been set up, but not written yet */ char *name = "pmcd.timezone"; pmID pmid; pmResult *resp; __pmtimevalNow(&epoch); sts = pmUseContext(ctx); if (sts >= 0) sts = pmLookupName(1, &name, &pmid); if (sts >= 0) sts = pmFetch(1, &pmid, &resp); if (sts >= 0) { if (resp->vset[0]->numval > 0) { /* pmcd.timezone present */ strcpy(logctl.l_label.ill_tz, resp->vset[0]->vlist[0].value.pval->vbuf); /* prefer to use remote time to avoid clock drift problems */ epoch = resp->timestamp; /* struct assignment */ if (! use_localtime) pmNewZone(logctl.l_label.ill_tz); } #ifdef PCP_DEBUG else if (pmDebug & DBG_TRACE_LOG) { fprintf(stderr, "main: Could not get timezone from host %s\n", pmcd_host); } #endif pmFreeResult(resp); } } /* do ParseTimeWindow stuff for -T */ if (runtime) { struct timeval res_end; /* time window end */ struct timeval start; struct timeval end; struct timeval last_delta; char *err_msg; /* parsing error message */ time_t now; struct timeval now_tv; time(&now); now_tv.tv_sec = now; now_tv.tv_usec = 0; start = now_tv; end.tv_sec = INT_MAX; end.tv_usec = INT_MAX; sts = __pmParseTime(runtime, &start, &end, &res_end, &err_msg); if (sts < 0) { fprintf(stderr, "%s: illegal -T argument\n%s", pmProgname, err_msg); exit(1); } last_delta = res_end; tsub(&last_delta, &now_tv); __pmAFregister(&last_delta, NULL, run_done_callback); last_stamp = res_end; } fprintf(stderr, "Archive basename: %s\n", archBase); #ifndef IS_MINGW /* detach yourself from the launching process */ if (isdaemon) setpgid(getpid(), 0); #endif /* set up control port */ init_ports(); __pmFD_ZERO(&fds); for (i = 0; i < CFD_NUM; ++i) { if (ctlfds[i] >= 0) __pmFD_SET(ctlfds[i], &fds); } #ifndef IS_MINGW __pmFD_SET(pmcdfd, &fds); #endif if (rsc_fd != -1) __pmFD_SET(rsc_fd, &fds); numfds = maxfd() + 1; if ((sts = do_preamble()) < 0) fprintf(stderr, "Warning: problem writing archive preamble: %s\n", pmErrStr(sts)); sts = 0; /* default exit status */ parse_done = 1; /* enable callback processing */ __pmAFunblock(); for ( ; ; ) { int nready; #ifdef PCP_DEBUG if ((pmDebug & DBG_TRACE_APPL2) && (pmDebug & DBG_TRACE_DESPERATE)) { fprintf(stderr, "before __pmSelectRead(%d,...): run_done_alarm=%d vol_switch_alarm=%d log_alarm=%d\n", numfds, run_done_alarm, vol_switch_alarm, log_alarm); } #endif niter = 0; while (log_alarm && niter++ < 10) { __pmAFblock(); log_alarm = 0; #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL2) fprintf(stderr, "delayed callback: log_alarm\n"); #endif for (tp = tasklist; tp != NULL; tp = tp->t_next) { if (tp->t_alarm) { tp->t_alarm = 0; do_work(tp); } } __pmAFunblock(); } if (vol_switch_alarm) { __pmAFblock(); vol_switch_alarm = 0; #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL2) fprintf(stderr, "delayed callback: vol_switch_alarm\n"); #endif newvolume(VOL_SW_TIME); __pmAFunblock(); } if (run_done_alarm) { #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL2) fprintf(stderr, "delayed callback: run_done_alarm\n"); #endif run_done(0, NULL); /*NOTREACHED*/ } __pmFD_COPY(&readyfds, &fds); nready = __pmSelectRead(numfds, &readyfds, NULL); #ifdef PCP_DEBUG if ((pmDebug & DBG_TRACE_APPL2) && (pmDebug & DBG_TRACE_DESPERATE)) { fprintf(stderr, "__pmSelectRead(%d,...) done: nready=%d run_done_alarm=%d vol_switch_alarm=%d log_alarm=%d\n", numfds, nready, run_done_alarm, vol_switch_alarm, log_alarm); } #endif __pmAFblock(); if (nready > 0) { /* handle request on control port */ for (i = 0; i < CFD_NUM; ++i) { if (ctlfds[i] >= 0 && __pmFD_ISSET(ctlfds[i], &readyfds)) { if (control_req(ctlfds[i])) { /* new client has connected */ __pmFD_SET(clientfd, &fds); if (clientfd >= numfds) numfds = clientfd + 1; } } } if (clientfd >= 0 && __pmFD_ISSET(clientfd, &readyfds)) { /* process request from client, save clientfd in case client * closes connection, resetting clientfd to -1 */ int fd = clientfd; if (client_req()) { /* client closed connection */ __pmFD_CLR(fd, &fds); __pmCloseSocket(clientfd); clientfd = -1; numfds = maxfd() + 1; qa_case = 0; } } #ifndef IS_MINGW if (pmcdfd >= 0 && __pmFD_ISSET(pmcdfd, &readyfds)) { /* * do not expect this, given synchronous commumication with the * pmcd ... either pmcd has terminated, or bogus PDU ... or its * Win32 and we are operating under the different conditions of * our AF.c implementation there, which has to deal with a lack * of signal support on Windows - race condition exists between * this check and the async event timer callback. */ __pmPDU *pb; __pmPDUHdr *php; sts = __pmGetPDU(pmcdfd, ANY_SIZE, TIMEOUT_NEVER, &pb); if (sts <= 0) { if (sts < 0) fprintf(stderr, "Error: __pmGetPDU: %s\n", pmErrStr(sts)); disconnect(sts); } else { php = (__pmPDUHdr *)pb; fprintf(stderr, "Error: Unsolicited %s PDU from PMCD\n", __pmPDUTypeStr(php->type)); disconnect(PM_ERR_IPC); } if (sts > 0) __pmUnpinPDUBuf(pb); } #endif if (rsc_fd >= 0 && __pmFD_ISSET(rsc_fd, &readyfds)) { /* * some action on the recording session control fd * end-of-file means launcher has quit, otherwise we * expect one of these commands * V<number>\n - version * F<folio>\n - folio name * P<name>\n - launcher's name * R\n - launcher can replay * D\n - detach from launcher * Q\n - quit pmlogger */ char rsc_buf[MAXPATHLEN]; char *rp = rsc_buf; char myc; int fake_x = 0; for (rp = rsc_buf; ; rp++) { if (read(rsc_fd, &myc, 1) <= 0) { #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL2) fprintf(stderr, "recording session control: eof\n"); #endif if (rp != rsc_buf) { *rp = '\0'; fprintf(stderr, "Error: incomplete recording session control message: \"%s\"\n", rsc_buf); } fake_x = 1; break; } if (rp >= &rsc_buf[MAXPATHLEN]) { fprintf(stderr, "Error: absurd recording session control message: \"%100.100s ...\"\n", rsc_buf); fake_x = 1; break; } if (myc == '\n') { *rp = '\0'; break; } *rp = myc; } #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL2) { if (fake_x == 0) fprintf(stderr, "recording session control: \"%s\"\n", rsc_buf); } #endif if (fake_x) do_dialog('X'); else if (strcmp(rsc_buf, "Q") == 0 || strcmp(rsc_buf, "D") == 0 || strcmp(rsc_buf, "?") == 0) do_dialog(rsc_buf[0]); else if (rsc_buf[0] == 'F') folio_name = strdup(&rsc_buf[1]); else if (rsc_buf[0] == 'P') rsc_prog = strdup(&rsc_buf[1]); else if (strcmp(rsc_buf, "R") == 0) rsc_replay = 1; else if (rsc_buf[0] == 'V' && rsc_buf[1] == '0') { /* * version 0 of the recording session control ... * this is all we grok at the moment */ ; } else { fprintf(stderr, "Error: illegal recording session control message: \"%s\"\n", rsc_buf); do_dialog('X'); } } } else if (vol_switch_flag) { newvolume(VOL_SW_SIGHUP); vol_switch_flag = 0; } else if (nready < 0 && neterror() != EINTR) fprintf(stderr, "Error: select: %s\n", netstrerror()); __pmAFunblock(); if (target_pid && !__pmProcessExists(target_pid)) exit(EXIT_SUCCESS); if (exit_code) break; } exit(exit_code); }
int main(int argc, char **argv) { int autoport = 0; QApplication a(argc, argv); setupEnvironment(); /* -a/-h ignored, back-compat for time control from libpcp_gui */ opts.short_options = "ahD:p:V?"; opts.long_options = longopts; (void)pmGetOptions(argc, argv, &opts); if (opts.errors || opts.optind != argc) { pmUsageMessage(&opts); exit(1); } if (!opts.guiport) { char *endnum, *envstr; autoport = 1; if ((envstr = getenv("PMTIME_PORT")) == NULL) { opts.guiport = PmTime::BasePort; } else { opts.guiport = strtol(envstr, &endnum, 0); if (*endnum != '\0' || opts.guiport < 0) { pmprintf( "%s: PMTIME_PORT must be a numeric port number (not %s)\n", pmProgname, envstr); pmflush(); exit(1); } } } console = new Console; TimeLord tl(&a); do { if (tl.listen(QHostAddress::LocalHost, opts.guiport)) break; opts.guiport++; } while (autoport && (opts.guiport >= 0)); if (!opts.guiport || tl.isListening() == false) { if (!autoport) pmprintf("%s: cannot find an available port\n", pmProgname); else pmprintf("%s: cannot connect to requested port (%d)\n", pmProgname, opts.guiport); pmflush(); exit(1); } else if (autoport) { /* write to stdout for client */ char name[32]; int c = snprintf(name, sizeof(name), "port=%u\n", opts.guiport); if (write(fileno(stdout), name, c + 1) < 0) { if (errno != EPIPE) { pmprintf("%s: cannot write port for client: %s\n", pmProgname, strerror(errno)); pmflush(); } exit(1); } } PmTimeLive hc; PmTimeArch ac; tl.setContext(&hc, &ac); hc.init(); if (!pmDebug) hc.disableConsole(); else hc.popup(1); ac.init(); if (!pmDebug) ac.disableConsole(); else ac.popup(1); a.exec(); return 0; }
static void ParseOptions(int argc, char *argv[], int *nports) { int c; int sts; int usage = 0; while ((c = pmgetopt_r(argc, argv, &opts)) != EOF) { switch (c) { case 'A': /* disable pmproxy service advertising */ __pmServerClearFeature(PM_SERVER_FEATURE_DISCOVERY); break; case 'C': /* path to NSS certificate database */ certdb = opts.optarg; break; case 'D': /* debug flag */ if ((sts = __pmParseDebug(opts.optarg)) < 0) { pmprintf("%s: unrecognized debug flag specification (%s)\n", pmProgname, opts.optarg); opts.errors++; } else { pmDebug |= sts; } break; case 'f': /* foreground, i.e. do _not_ run as a daemon */ run_daemon = 0; break; case 'i': /* one (of possibly several) interfaces for client requests */ __pmServerAddInterface(opts.optarg); break; case 'l': /* log file name */ logfile = opts.optarg; break; case 'L': /* Maximum size for PDUs from clients */ sts = (int)strtol(opts.optarg, NULL, 0); if (sts <= 0) { pmprintf("%s: -L requires a positive value\n", pmProgname); opts.errors++; } else { __pmSetPDUCeiling(sts); } break; case 'p': if (__pmServerAddPorts(opts.optarg) < 0) { pmprintf("%s: -p requires a positive numeric argument (%s)\n", pmProgname, opts.optarg); opts.errors++; } else { *nports += 1; } break; case 'P': /* password file for certificate database access */ dbpassfile = opts.optarg; break; case 'U': /* run as user username */ username = opts.optarg; break; case 'x': fatalfile = opts.optarg; break; case '?': usage = 1; break; default: opts.errors++; break; } } if (usage || opts.errors || opts.optind < argc) { pmUsageMessage(&opts); if (usage) exit(0); DontStart(); } }
int main(int argc, char *argv[]) { int c; int sts; char *endnum; pmDesc desc; int one_trip = 1; while ((c = pmGetOptions(argc, argv, &opts)) != EOF) { switch (c) { case 'w': /* wide flag */ line_fmt = "%.1024s"; break; case 'p': /* show flag */ if (one_trip) { show_spec = 0; one_trip = 0; } if ((sts = parse_show_spec(opts.optarg)) < 0) { pmprintf("%s: unrecognized print flag specification (%s)\n", pmProgname, opts.optarg); opts.errors++; } else { show_spec |= sts; } break; case 'm': /* top N */ top = (int)strtol(opts.optarg, &endnum, 10); if (top <= 0) { pmprintf("%s: -m requires a positive integer\n", pmProgname); opts.errors++; } break; } } if (opts.optind < argc) opts.errors++; if (opts.errors) { pmUsageMessage(&opts); exit(1); } create_namelist(); if (opts.interval.tv_sec == 0) opts.interval.tv_sec = 2; if (opts.nhosts > 0) hostname = opts.hosts[0]; else hostname = "local:"; if ((sts = c = pmNewContext(PM_CONTEXT_HOST, hostname)) < 0) { fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, hostname, pmErrStr(sts)); exit(1); } hostname = (char *)pmGetContextHostName(c); if (pmGetContextOptions(c, &opts)) { pmflush(); exit(1); } if ((sts = pmLookupName(num_pmid, namelist, pmidlist)) < 0) { fprintf(stderr, "%s: Failed to lookup metrics : %s\n", pmProgname, pmErrStr(sts)); exit(1); } for (c = 0; c < num_pmid; c++) { if ((sts = pmLookupDesc(pmidlist[c], &desc)) < 0) { fprintf(stderr, "%s: Failed to lookup descriptor for metric \"%s\": %s\n", pmProgname, namelist[c], pmErrStr(sts)); exit(1); } type_tab[c] = desc.type; /* ASSUMES that the first metric will always be a proc metric */ if (c == 0) { proc_indom = desc.indom; } } for (;;) { doit(); __pmtimevalSleep(opts.interval); } return 0; }
int __pmConnectLocal(__pmHashCtl *attrs) { int i; __pmDSO *dp; char pathbuf[MAXPATHLEN]; const char *path; #if defined(HAVE_DLOPEN) unsigned int challenge; void (*initp)(pmdaInterface *); #ifdef HAVE_ATEXIT static int atexit_installed = 0; #endif #endif if (numdso == -1) { int sts; sts = build_dsotab(); if (sts < 0) return sts; } for (i = 0; i < numdso; i++) { dp = &dsotab[i]; if (dp->domain == -1 || dp->handle != NULL) continue; /* * __pmLocalPMDA() means the path to the DSO may be something * other than relative to $PCP_PMDAS_DIR ... need to try both * options and also with and without DSO_SUFFIX (so, dll, etc) */ snprintf(pathbuf, sizeof(pathbuf), "%s%c%s", pmGetConfig("PCP_PMDAS_DIR"), __pmPathSeparator(), dp->name); if ((path = __pmFindPMDA(pathbuf)) == NULL) { snprintf(pathbuf, sizeof(pathbuf), "%s%c%s.%s", pmGetConfig("PCP_PMDAS_DIR"), __pmPathSeparator(), dp->name, DSO_SUFFIX); if ((path = __pmFindPMDA(pathbuf)) == NULL) { if ((path = __pmFindPMDA(dp->name)) == NULL) { snprintf(pathbuf, sizeof(pathbuf), "%s.%s", dp->name, DSO_SUFFIX); if ((path = __pmFindPMDA(pathbuf)) == NULL) { pmprintf("__pmConnectLocal: Warning: cannot find DSO at \"%s\" or \"%s\"\n", pathbuf, dp->name); pmflush(); dp->domain = -1; dp->handle = NULL; continue; } } } } #if defined(HAVE_DLOPEN) dp->handle = dlopen(path, RTLD_NOW); if (dp->handle == NULL) { pmprintf("__pmConnectLocal: Warning: error attaching DSO " "\"%s\"\n%s\n\n", path, dlerror()); pmflush(); dp->domain = -1; } #else /* ! HAVE_DLOPEN */ dp->handle = NULL; pmprintf("__pmConnectLocal: Warning: error attaching DSO \"%s\"\n", path); pmprintf("No dynamic DSO/DLL support on this platform\n\n"); pmflush(); dp->domain = -1; #endif if (dp->handle == NULL) continue; #if defined(HAVE_DLOPEN) /* * rest of this only makes sense if the dlopen() worked */ if (dp->init == NULL) initp = NULL; else initp = (void (*)(pmdaInterface *))dlsym(dp->handle, dp->init); if (initp == NULL) { pmprintf("__pmConnectLocal: Warning: couldn't find init function " "\"%s\" in DSO \"%s\"\n", dp->init, path); pmflush(); dlclose(dp->handle); dp->domain = -1; continue; } /* * Pass in the expected domain id. * The PMDA initialization routine can (a) ignore it, (b) check it * is the expected value, or (c) self-adapt. */ dp->dispatch.domain = dp->domain; /* * the PMDA interface / PMAPI version discovery as a "challenge" ... * for pmda_interface it is all the bits being set, * for pmapi_version it is the complement of the one you are using now */ challenge = 0xff; dp->dispatch.comm.pmda_interface = challenge; dp->dispatch.comm.pmapi_version = ~PMAPI_VERSION; dp->dispatch.comm.flags = 0; dp->dispatch.status = 0; (*initp)(&dp->dispatch); if (dp->dispatch.status != 0) { /* initialization failed for some reason */ char errmsg[PM_MAXERRMSGLEN]; pmprintf("__pmConnectLocal: Warning: initialization " "routine \"%s\" failed in DSO \"%s\": %s\n", dp->init, path, pmErrStr_r(dp->dispatch.status, errmsg, sizeof(errmsg))); pmflush(); dlclose(dp->handle); dp->domain = -1; } else { if (dp->dispatch.comm.pmda_interface < PMDA_INTERFACE_2 || dp->dispatch.comm.pmda_interface > PMDA_INTERFACE_LATEST) { pmprintf("__pmConnectLocal: Error: Unknown PMDA interface " "version %d in \"%s\" DSO\n", dp->dispatch.comm.pmda_interface, path); pmflush(); dlclose(dp->handle); dp->domain = -1; } else if (dp->dispatch.comm.pmapi_version != PMAPI_VERSION_2) { pmprintf("__pmConnectLocal: Error: Unknown PMAPI version %d " "in \"%s\" DSO\n", dp->dispatch.comm.pmapi_version, path); pmflush(); dlclose(dp->handle); dp->domain = -1; } else if (dp->dispatch.comm.pmda_interface >= PMDA_INTERFACE_6 && (dp->dispatch.comm.flags & PDU_FLAG_AUTH) != 0) { /* Agent wants to know about connection attributes */ build_dsoattrs(&dp->dispatch, attrs); } } #ifdef HAVE_ATEXIT PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); if (dp->dispatch.comm.pmda_interface >= PMDA_INTERFACE_5 && atexit_installed == 0) { /* install end of local context handler */ atexit(EndLocalContext); atexit_installed = 1; } PM_UNLOCK(__pmLock_libpcp); #endif #endif /* HAVE_DLOPEN */ } return 0; }
int main(int argc, char **argv) { int c; int sts; int samples; int pauseFlag = 0; int lines = 0; char *source; const char *host; info_t info; /* values to report each sample */ char timebuf[26]; /* for pmCtime result */ setlinebuf(stdout); while ((c = pmGetOptions(argc, argv, &opts)) != EOF) { switch (c) { case 'P': pauseFlag++; break; default: opts.errors++; break; } } if (pauseFlag && opts.context != PM_CONTEXT_ARCHIVE) { pmprintf("%s: pause can only be used with archives\n", pmProgname); opts.errors++; } if (opts.errors || opts.optind < argc - 1) { pmUsageMessage(&opts); exit(1); } if (opts.context == PM_CONTEXT_ARCHIVE) { source = opts.archives[0]; } else if (opts.context == PM_CONTEXT_HOST) { source = opts.hosts[0]; } else { opts.context = PM_CONTEXT_HOST; source = "local:"; } if ((sts = c = pmNewContext(opts.context, source)) < 0) { if (opts.context == PM_CONTEXT_HOST) fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, source, pmErrStr(sts)); else fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n", pmProgname, source, pmErrStr(sts)); exit(1); } /* complete TZ and time window option (origin) setup */ if (pmGetContextOptions(c, &opts)) { pmflush(); exit(1); } host = pmGetContextHostName(c); ncpu = get_ncpu(); if ((opts.context == PM_CONTEXT_ARCHIVE) && (opts.start.tv_sec != 0 || opts.start.tv_usec != 0)) { if ((sts = pmSetMode(PM_MODE_FORW, &opts.start, 0)) < 0) { fprintf(stderr, "%s: pmSetMode failed: %s\n", pmProgname, pmErrStr(sts)); exit(1); } } get_sample(&info); /* set a default sampling interval if none has been requested */ if (opts.interval.tv_sec == 0 && opts.interval.tv_usec == 0) opts.interval.tv_sec = 5; /* set sampling loop termination via the command line options */ samples = opts.samples ? opts.samples : -1; while (samples == -1 || samples-- > 0) { if (lines % 15 == 0) { if (opts.context == PM_CONTEXT_ARCHIVE) printf("Archive: %s, ", opts.archives[0]); printf("Host: %s, %d cpu(s), %s", host, ncpu, pmCtime((const time_t *)&info.timestamp.tv_sec, timebuf)); /* - report format CPU Busy Busy Free Mem Disk Load Average Util CPU Util (Mbytes) IOPS 1 Min 15 Min X.XXX XXX X.XXX XXXXX.XXX XXXXXX XXXX.XX XXXX.XX */ printf(" CPU"); if (ncpu > 1) printf(" Busy Busy"); printf(" Free Mem Disk Load Average\n"); printf(" Util"); if (ncpu > 1) printf(" CPU Util"); printf(" (Mbytes) IOPS 1 Min 15 Min\n"); } if (opts.context != PM_CONTEXT_ARCHIVE || pauseFlag) __pmtimevalSleep(opts.interval); get_sample(&info); printf("%5.2f", info.cpu_util); if (ncpu > 1) printf(" %3d %5.2f", info.peak_cpu, info.peak_cpu_util); printf(" %9.3f", info.freemem); printf(" %6d", info.dkiops); printf(" %7.2f %7.2f\n", info.load1, info.load15); lines++; } exit(0); }
int main(int argc, char **argv) { int c; int sts; int samples; int pauseFlag = 0; int lines = 0; char *source; const char *host; char timebuf[26]; /* for pmCtime result */ setlinebuf(stdout); while ((c = pmGetOptions(argc, argv, &opts)) != EOF) { switch (c) { case 'P': pauseFlag++; break; default: opts.errors++; break; } } if (pauseFlag && opts.context != PM_CONTEXT_ARCHIVE) { pmprintf("%s: pause can only be used with archives\n", pmGetProgname()); opts.errors++; } if (opts.errors || opts.optind < argc - 1) { pmUsageMessage(&opts); exit(1); } if (opts.context == PM_CONTEXT_ARCHIVE) { source = opts.archives[0]; } else if (opts.context == PM_CONTEXT_HOST) { source = opts.hosts[0]; } else { opts.context = PM_CONTEXT_HOST; source = "local:"; } sts = pmCreateFetchGroup(& pmfg, opts.context, source); if (sts < 0) { if (opts.context == PM_CONTEXT_HOST) fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n", pmGetProgname(), source, pmErrStr(sts)); else fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n", pmGetProgname(), source, pmErrStr(sts)); exit(1); } c = pmGetFetchGroupContext(pmfg); /* complete TZ and time window option (origin) setup */ if (pmGetContextOptions(c, &opts)) { pmflush(); exit(1); } host = pmGetContextHostName(c); /* set a default sampling interval if none has been requested */ if (opts.interval.tv_sec == 0 && opts.interval.tv_usec == 0) opts.interval.tv_sec = 5; if (opts.context == PM_CONTEXT_ARCHIVE) { if ((sts = pmSetMode(PM_MODE_INTERP, &opts.start, (int)(opts.interval.tv_sec*1000 + opts.interval.tv_usec/1000))) < 0) { fprintf(stderr, "%s: pmSetMode failed: %s\n", pmGetProgname(), pmErrStr(sts)); exit(1); } } if (opts.context == PM_CONTEXT_ARCHIVE) get_sample(); /* fetch the separate early ncpu record */ get_sample(); /* fetch other rate metrics */ /* set sampling loop termination via the command line options */ samples = opts.samples ? opts.samples : -1; while (samples == -1 || samples-- > 0) { if (lines % 15 == 0) { time_t now = info.timestamp.tv_sec; if (opts.context == PM_CONTEXT_ARCHIVE) printf("Archive: %s, ", opts.archives[0]); printf("Host: %s, %d cpu(s), %s", host, info.ncpu.l, pmCtime(&now, timebuf)); /* - report format CPU Busy Busy Free Mem Disk Load Average Util CPU Util (Mbytes) IOPS 1 Min 15 Min X.XXX XXX X.XXX XXXXX.XXX XXXXXX XXXX.XX XXXX.XX */ printf(" CPU"); if (info.ncpu.l > 1) printf(" Busy Busy"); printf(" Free Mem Disk Load Average\n"); printf(" Util"); if (info.ncpu.l > 1) printf(" CPU Util"); printf(" (Mbytes) IOPS 1 Min 15 Min\n"); } if (opts.context != PM_CONTEXT_ARCHIVE || pauseFlag) __pmtimevalSleep(opts.interval); get_sample(); printf("%5.2f", info.cpu_util); if (info.ncpu.l > 1) printf(" %3d %5.2f", info.peak_cpu, info.peak_cpu_util); printf(" %9.3f", info.freemem.d); printf(" %6d", info.dkiops.l); printf(" %7.2f %7.2f\n", info.load1.d, info.load15.d); lines++; } exit(0); }
static int parseargs(int argc, char *argv[]) { int c; int sts; char *endnum; char *msg; struct timeval interval; while ((c = pmgetopt_r(argc, argv, &opts)) != EOF) { switch (c) { case 'A': /* output time alignment */ Aarg = opts.optarg; break; case 'D': /* debug flag */ sts = __pmParseDebug(opts.optarg); if (sts < 0) { pmprintf("%s: unrecognized debug flag specification (%s)\n", pmProgname, opts.optarg); opts.errors++; } else pmDebug |= sts; break; case 's': /* number of samples to write out */ sarg = (int)strtol(opts.optarg, &endnum, 10); if (*endnum != '\0' || sarg < 0) { pmprintf("%s: -s requires numeric argument\n", pmProgname); opts.errors++; } break; case 'S': /* start time for reduction */ Sarg = opts.optarg; break; case 'T': /* end time for reduction */ Targ = opts.optarg; break; case 't': /* output sample interval */ if (pmParseInterval(opts.optarg, &interval, &msg) < 0) { pmprintf("%s", msg); free(msg); opts.errors++; } else targ = tv2double(&interval); break; case 'v': /* number of samples per volume */ varg = (int)strtol(opts.optarg, &endnum, 10); if (*endnum != '\0' || varg < 0) { pmprintf("%s: -v requires numeric argument\n", pmProgname); opts.errors++; } break; case 'Z': /* use timezone from command line */ if (zarg) { pmprintf("%s: at most one of -Z and/or -z allowed\n", pmProgname); opts.errors++; } tz = opts.optarg; break; case 'z': /* use timezone from archive */ if (tz != NULL) { pmprintf("%s: at most one of -Z and/or -z allowed\n", pmProgname); opts.errors++; } zarg++; break; case '?': default: opts.errors++; break; } } if (opts.errors == 0 && opts.optind > argc-2) { pmprintf("%s: Error: insufficient arguments\n", pmProgname); opts.errors++; } return -opts.errors; }
int QmcGroup::use(int type, const QString &theSource, int flags) { int sts = 0; unsigned int i; QString source(theSource); if (type == PM_CONTEXT_LOCAL) { for (i = 0; i < numContexts(); i++) if (my.contexts[i]->source().type() == type) break; } else if (type == PM_CONTEXT_ARCHIVE) { if (source == QString::null) { pmprintf("%s: Error: Archive context requires archive path\n", pmProgname); return PM_ERR_NOCONTEXT; } // This doesn't take into account {.N,.meta,.index,} ... but // then again, nor does pmNewContext. More work ... useful? for (i = 0; i < numContexts(); i++) { if (source == my.contexts[i]->source().source()) break; } } else { if (source == QString::null) { if (!defaultDefined()) { createLocalContext(); if (!defaultDefined()) { pmprintf("%s: Error: " "Cannot connect to PMCD on localhost: %s\n", pmProgname, pmErrStr(my.localSource->status())); return my.localSource->status(); } } source = my.contexts[0]->source().source(); } for (i = 0; i < numContexts(); i++) { if (source == my.contexts[i]->source().source()) break; } } if (i == numContexts()) { if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: No direct match for context \"" << source << "\" (type " << type << ")." << endl; } // Determine live or archive mode by the first source if (i == 0) my.mode = type; // If the assumed mode differs from the requested context type // we may need to map the host to an archive if (my.mode != type) { if (my.mode == PM_CONTEXT_HOST && type == PM_CONTEXT_ARCHIVE) { pmprintf("%s: Error: Archive \"%s\" requested " "after live mode was assumed.\n", pmProgname, (const char *)source.toAscii()); return PM_ERR_NOCONTEXT; } // If we are in archive mode, map hosts to archives of same host if (my.mode == PM_CONTEXT_ARCHIVE && type == PM_CONTEXT_HOST) { QString chop1 = source.remove(PM_LOG_MAXHOSTLEN-1, INT_MAX); for (i = 0; i < numContexts(); i++) { QString chop2 = my.contexts[i]->source().host(); chop2.remove(PM_LOG_MAXHOSTLEN-1, INT_MAX); if (chop1 == chop2) break; } if (i == numContexts()) { pmprintf("%s: Error: No archives were specified " "for host \"%s\"\n", pmProgname, (const char *)source.toAscii()); return PM_ERR_NOTARCHIVE; } } } } if (i == numContexts()) { if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: Creating new context for \"" << source << '\"' << endl; } QmcSource *src = QmcSource::getSource(type, source, flags, false); if (src == NULL) { pmprintf("%s: Error: No archives were specified for host \"%s\"\n", pmProgname, (const char *)source.toAscii()); return PM_ERR_NOTARCHIVE; } QmcContext *newContext = new QmcContext(src); if (newContext->handle() < 0) { sts = newContext->handle(); pmprintf("%s: Error: %s: %s\n", pmProgname, (const char *)source.toAscii(), pmErrStr(sts)); delete newContext; return sts; } // If we are in archive mode and are adding an archive, // make sure another archive for the same host does not exist if (my.restrictArchives && type == PM_CONTEXT_ARCHIVE) { for (i = 0; i < numContexts(); i++) // No need to restrict comparison here, both are from // log labels. if (my.contexts[i]->source().host() == newContext->source().host()) { pmprintf("%s: Error: Archives \"%s\" and \"%s\" are from " "the same host \"%s\"\n", pmProgname, my.contexts[i]->source().sourceAscii(), newContext->source().sourceAscii(), my.contexts[i]->source().hostAscii()); delete newContext; return PM_ERR_NOCONTEXT; } } my.contexts.append(newContext); my.use = my.contexts.size() - 1; if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: Added context " << my.use << ": " << *newContext << endl; } } // We found a match, do we need to use a different context? else if (i != (unsigned int)my.use) { my.use = i; sts = useContext(); if (sts < 0) { pmprintf("%s: Error: Unable to use context to %s: %s\n", pmProgname, context()->source().sourceAscii(), pmErrStr(sts)); return sts; } if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: Using existing context " << my.use << " for " << context()->source().desc() << endl; } } else if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: Using current context " << my.use << " (handle = " << context()->handle() << ") for " << context()->source().desc() << endl; } return context()->handle(); }