Пример #1
0
/**
 * timerqueue_getptr(Q, tv):
 * If the least timeval in ${Q} is less than or equal to ${tv}, return the
 * associated pointer and remove the pair from the priority queue.  If not,
 * return NULL.
 */
void *
timerqueue_getptr(struct timerqueue * Q, const struct timeval * tv)
{
	struct timerrec * r;
	void * ptr;

	/*
	 * Get the minimum element from the heap.  Return NULL if the heap
	 * has no minimum element (i.e., is empty).
	 */
	if ((r = ptrheap_getmin(Q->H)) == NULL)
		return (NULL);

	/* If the minimum timeval is greater than ${tv}, return NULL. */
	if (tvcmp(&r->tv, tv) > 0)
		return (NULL);

	/* Remove this record from the heap. */
	ptrheap_deletemin(Q->H);

	/* Extract its pointer. */
	ptr = r->ptr;

	/* Free the record. */
	free(r);

	/*
	 * And finally return the pointer which was associated with the
	 * (formerly) minimum timeval in the heap.
	 */
	return (ptr);
}
Пример #2
0
/* external function definitions */
int 
timerproc(void)
{
  struct node *hp = &timers;
  struct timeval *now = tod();
  struct node *np;
  int didwork = 0;

  while ((np = hp->f) != hp) {
    struct timer *tp = TIMERAT(np);
    struct timeval *tvp = &(tp->expire);

    if (tvcmp(now, tvp) >= 0) {
      void (*func) () = tp->func;
      void *arg = tp->arg;

      timerclr(tp);
      if (func != (void (*) ()) (0))
	(*func) (arg);
    } else {
      break;
    }
    didwork = 1;
  }

  return didwork;
}
Пример #3
0
/* Record-comparison callback from ptrheap. */
static int
compar(void * cookie, const void * x, const void * y)
{
	const struct timerrec * _x = x;
	const struct timerrec * _y = y;

	(void)cookie; /* UNUSED */

	return (tvcmp(&_x->tv, &_y->tv));
}
Пример #4
0
// t0 -= t1, but min is { 0, 0 }
void tvsub(struct timeval *t0, const struct timeval *t1) {
    if (tvcmp(t0, t1) <= 0) {
        t0->tv_sec = 0;
        t0->tv_usec = 0;
        return;
    }
    t0->tv_usec -= t1->tv_usec;
    if (t0->tv_usec < 0) {
        t0->tv_usec += 1000000;
        t0->tv_sec --;
    }
    t0->tv_sec -= t1->tv_sec;
}
Пример #5
0
int
main(int argc, char *argv[])
{
    int			c;
    int			sts;
    char		*rawfile = NULL;
    int			i;
    int			ctxid;
    int			first = 1;
    int			dflag = 0;
    int			iflag = 0;
    int			Lflag = 0;
    int			lflag = 0;
    int			Mflag = 0;
    int			mflag = 0;
    int			tflag = 0;
    int			vflag = 0;
    int			mode = PM_MODE_FORW;
    __pmContext		*ctxp;
    pmResult		*raw_result;
    pmResult		*skel_result = NULL;
    pmResult		*result;
    struct timeval	done;

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

	case 'a':	/* dump everything */
	    dflag = iflag = lflag = mflag = sflag = tflag = 1;
	    break;

	case 'd':	/* dump pmDesc structures */
	    dflag = 1;
	    break;

	case 'i':	/* dump instance domains */
	    iflag = 1;
	    break;

	case 'L':	/* dump label, verbose */
	    Lflag = 1;
	    lflag = 1;
	    break;

	case 'l':	/* dump label */
	    lflag = 1;
	    break;

	case 'm':	/* dump metrics in log */
	    mflag = 1;
	    break;

	case 'M':	/* report <mark> records */
	    Mflag = 1;
	    break;

	case 'r':	/* read log in reverse chornological order */
	    mode = PM_MODE_BACK;
	    break;

	case 's':	/* report data size in log */
	    sflag = 1;
	    break;

	case 't':	/* dump temporal index */
	    tflag = 1;
	    break;

	case 'v':	/* verbose, dump in raw format */
	    vflag = 1;
	    rawfile = opts.optarg;
	    break;

	case 'x':	/* report Ddd Mmm DD <timestamp> YYYY */
			/* -xx reports numeric timeval also */
	    xflag++;
	    break;
	}
    }

    if (opts.errors ||
	(vflag && opts.optind != argc) ||
	(!vflag && opts.optind > argc - 1 && !opts.narchives)) {
	pmUsageMessage(&opts);
	exit(1);
    }

    if (vflag) {
	FILE	*f;
	if ((f = fopen(rawfile, "r")) == NULL) {
	    fprintf(stderr, "%s: Cannot open \"%s\": %s\n", pmProgname, rawfile, osstrerror());
	    exit(1);
	}
	printf("Raw dump of physical archive file \"%s\" ...\n", rawfile);
	rawdump(f);
	exit(0);
    }

    if (dflag + iflag + lflag + mflag + tflag == 0)
	mflag = 1;	/* default */

    /* delay option end processing until now that we have the archive name */
    if (opts.narchives == 0)
	__pmAddOptArchive(&opts, argv[opts.optind++]);
    opts.flags &= ~PM_OPTFLAG_DONE;
    __pmEndOptions(&opts);

    if ((sts = ctxid = pmNewContext(PM_CONTEXT_ARCHIVE, opts.archives[0])) < 0) {
	fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
		pmProgname, opts.archives[0], pmErrStr(sts));
	exit(1);
    }
    /* complete TZ and time window option (origin) setup */
    if (pmGetContextOptions(ctxid, &opts)) {
	pmflush();
	exit(1);
    }

    numpmid = argc - opts.optind;
    if (numpmid) {
	numpmid = 0;
	pmid = NULL;
	for (i = 0; opts.optind < argc; i++, opts.optind++) {
	    numpmid++;
	    pmid = (pmID *)realloc(pmid, numpmid * sizeof(pmID));
	    if ((sts = pmLookupName(1, &argv[opts.optind], &pmid[numpmid-1])) < 0) {
		if (sts == PM_ERR_NONLEAF) {
		    numpmid--;
		    if ((sts = pmTraversePMNS(argv[opts.optind], dometric)) < 0)
			fprintf(stderr, "%s: pmTraversePMNS(%s): %s\n",
				pmProgname, argv[opts.optind], pmErrStr(sts));
		}
		else
		    fprintf(stderr, "%s: pmLookupName(%s): %s\n",
			    pmProgname, argv[opts.optind], pmErrStr(sts));
		if (sts < 0)
		    numpmid--;
	    }
	}
	if (numpmid == 0) {
	    fprintf(stderr, "No metric names can be translated, dump abandoned\n");
	    exit(1);
	}
    }

    if ((sts = pmGetArchiveLabel(&label)) < 0) {
	fprintf(stderr, "%s: Cannot get archive label record: %s\n",
		pmProgname, pmErrStr(sts));
	exit(1);
    }

    if (numpmid > 0) {
	/*
	 * setup dummy pmResult
	 */
	skel_result = (pmResult *)malloc(sizeof(pmResult)+(numpmid-1)*sizeof(pmValueSet *));
	if (skel_result == NULL) {
	    fprintf(stderr, "%s: malloc(skel_result): %s\n", pmProgname, osstrerror());
	    exit(1);

	}
    }

    /*
     * 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
     *       pmdumplog code.
     *       This works because ctxp->c_lock is a recursive lock and
     *       pmdumplog is single-threaded.
     */
    if ((ctxp = __pmHandleToPtr(ctxid)) == NULL) {
	fprintf(stderr, "%s: botch: __pmHandleToPtr(%d) returns NULL!\n",
		pmProgname, ctxid);
	exit(1);
    }

    pmSetMode(mode, &opts.start, 0);

    if (lflag)
	dumpLabel(Lflag);

    if (dflag)
	dumpDesc(ctxp);

    if (iflag)
	dumpInDom(ctxp);

    if (tflag)
	dumpTI(ctxp);

    if (mflag) {
	if (mode == PM_MODE_FORW) {
	    if (opts.start_optarg != NULL || opts.finish_optarg != NULL) {
		/* -S or -T */
		sts = pmSetMode(mode, &opts.start, 0);
		done = opts.finish;
	    }
	    else {
		/* read the whole archive */
		done.tv_sec = 0;
		done.tv_usec = 0;
		sts = pmSetMode(mode, &done, 0);
		done.tv_sec = INT_MAX;
	    }
	}
	else {
	    if (opts.start_optarg != NULL || opts.finish_optarg != NULL) {
		/* -S or -T */
		done.tv_sec = INT_MAX;
		done.tv_usec = 0;
		sts = pmSetMode(mode, &done, 0);
		done = opts.start;
	    }
	    else {
		/* read the whole archive backwards */
		done.tv_sec = INT_MAX;
		done.tv_usec = 0;
		sts = pmSetMode(mode, &done, 0);
		done.tv_sec = 0;
	    }
	}
	if (sts < 0) {
	    fprintf(stderr, "%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
	    exit(1);
	}
	sts = 0;
	for ( ; ; ) {
	    sts = __pmLogFetch(ctxp, 0, NULL, &raw_result);
	    if (sts < 0)
		break;
	    if (numpmid == 0 || (raw_result->numpmid == 0 && Mflag)) {
		/*
		 * want 'em all or <mark> record ...
		 */
		result = raw_result;
	    }
	    else if (numpmid > 0) {
		/*
		 * cherry pick from raw_result if pmid matches one
		 * of interest
		 */
		int	picked = 0;
		int	j;
		skel_result->timestamp = raw_result->timestamp;
		for (j = 0; j < numpmid; j++)
		    skel_result->vset[j] = NULL;
		for (i = 0; i < raw_result->numpmid; i++) {
		    for (j = 0; j < numpmid; j++) {
			if (pmid[j] == raw_result->vset[i]->pmid) {
			    skel_result->vset[j] = raw_result->vset[i];
			    picked++;
			    break;
			}
		    }
		}
		if (picked == 0) {
		    /* no metrics of interest, skip this record */
		    pmFreeResult(raw_result);
		    continue;
		}
		skel_result->numpmid = picked;
		if (picked != numpmid) {
		    /* did not find 'em all ... shuffle time */
		    int		j;
		    i = 0;
		    for (j = 0; j < numpmid; j++) {
			if (skel_result->vset[j] != NULL)
			    skel_result->vset[i++] = skel_result->vset[j];
		    }
		}
		result = skel_result;
	    }
	    else {
		/* not interesting */
		pmFreeResult(raw_result);
		continue;
	    }
	    if (first && mode == PM_MODE_BACK) {
		first = 0;
		printf("\nLog finished at %24.24s - dump in reverse order\n",
			pmCtime(&result->timestamp.tv_sec, timebuf));
	    }
	    if ((mode == PM_MODE_FORW && tvcmp(result->timestamp, done) > 0) ||
		(mode == PM_MODE_BACK && tvcmp(result->timestamp, done) < 0)) {
		sts = PM_ERR_EOL;
		break;
	    }
	    putchar('\n');
	    dump_result(result);
	    pmFreeResult(raw_result);
	}
	if (sts != PM_ERR_EOL) {
	    fprintf(stderr, "%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
	    exit(1);
	}
    }

    exit(0);
}
Пример #6
0
void
filein(register Archive_t* ap, register File_t* f)
{
	register off_t	c;
	register int	n;
	register char*	s;
	int		dfd;
	int		wfd;
	long		checksum;
	Filter_t*	fp;
	Proc_t*		pp;
	Tv_t		t1;
	Tv_t		t2;
	struct stat	st;

	if (f->skip)
		goto skip;
	else if (state.list)
	{
		if (fp = filter(ap, f))
		{
			for (n = 0; s = fp->argv[n]; n++)
			{
				while (*s)
					if (*s++ == '%' && *s == '(')
						break;
				if (*s)
				{
					s = fp->argv[n];
					listprintf(state.tmp.str, ap, f, s);
					if (!(fp->argv[n] = sfstruse(state.tmp.str)))
						nospace();
					break;
				}
			}
			pp = procopen(*fp->argv, fp->argv, NiL, NiL, PROC_WRITE);
			if (s)
				fp->argv[n] = s;
			if (!pp)
			{
				error(2, "%s: %s: cannot execute filter %s", ap->name, f->path, *fp->argv);
				goto skip;
			}
			if (!ap->format->getdata || !(*ap->format->getdata)(&state, ap, f, pp->wfd))
			{
				checksum = 0;
				for (c = f->st->st_size; c > 0; c -= n)
				{
					n = (c > state.buffersize) ? state.buffersize : c;
					if (!(s = bget(ap, n, NiL)))
					{
						error(ERROR_SYSTEM|2, "%s: read error", f->name);
						break;
					}
					if (write(pp->wfd, s, n) != n)
					{
						error(ERROR_SYSTEM|2, "%s: write error", f->name);
						break;
					}
					if (ap->format->checksum)
						checksum = (*ap->format->checksum)(&state, ap, f, s, n, checksum);
				}
			}
			if (ap->format->checksum && checksum != f->checksum)
				error(1, "%s: %s checksum error (0x%08x != 0x%08x)", f->name, ap->format->name, checksum, f->checksum);
			/*
			 * explicitly ignore exit status
			 */

			procclose(pp);
			return;
		}
		listentry(f);
		goto skip;
	}
	else switch (f->delta.op)
	{
	case DELTA_create:
		if (f->delta.base)
			error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__);
		if (ap->delta->format->flags & PSEUDO)
			goto regular;
		if ((wfd = openout(ap, f)) < 0)
			goto skip;
		else
			paxdelta(NiL, ap, f, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, f->st->st_size, 0);
		break;
	case DELTA_update:
		if (!f->delta.base || (unsigned long)f->delta.base->mtime.tv_sec >= (unsigned long)f->st->st_mtime)
			error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__);
		c = f->st->st_size;
		if ((wfd = openout(ap, f)) < 0)
			goto skip;
		if (state.ordered)
		{
			if (!f->delta.base->uncompressed)
				paxdelta(NiL, ap, f, DELTA_SRC|DELTA_BIO|DELTA_SIZE, ap->delta->base, f->delta.base->size, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0);
			else if (!paxdelta(NiL, ap, f, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap->delta->base, f->delta.base->size, DELTA_TAR|DELTA_TEMP|DELTA_OUTPUT, &dfd, 0))
				paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_SIZE|DELTA_FREE, dfd, f->delta.base->uncompressed, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0);
		}
		else if (!f->delta.base->uncompressed)
			paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_OFFSET|DELTA_SIZE, ap->delta->base->io->fd, f->delta.base->offset, f->delta.base->size, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0);
		else if (!paxdelta(NiL, ap, f, DELTA_DEL|DELTA_FD|DELTA_OFFSET|DELTA_SIZE, ap->delta->base->io->fd, f->delta.base->offset, f->delta.base->size, DELTA_TAR|DELTA_TEMP|DELTA_OUTPUT, &dfd, 0))
			paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_SIZE|DELTA_FREE, dfd, f->delta.base->uncompressed, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0);
		break;
	case DELTA_verify:
		if (!f->delta.base || f->delta.base->mtime.tv_sec != f->st->st_mtime)
			error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__);
		if ((*state.statf)(f->name, &st))
			error(2, "%s: not copied from base archive", f->name);
		else if (st.st_size != f->delta.base->size || state.modtime && tvcmp(tvmtime(&t1, &st), tvmtime(&t2, f->st)))
			error(1, "%s: changed from base archive", f->name);
		break;
	case DELTA_delete:
		if (!f->delta.base)
			error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__);
		/*FALLTHROUGH*/
	default:
	regular:
		wfd = openout(ap, f);
		if (wfd >= 0)
		{
			holeinit(wfd);
			if (!ap->format->getdata || !(*ap->format->getdata)(&state, ap, f, wfd))
			{
				checksum = 0;
				for (c = f->st->st_size; c > 0; c -= n)
				{
					n = (c > state.buffersize) ? state.buffersize : c;
					if (!(s = bget(ap, n, NiL)))
					{
						error(ERROR_SYSTEM|2, "%s: read error", f->name);
						break;
					}
					if (holewrite(wfd, s, n) != n)
					{
						error(ERROR_SYSTEM|2, "%s: write error", f->name);
						break;
					}
					if (ap->format->checksum)
						checksum = (*ap->format->checksum)(&state, ap, f, s, n, checksum);
				}
			}
			holedone(wfd);
			closeout(ap, f, wfd);
			setfile(ap, f);
			if (ap->format->checksum && checksum != f->checksum)
				error(1, "%s: %s checksum error (0x%08x != 0x%08x)", f->name, ap->format->name, checksum, f->checksum);
		}
		else if (ap->format->getdata)
			(*ap->format->getdata)(&state, ap, f, wfd);
		else
		{
			if (wfd < -1)
				listentry(f);
			goto skip;
		}
		break;
	}
	listentry(f);
	return;
 skip:
	fileskip(ap, f);
}