Пример #1
0
Файл: fetch.c Проект: Aconex/pcp
int
pmFetchArchive(pmResult **result)
{
    int		n;
    __pmContext	*ctxp;
    int		ctxp_mode;

    if ((n = pmWhichContext()) >= 0) {
	ctxp = __pmHandleToPtr(n);
	if (ctxp == NULL)
	    n = PM_ERR_NOCONTEXT;
	else {
	    ctxp_mode = (ctxp->c_mode & __PM_MODE_MASK);
	    if (ctxp->c_type != PM_CONTEXT_ARCHIVE)
		n = PM_ERR_NOTARCHIVE;
	    else if (ctxp_mode == PM_MODE_INTERP)
		/* makes no sense! */
		n = PM_ERR_MODE;
	    else {
		/* assume PM_CONTEXT_ARCHIVE and BACK or FORW */
		n = __pmLogFetch(ctxp, 0, NULL, result);
		if (n >= 0) {
		    ctxp->c_origin.tv_sec = (__int32_t)(*result)->timestamp.tv_sec;
		    ctxp->c_origin.tv_usec = (__int32_t)(*result)->timestamp.tv_usec;
		}
	    }
	    PM_UNLOCK(ctxp->c_lock);
	}
    }

    return n;
}
Пример #2
0
void
disconnect(int sts)
{
    time_t  		now;
#if CAN_RECONNECT
    int			ctx;
    __pmContext		*ctxp;
#endif

    time(&now);
    if (sts != 0)
	fprintf(stderr, "%s: Error: %s\n", pmProgname, pmErrStr(sts));
    fprintf(stderr, "%s: Lost connection to PMCD on \"%s\" at %s",
	    pmProgname, pmcd_host, ctime(&now));
#if CAN_RECONNECT
    if (primary) {
	fprintf(stderr, "This is fatal for the primary logger.");
	exit(1);
    }
    close(pmcdfd);
    __pmFD_CLR(pmcdfd, &fds);
    pmcdfd = -1;
    numfds = maxfd() + 1;
    if ((ctx = pmWhichContext()) >= 0)
	ctxp = __pmHandleToPtr(ctx);
    if (ctx < 0 || ctxp == NULL) {
	fprintf(stderr, "%s: disconnect botch: cannot get context: %s\n", pmProgname, pmErrStr(ctx));
	exit(1);
    }
    ctxp->c_pmcd->pc_fd = -1;
    PM_UNLOCK(ctxp->c_lock);
#else
    exit(1);
#endif
}
Пример #3
0
/* Initialize API and fill in internal description for given Context. */
static void
initapi(Context *x)
{
    int e;

    x->handle = pmWhichContext();

    if ((e = pmLookupName(1, &(x->metric), &(x->pmid))) < 0) {
        fprintf(stderr, "%s: pmLookupName(%s): %s\n", pmProgname, x->metric, pmErrStr(e));
        exit(EXIT_FAILURE);
    }

    if ((e = pmLookupDesc(x->pmid, &(x->desc))) < 0) {
        fprintf(stderr, "%s: pmLookupDesc: %s\n", pmProgname, pmErrStr(e));
        exit(EXIT_FAILURE);
    }

    if (x->desc.sem == PM_SEM_COUNTER) {
	if (x->desc.units.dimTime == 0)
	    x->scale = 1.0;
	else {
	    if (x->desc.units.scaleTime > PM_TIME_SEC)
		x->scale = pow(60, (PM_TIME_SEC - x->desc.units.scaleTime));
	    else
		x->scale = pow(1000, (PM_TIME_SEC - x->desc.units.scaleTime));
	}
    }
}
Пример #4
0
int
reconnect(void)
{
    int	    		sts;
    int			ctx;
    __pmContext		*ctxp;

    if ((ctx = pmWhichContext()) >= 0)
	ctxp = __pmHandleToPtr(ctx);
    if (ctx < 0 || ctxp == NULL) {
	fprintf(stderr, "%s: reconnect botch: cannot get context: %s\n", pmProgname, pmErrStr(ctx));
	exit(1);
    }
    sts = pmReconnectContext(ctx);
    if (sts >= 0) {
	time_t      now;
	time(&now);
	fprintf(stderr, "%s: re-established connection to PMCD on \"%s\" at %s\n",
		pmProgname, pmcd_host, ctime(&now));
	pmcdfd = ctxp->c_pmcd->pc_fd;
	__pmFD_SET(pmcdfd, &fds);
	numfds = maxfd() + 1;
    }
    PM_UNLOCK(ctxp->c_lock);
    return sts;
}
Пример #5
0
void
disconnect(int sts)
{
    time_t  		now;
    int			ctx;
    __pmContext		*ctxp;

    time(&now);
    if (sts != 0)
	fprintf(stderr, "%s: Error: %s\n", pmProgname, pmErrStr(sts));
    fprintf(stderr, "%s: Lost connection to PMCD on \"%s\" at %s",
	    pmProgname, pmcd_host, ctime(&now));
    if (pmcdfd != -1) {
	close(pmcdfd);
	__pmFD_CLR(pmcdfd, &fds);
	pmcdfd = -1;
    }
    numfds = maxfd() + 1;
    if ((ctx = pmWhichContext()) >= 0)
	ctxp = __pmHandleToPtr(ctx);
    if (ctx < 0 || ctxp == NULL) {
	fprintf(stderr, "%s: disconnect botch: cannot get context: %s\n", pmProgname, pmErrStr(ctx));
	exit(1);
    }
    ctxp->c_pmcd->pc_fd = -1;
    PM_UNLOCK(ctxp->c_lock);
}
Пример #6
0
static void
EndLocalContext(void)
{
    int		i;
    __pmDSO	*dp;
    int		ctx = pmWhichContext();

    if (PM_MULTIPLE_THREADS(PM_SCOPE_DSO_PMDA))
	/*
	 * Local context requires single-threaded applications
	 * ... should not really get here, so do nothing!
	 */
	return;

    for (i = 0; i < numdso; i++) {
	dp = &dsotab[i];
	if (dp->domain != -1 &&
	    dp->dispatch.comm.pmda_interface >= PMDA_INTERFACE_5 &&
	    dp->dispatch.version.four.ext->e_endCallBack != NULL) {
#ifdef PCP_DEBUG
	    if (pmDebug & DBG_TRACE_CONTEXT) {
		fprintf(stderr, "NotifyEndLocalContext: DSO PMDA %s (%d) notified of context %d close\n", 
		    dp->name, dp->domain, ctx);
	    }
#endif
	    (*(dp->dispatch.version.four.ext->e_endCallBack))(ctx);
	}
    }
}
Пример #7
0
int
reconnect(void)
{
    int	    		sts;
    int			ctx;
    time_t		now;
    __pmContext		*ctxp;

    if ((ctx = pmWhichContext()) >= 0)
	ctxp = __pmHandleToPtr(ctx);
    if (ctx < 0 || ctxp == NULL) {
	fprintf(stderr, "%s: reconnect botch: cannot get context: %s\n",
		pmProgname, pmErrStr(ctx));
	exit(1);
    }
    sts = pmReconnectContext(ctx);
    if (sts >= 0) {
	pmcdfd = ctxp->c_pmcd->pc_fd;
	__pmFD_SET(pmcdfd, &fds);
	numfds = maxfd() + 1;
    }
    PM_UNLOCK(ctxp->c_lock);
    if (sts < 0)
	return sts;

    time(&now);
    fprintf(stderr, "%s: re-established connection to PMCD on \"%s\" at %s",
	    pmProgname, pmcd_host, ctime(&now));

    /*
     * Metrics may have changed while PMCD was unreachable, so we
     * need to recheck each metric to make sure that its PMID and
     * semantics have not changed.  We cannot recover if there is
     * an incompatible change - must defer to controlling scripts
     * or processes (a new-named archive will have to be created,
     * from a new pmlogger process, and pmlogrewrite/pmlogextract
     * will need to become involved if they need to be merged).
     */
    validate_metrics();

    /*
     * All metrics have been validated, however, this state change
     * represents a potential gap in the stream of metrics.  So we
     * must store a <mark> record at this point.
     */
     if ((sts = putmark()) < 0) {
	fprintf(stderr, "putmark: %s\n", pmErrStr(sts));
	exit(1);
    }

    return 0;
}
Пример #8
0
Файл: fetch.c Проект: Aconex/pcp
int
pmSetMode(int mode, const struct timeval *when, int delta)
{
    int		n;
    __pmContext	*ctxp;
    int		l_mode = (mode & __PM_MODE_MASK);

    if ((n = pmWhichContext()) >= 0) {
	ctxp = __pmHandleToPtr(n);
	if (ctxp == NULL)
	    return PM_ERR_NOCONTEXT;
	if (ctxp->c_type == PM_CONTEXT_HOST) {
	    if (l_mode != PM_MODE_LIVE)
		n = PM_ERR_MODE;
	    else {
		ctxp->c_origin.tv_sec = ctxp->c_origin.tv_usec = 0;
		ctxp->c_mode = mode;
		ctxp->c_delta = delta;
		n = 0;
	    }
	}
	else if (ctxp->c_type == PM_CONTEXT_LOCAL) {
	    n = PM_ERR_MODE;
	}
	else {
	    /* assume PM_CONTEXT_ARCHIVE */
	    if (l_mode == PM_MODE_INTERP ||
		l_mode == PM_MODE_FORW || l_mode == PM_MODE_BACK) {
		if (when != NULL) {
		    /*
		     * special case of NULL for timestamp
		     * => do not update notion of "current" time
		     */
		    ctxp->c_origin.tv_sec = (__int32_t)when->tv_sec;
		    ctxp->c_origin.tv_usec = (__int32_t)when->tv_usec;
		}
		ctxp->c_mode = mode;
		ctxp->c_delta = delta;
		__pmLogSetTime(ctxp);
		__pmLogResetInterp(ctxp);
		n = 0;
	    }
	    else
		n = PM_ERR_MODE;
	}
	PM_UNLOCK(ctxp->c_lock);
    }
    return n;
}
Пример #9
0
/* Initialize API and fill in internal description for given Context. */
static void
initapi(Context *x, pmMetricSpec *msp, int argc, char **argv)
{
    int e;

    x->metric = msp->metric;
    if (msp->ninst > 0) {
	x->inum = msp->ninst;
	x->iall = (x->inum == 0);
	x->inames = &msp->inst[0];
    }
    x->handle = pmWhichContext();

    if ((e = pmLookupName(1, &(x->metric), &(x->pmid))) < 0) {
	fprintf(stderr, "%s: pmLookupName(%s): %s\n", pmProgname, x->metric,
		pmErrStr(e));
	exit(EXIT_FAILURE);
    }

    if ((e = pmLookupDesc(x->pmid, &(x->desc))) < 0) {
	fprintf(stderr, "%s: pmLookupDesc: %s\n", pmProgname, pmErrStr(e));
	exit(EXIT_FAILURE);
    }

    if (x->desc.indom == PM_INDOM_NULL && msp->ninst > 0) {
	fprintf(stderr, "%s: %s: singular metrics do not have instances\n",
		pmProgname, msp->metric);
	exit(EXIT_FAILURE);
    }

    if (x->desc.type == PM_TYPE_EVENT ||
	x->desc.type == PM_TYPE_HIGHRES_EVENT) {
	amode = PM_MODE_FORW;	/* do no interpolate events */
	rawArchive = archive;
	rawEvents = 1;
    }

    if (x->desc.sem == PM_SEM_COUNTER) {
	if (x->desc.units.dimTime == 0)
	    x->scale = 1.0;
	else {
	    if (x->desc.units.scaleTime > PM_TIME_SEC)
		x->scale = pow(60, (PM_TIME_SEC - x->desc.units.scaleTime));
	    else
		x->scale = pow(1000, (PM_TIME_SEC - x->desc.units.scaleTime));
	}
    }
}
Пример #10
0
/* send pmDescriptor for the given Expr as a binary PDU */
static void
sendDesc(Expr *x, pmValueSet *vset)
{
    pmDesc	d;

    d.pmid = vset->pmid;
    d.indom = PM_INDOM_NULL;
    switch (x->sem) {
	case PM_SEM_COUNTER:
	case PM_SEM_INSTANT:
	case PM_SEM_DISCRETE:
	    /* these map directly to PMAPI semantics */
	    d.type = PM_TYPE_DOUBLE;
	    d.sem = x->sem;
	    d.units = x->units;
	    break;

	case SEM_NUMVAR:
	case SEM_NUMCONST:
	case SEM_BOOLEAN:
	    /* map to a numeric value */
	    d.type = PM_TYPE_DOUBLE;
	    d.sem = PM_SEM_INSTANT;
	    d.units = x->units;
	    break;

	default:
	    fprintf(stderr, "sendDesc(%s): botch sem=%d?\n", pmIDStr(d.pmid), x->sem);
	    /* FALLTHROUGH */
	case SEM_UNKNOWN:
	case SEM_CHAR:
	case SEM_REGEX:
	    /* no mapping is possible */
	    d.type = PM_TYPE_NOSUPPORT;
	    d.sem = PM_SEM_INSTANT;
	    d.units = noUnits;
	    break;
    }
    __pmSendDesc(STDOUT_FILENO, pmWhichContext(), &d);
}
Пример #11
0
/*
 * main
 */
int
main(int argc, char **argv)
{
    int	sts;

    set_proc_fmt();
    printf("pid=%" FMT_PID " ppid=%" FMT_PID "\n", getpid(), getppid());
    getargs(argc, argv);

    if (pmnsfile != PM_NS_DEFAULT) {
	if ((sts = pmLoadNameSpace(pmnsfile)) < 0) {
	    printf("%s: Cannot load pmnsfile from \"%s\": %s\n", 
		    pmProgname, pmnsfile, pmErrStr(sts));
	    exit(1);
	}
    }

    if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
	printf("%s: Cannot connect to PMCD on host \"%s\": %s\n", 
		pmProgname, host, pmErrStr(sts));
	exit(1);
    }

    test_PMNS();
    test_desc();
    test_instance();
    test_prof_fetch();
    if (!is_hotproc)
        test_store();

    if ((sts = pmWhichContext()) < 0) {
	printf("%s: pmWhichContext: %s\n", pmProgname, pmErrStr(sts));
	exit(1);
    }
    pmDestroyContext(sts);

    exit(0);
}
Пример #12
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));
	}
    }
}
Пример #13
0
int
main(int argc, char **argv)
{
    int		c;
    char	*p;
    int		ctx;
    int		sts;
    char 	*configfile = NULL;
    int		fflag = 0;
    int		iflag = 0;
    int		lflag = 0;

    pmSetProgname(argv[0]);

    while ((c = pmGetOptions(argc, argv, &opts)) != EOF) {
	switch (c) {

	case 'c':	/* my configfile */
	    if (configfile != NULL) {
		fprintf(stderr, "%s: at most one -c option allowed\n", pmGetProgname());
		exit(EXIT_FAILURE);
	    }
	    configfile = opts.optarg;
	    break;	

	case 'f':	/* my flag */
	    fflag++;
	    break;

	case 'i':	/* my instances */
	    iflag++;
	    /* TODO extract instances from opts.optarg */
	    break;

	case 'l':	/* my logfile */
	    if (lflag) {
		fprintf(stderr, "%s: at most one -l option allowed\n", pmGetProgname());
		exit(EXIT_FAILURE);
	    }
	    pmOpenLog(pmGetProgname(), opts.optarg, stderr, &sts);
	    if (sts != 1) {
		fprintf(stderr, "%s: Could not open logfile \"%s\"\n", pmGetProgname(), opts.optarg);
		exit(EXIT_FAILURE);
	    }
	    lflag++;
	    break;	

	}
    }

    if (opts.flags & PM_OPTFLAG_EXIT) {
	pmflush();
	pmUsageMessage(&opts);
	exit(0);
    }

    if (opts.narchives == 1) {
	if ((ctx = pmNewContext(PM_CONTEXT_ARCHIVE, opts.archives[0])) < 0) {
	    fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
		    pmGetProgname(), opts.archives[0],  pmErrStr(ctx));
	    exit(EXIT_FAILURE);
	}
	if ((sts = pmGetContextOptions(ctx, &opts)) < 0) {
	    pmflush();
	    fprintf(stderr, "%s: pmGetContextOptions(%d, ...) failed: %s\n",
			pmGetProgname(), pmWhichContext(), pmErrStr(sts));
		exit(EXIT_FAILURE);
	}
    }
    else if (opts.narchives > 0) {
	fprintf(stderr, "%s: at most one archive allowed\n", pmGetProgname());
	exit(EXIT_FAILURE);
    }

    if (opts.nhosts == 1) {
	if ((ctx = pmNewContext(PM_CONTEXT_HOST, opts.hosts[0])) < 0) {
	    fprintf(stderr, "%s: Cannot connect to pmcd on host \"%s\": %s\n",
		    pmGetProgname(), opts.hosts[0],  pmErrStr(ctx));
	    exit(EXIT_FAILURE);
	}
    }
    else if (opts.nhosts > 0) {
	fprintf(stderr, "%s: at most one host allowed\n", pmGetProgname());
	exit(EXIT_FAILURE);
    }

    if (opts.errors) {
	pmUsageMessage(&opts);
	exit(EXIT_FAILURE);
    }

    if (opts.align_optarg != NULL)
	printf("Got -A \"%s\"\n", opts.align_optarg);

    if (opts.guiflag)
	printf("Got -g\n");

    if (opts.nsflag)
	printf("Loaded PMNS\n");

    if (opts.guiport)
	printf("Got -p \"%s\"\n", opts.guiport_optarg);

    if (opts.align_optarg != NULL || opts.start_optarg != NULL ||
        opts.finish_optarg != NULL || opts.origin_optarg != NULL) {
	printf("Start time: ");
	pmPrintStamp(stdout, &opts.start);
	putchar('\n');
	printf("Origin time: ");
	pmPrintStamp(stdout, &opts.origin);
	putchar('\n');
	printf("Finish time: ");
	pmPrintStamp(stdout, &opts.finish);
	putchar('\n');
    }

    if (sflag)
	printf("Got -s \"%d\"\n", opts.samples);

    if (opts.interval.tv_sec > 0 || opts.interval.tv_usec > 0)
	printf("Got -t %d.%06d (secs)\n",
		(int)opts.interval.tv_sec, (int)opts.interval.tv_usec);

    p = getenv("PCP_CONTAINER");
    if (p != NULL)
	printf("Got --container=\"%s\"\n", p);

    if (opts.timezone != NULL)
	printf("Got -Z \"%s\"\n", opts.timezone);

    if (opts.tzflag)
	printf("Got -z\n");

    if (opts.Lflag)
	printf("Got -L\n");

    /* non-flag args are argv[optind] ... argv[argc-1] */
    while (opts.optind < argc) {
	printf("extra argument[%d]: %s\n", opts.optind, argv[opts.optind]);
	opts.optind++;
    }

    while (!sflag || opts.samples-- > 0) {
	/* put real stuff here */
	break;
    }

    return 0;
}
Пример #14
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;
}
Пример #15
0
/* Return (in result) a list of active pmlogger ports on the specified machine.
 * The return value of the function is the number of elements in the array.
 * The caller must NOT free any part of the result stucture, it's storage is
 * managed here.  Subsequent calls will overwrite the data so the caller should
 * copy it if persistence is required.
 */
int
__pmLogFindPort(const char *host, int pid, __pmLogPort **lpp)
{
    int			ctx, oldctx;
    char		*ctxhost;
    int			sts, numval;
    int			i, j;
    int			findone = pid != PM_LOG_ALL_PIDS;
    int			localcon = 0;	/* > 0 for local connection */
    pmDesc		desc;
    pmResult		*res;
    char		*namelist[] = {"pmcd.pmlogger.port"};
    pmID		pmid;

    if (PM_MULTIPLE_THREADS(PM_SCOPE_LOGPORT))
	return PM_ERR_THREAD;

    *lpp = NULL;		/* pass null back in event of error */
    localcon = __pmIsLocalhost(host);
    if (localcon > 0)
	/* do the work here instead of making PMCD do it */
	return __pmLogFindLocalPorts(pid, lpp);
    else if (localcon < 0)
	return localcon;

    /* note: there may not be a current context */
    ctx = 0;
    oldctx = pmWhichContext();

    /*
     * Enclose ctxhost in [] in case it is an ipv6 address. This prevents
     * the first colon from being taken as a port separator by pmNewContext
     * and does no harm otherwise.
     */
    ctxhost = malloc(strlen(host) + 2 + 1);
    if (ctxhost == NULL) {
	sts = -ENOMEM;
	goto ctxErr;
    }
    sprintf(ctxhost, "[%s]", host);
    ctx = pmNewContext(PM_CONTEXT_HOST, ctxhost);
    free(ctxhost);
    if (ctx < 0)
	return ctx;
    if ((sts = pmLookupName(1, namelist, &pmid)) < 0)
	goto ctxErr;

    if ((sts = pmLookupDesc(pmid, &desc)) < 0)
	goto ctxErr;
    if ((sts = pmFetch(1, &pmid, &res) < 0))
	goto ctxErr;
    if ((sts = numval = res->vset[0]->numval) < 0)
	goto resErr;
    j = 0;
    if (numval) {
	if (resize_logports(findone ? 1 : numval) < 0) {
	    sts = -oserror();
	    goto resErr;
	}
	/* scan the pmResult, copying matching pid(s) to logport */
	for (i = j = 0; i < numval; i++) {
	    __pmLogPort	*p = &logport[j];
	    pmValue	*vp = &res->vset[0]->vlist[i];

	    if (vp->inst == 1)	/* old vcr instance (pseudo-init) */
		continue;
	    if (findone && vp->inst != pid)
		continue;
	    p->pid = vp->inst;
	    p->port = vp->value.lval;
	    sts = pmNameInDom(desc.indom, p->pid, &p->name);
	    if (sts < 0) {
		p->name = NULL;
		goto resErr;
	    }
	    j++;
	    if (findone)		/* found one, stop searching */
		break;
	}
	*lpp = logport;
    }
    sts = j;			/* the number actually added */

resErr:
    pmFreeResult(res);
ctxErr:
    if (oldctx >= 0)
	pmUseContext(oldctx);
    if (ctx >= 0)
	pmDestroyContext(ctx);
    return sts;
}
Пример #16
0
/* evaluate Task */
static void
eval(Task *task)
{
    Symbol	*s;
    pmValueSet  *vset;
    int		i;

    /* fetch metrics */
    taskFetch(task);

    /* evaluate rule expressions */
    s = task->rules;
    for (i = 0; i < task->nrules; i++) {
	curr = symValue(*s);
	if (curr->op < NOP) {
	    (curr->eval)(curr);
	    perf->eval_actual++;
	}
	s++;
    }

    if (verbose) {

	/* send binary values */
	if (agent) {
	    int	sts;
	    s = task->rules;
	    for (i = 0; i < task->nrules; i++) {
		vset = task->rslt->vset[i];
		fillVSet(symValue(*s), vset);
		s++;
	    }
	    __pmOverrideLastFd(PDU_OVERRIDE2);
	    sts = __pmSendResult(STDOUT_FILENO, pmWhichContext(), task->rslt);
	    if (sts < 0) {
		fprintf(stderr, "Error: __pmSendResult to summary agent failed: %s\n", pmErrStr(sts));
		exit(0);
	    }

	}

        /* send values to applet */
        else if (applet) {
            s = task->rules;
            for (i = 0; i < task->nrules; i++) {
                showValue(stdout, symValue(*s));
                putchar(' ');
                s++;
            }
            putchar('\n');
        }

	/* print values in ASCII */
	else {
	    s = task->rules;
	    for (i = 0; i < task->nrules; i++) {
		printf("%s", symName(*s));
		if (archives || showTimeFlag) {
		    printf(" (");
		    showTime(stdout, now);
		    putchar(')');
		}
		printf(": ");
		switch (verbose) {
		case 1:
		    showValue(stdout, symValue(*s));
		    break;
		case 2:
		    showAnnotatedValue(stdout, symValue(*s));
		    break;
		case 3:
		    showSatisfyingValue(stdout, symValue(*s));
		    break;
		}
		putchar('\n');
		s++;
	    }
	    putchar('\n');
	}
    }
}
Пример #17
0
Файл: fetch.c Проект: Aconex/pcp
int
pmFetch(int numpmid, pmID pmidlist[], pmResult **result)
{
    int		n;

    if (numpmid < 1) {
	n = PM_ERR_TOOSMALL;
	goto done;
    }

    if ((n = pmWhichContext()) >= 0) {
	__pmContext	*ctxp = __pmHandleToPtr(n);
	int		newcnt;
	pmID		*newlist = NULL;
	int		have_dm;

	if (ctxp == NULL) {
	    n = PM_ERR_NOCONTEXT;
	    goto done;
	}
	if (ctxp->c_type == PM_CONTEXT_LOCAL && PM_MULTIPLE_THREADS(PM_SCOPE_DSO_PMDA)) {
	    /* Local context requires single-threaded applications */
	    n = PM_ERR_THREAD;
	    PM_UNLOCK(ctxp->c_lock);
	    goto done;
	}

	/* for derived metrics, may need to rewrite the pmidlist */
	have_dm = newcnt = __pmPrepareFetch(ctxp, numpmid, pmidlist, &newlist);
	if (newcnt > numpmid) {
	    /* replace args passed into pmFetch */
	    numpmid = newcnt;
	    pmidlist = newlist;
	}

	if (ctxp->c_type == PM_CONTEXT_HOST) {
	    /*
	     * Thread-safe note
	     *
	     * Need to be careful here, because the PMCD changed protocol
	     * may mean several PDUs are returned, but __pmDecodeResult()
	     * may request more info from PMCD if pmDebug is set.
	     *
	     * So unlock ctxp->c_pmcd->pc_lock as soon as possible.
	     */
	    PM_LOCK(ctxp->c_pmcd->pc_lock);
	    if ((n = request_fetch(n, ctxp, numpmid, pmidlist)) >= 0) {
		int changed = 0;
		do {
		    __pmPDU	*pb;
		    int		pinpdu;

		    pinpdu = n = __pmGetPDU(ctxp->c_pmcd->pc_fd, ANY_SIZE,
					    ctxp->c_pmcd->pc_tout_sec, &pb);
		    if (n == PDU_RESULT) {
			PM_UNLOCK(ctxp->c_pmcd->pc_lock);
			n = __pmDecodeResult(pb, result);
		    }
		    else if (n == PDU_ERROR) {
			__pmDecodeError(pb, &n);
			if (n > 0)
			    /* PMCD state change protocol */
			    changed = n;
			else
			    PM_UNLOCK(ctxp->c_pmcd->pc_lock);
		    }
		    else {
			PM_UNLOCK(ctxp->c_pmcd->pc_lock);
			if (n != PM_ERR_TIMEOUT)
			    n = PM_ERR_IPC;
		    }
		    if (pinpdu > 0)
			__pmUnpinPDUBuf(pb);
		} while (n > 0);

		if (n == 0)
		    n |= changed;
	    }
	    else
		PM_UNLOCK(ctxp->c_pmcd->pc_lock);
	}
	else if (ctxp->c_type == PM_CONTEXT_LOCAL) {
	    n = __pmFetchLocal(ctxp, numpmid, pmidlist, result);
	}
	else {
	    /* assume PM_CONTEXT_ARCHIVE */
	    n = __pmLogFetch(ctxp, numpmid, pmidlist, result);
	    if (n >= 0 && (ctxp->c_mode & __PM_MODE_MASK) != PM_MODE_INTERP) {
		ctxp->c_origin.tv_sec = (__int32_t)(*result)->timestamp.tv_sec;
		ctxp->c_origin.tv_usec = (__int32_t)(*result)->timestamp.tv_usec;
	    }
	}

	/* process derived metrics, if any */
	if (have_dm) {
	    __pmFinishResult(ctxp, n, result);
	    if (newlist != NULL)
		free(newlist);
	}
	PM_UNLOCK(ctxp->c_lock);
    }

done:
#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_FETCH) {
	fprintf(stderr, "pmFetch returns ...\n");
	if (n > 0) {
	    fprintf(stderr, "PMCD state changes: agent(s)");
	    if (n & PMCD_ADD_AGENT) fprintf(stderr, " added");
	    if (n & PMCD_RESTART_AGENT) fprintf(stderr, " restarted");
	    if (n & PMCD_DROP_AGENT) fprintf(stderr, " dropped");
	    fputc('\n', stderr);
	}
	if (n >= 0)
	    __pmDumpResult(stderr, *result);
	else {
	    char	errmsg[PM_MAXERRMSGLEN];
	    fprintf(stderr, "Error: %s\n", pmErrStr_r(n, errmsg, sizeof(errmsg)));
	}
    }
#endif

    return n;
}
Пример #18
0
/*
 * Tests 4. and 5.
 * Set up an explicit profile of ourself and our parent
 * If any of the metrics are not in the proc indom, we'll get no values back.
 * Checks if profile is being handled correctly.
 * Checks if fetch is using profile correctly.
 */
void
test_prof_fetch(void)
{
    int 	sts;
    int		i;
    int		pids[2];
    pmResult	*result1, *result2;

    print_banner_start("profile/fetch");

    pids[0] = (int)getpid();
    pids[1] = (int)getppid();
    pmDelProfile(indom, 0, NULL);
    pmAddProfile(indom, 2, pids);

    printf("\n--- Check profile in context dump... ---\n");
    if ((sts = pmWhichContext()) < 0) {
	printf("%s: pmWhichContext: %s\n", pmProgname, pmErrStr(sts));
	exit(1);
    }
    __pmDumpContext(stdout, sts, PM_INDOM_NULL);
    printf("--- End Check profile in context dump... ---\n");

    printf("\n--- Fetch Over Restricted Instance Domain ... ---\n");
    for (i=0; i < iterations; i++) {
	int j,k;

	sts = pmFetch(nmetrics, pmids, &result1);
	if (sts < 0) {
	    printf("%s: iteration %d : %s\n", pmProgname, i, pmErrStr(sts));
	    exit(1);
	}
	__pmDumpResult(stdout, result1);


	for (j = 0; j < result1->numpmid; j++) {
	    pmValueSet *set = result1->vset[j];

	    if (set->numval != 2) {
		printf("%s: Error: num of inst == %d\n", pmProgname, set->numval);
	    }        

	    for (k = 0; k < set->numval; k++) {
		pmValue *val = &set->vlist[k];
		if (val->inst != pids[0] && val->inst != pids[1]) {
		    printf("%s: Error: inst ids do not match pids\n", pmProgname);
		    exit(1);
		}        
	    } 
	}

	pmFreeResult(result1);
    }
    printf("--- End Fetch Over Restricted Instance Domain ... ---\n");



    printf("\n--- Fetch Over Entire Instance Domain ... ---\n");
    if (indom != PM_INDOM_NULL) {
	pmDelProfile(indom, 0, NULL);
	pmAddProfile(indom, all_n, all_inst);
    }
    sts = pmFetch(nmetrics, pmids, &result2);
    if (sts < 0) {
	printf("%s: fetch all %d instances : %s\n", pmProgname, all_n, pmErrStr(sts));
	exit(1);
    }
    __pmDumpResult(stdout, result2);
    pmFreeResult(result2);
    printf("--- End Fetch Over Entire Instance Domain ... ---\n");

    print_banner_end("profile/fetch");

}