Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
    }
}
Exemplo n.º 3
0
Arquivo: config.c Projeto: Aconex/pcp
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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
Arquivo: pmcpp.c Projeto: Aconex/pcp
/*
 * 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);
}
Exemplo n.º 6
0
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);
    }
}
Exemplo n.º 7
0
/*
 * 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;
}
Exemplo n.º 8
0
/*
 * 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;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
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);
    }
}
Exemplo n.º 11
0
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 * 
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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);
    }
}
Exemplo n.º 12
0
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;
    }
}
Exemplo n.º 13
0
Arquivo: mailq.c Projeto: Aconex/pcp
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;
}
Exemplo n.º 14
0
Arquivo: derive.c Projeto: Aconex/pcp
/* 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;
}
Exemplo n.º 15
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));
	}
    }
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
void
QmcMetric::dumpErr(const char *inst) const
{
    pmprintf("%s: Error: %s[%s]: %s\n", pmProgname,
	     (const char *)spec(true).toLatin1(), inst, pmErrStr(my.status));
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
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);
}
Exemplo n.º 20
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;
}
Exemplo n.º 21
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;
}
Exemplo n.º 22
0
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);
}
Exemplo n.º 23
0
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;
}
Exemplo n.º 24
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();
    }
}
Exemplo n.º 25
0
Arquivo: pmtop.c Projeto: tongfw/pcp
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;
}
Exemplo n.º 26
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;
}
Exemplo n.º 27
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);
}
Exemplo n.º 28
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);
}
Exemplo n.º 29
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;
}
Exemplo n.º 30
0
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();
}