Ejemplo n.º 1
0
static int
hotspotread(struct wire_requestqueue * Q, uint64_t N)
{
	struct hotspotread_state C;
	struct timeval tv_now;
	uint8_t buf[40];	/* dummy */

	/* Initialize. */
	C.Q = Q;
	C.Nip = 0;
	C.Xmax = N / 65536;
	C.X = 0;
	C.Y = 65536;
	C.failed = 0;
	C.done = 0;
	C.N = 0;

	/* Allocate key structure. */
	if ((C.key = kvldskey_create(buf, 40)) == NULL)
		goto err0;

	/* Get current time and store T+60s and T+50s. */
	if (monoclock_get(&tv_now)) {
		warnp("Error reading clock");
		goto err1;
	}
	C.tv_60.tv_sec = tv_now.tv_sec + 60;
	C.tv_60.tv_usec = tv_now.tv_usec;
	C.tv_50.tv_sec = tv_now.tv_sec + 50;
	C.tv_50.tv_usec = tv_now.tv_usec;

	/* Send an initial batch of 4096 requests. */
	if (sendbatch(&C))
		goto err1;

	/* Wait until we've finished. */
	if (events_spin(&C.done) || C.failed) {
		warnp("SET request failed");
		goto err1;
	}

	/* Print number of reads performed in a single second. */
	printf("%" PRIu64 "\n", C.N / 10);

	/* Free the key structure. */
	kvldskey_free(C.key);

	/* Success! */
	return (0);

err1:
	kvldskey_free(C.key);
err0:
	/* Failure! */
	return (-1);
}
Ejemplo n.º 2
0
/**
 * events_timer_min(timeo):
 * Return via ${timeo} a pointer to the minimum time which must be waited
 * before a timer will expire; or to NULL if there are no timers.  The caller
 * is responsible for freeing the returned pointer.
 */
int
events_timer_min(struct timeval ** timeo)
{
	struct timeval tnow;
	const struct timeval * tv;

	/* If we have no queue, we have no timers; return NULL. */
	if (Q == NULL) {
		*timeo = NULL;
		goto done;
	}

	/* Get the minimum timer from the queue. */
	tv = timerqueue_getmin(Q);

	/* If there are no timers, return NULL. */
	if (tv == NULL) {
		*timeo = NULL;
		goto done;
	}

	/* Allocate space for holding the returned timeval. */
	if ((*timeo = malloc(sizeof(struct timeval))) == NULL)
		goto err0;

	/* Get the current time... */
	if (monoclock_get(&tnow))
		goto err1;

	/* ... and compare it to the minimum timer. */
	if ((tnow.tv_sec > tv->tv_sec) ||
	    ((tnow.tv_sec == tv->tv_sec) && (tnow.tv_usec > tv->tv_usec))) {
		/* The timer has already expired, so return zero. */
		(*timeo)->tv_sec = 0;
		(*timeo)->tv_usec = 0;
	} else {
		/* Compute the difference. */
		(*timeo)->tv_sec = tv->tv_sec - tnow.tv_sec;
		(*timeo)->tv_usec = tv->tv_usec - tnow.tv_usec;
		if (tv->tv_usec < tnow.tv_usec) {
			(*timeo)->tv_usec += 1000000;
			(*timeo)->tv_sec -= 1;
		}
	}

done:
	/* Success! */
	return (0);

err1:
	free(*timeo);
err0:
	/* Failure! */
	return (-1);
}
Ejemplo n.º 3
0
/**
 * s3_serverpool_add(SP, sa, ttl):
 * Add the address ${sa} to the server pool ${SP} for the next ${ttl} seconds.
 * (If already in the pool, update the expiry time.)
 */
int
s3_serverpool_add(struct s3_serverpool * SP,
    const struct sock_addr *sa, int ttl)
{
	S3_SERVERPOOL S = (S3_SERVERPOOL)SP;
	struct timeval tv;
	struct timeval * tvo;
	struct s3_endpoint ep;
	size_t i;

	/* Compute EOL for this endpoint. */
	if (monoclock_get(&tv))
		goto err0;
	tv.tv_sec += ttl;

	/* Look for the endpoint. */
	for (i = 0; i < serverpool_getsize(S); i++) {
		if (sock_addr_cmp(sa, serverpool_get(S, i)->sa) == 0) {
			/* Update the EOL and return. */
			tvo = &serverpool_get(S, i)->eol;
			if ((tvo->tv_sec < tv.tv_sec) ||
			    ((tvo->tv_sec == tv.tv_sec) &&
			     (tvo->tv_usec < tv.tv_usec))) {
				tvo->tv_sec = tv.tv_sec;
				tvo->tv_usec = tv.tv_usec;
			}
			return (0);
		}
	}

	/* Construct a new endpoint structure. */
	if ((ep.sa = sock_addr_dup(sa)) == NULL)
		goto err0;
	ep.eol.tv_sec = tv.tv_sec;
	ep.eol.tv_usec = tv.tv_usec;

	/* Add the new endpoint to the list. */
	if (serverpool_append(S, &ep, 1))
		goto err1;

	/* Success! */
	return (0);

err1:
	free(ep.sa);
err0:
	/* Failure! */
	return (-1);
}
Ejemplo n.º 4
0
/**
 * events_timer_register(func, cookie, timeo):
 * Register ${func}(${cookie}) to be run ${timeo} in the future.  Return a
 * cookie which can be passed to events_timer_cancel or events_timer_reset.
 */
void *
events_timer_register(int (*func)(void *), void * cookie,
    const struct timeval * timeo)
{
	struct eventrec * r;
	struct timerrec * t;
	struct timeval tv;

	/* Create the timer queue if it doesn't exist yet. */
	if (Q == NULL) {
		if ((Q = timerqueue_init()) == NULL)
			goto err0;
	}

	/* Bundle into an eventrec record. */
	if ((r = events_mkrec(func, cookie)) == NULL)
		goto err0;

	/* Create a timer record. */
	if ((t = malloc(sizeof(struct timerrec))) == NULL)
		goto err1;
	t->r = r;
	memcpy(&t->tv_orig, timeo, sizeof(struct timeval));

	/* Compute the absolute timeout. */
	if (monoclock_get(&tv))
		goto err2;
	tv.tv_sec += t->tv_orig.tv_sec;
	if ((tv.tv_usec += t->tv_orig.tv_usec) >= 1000000) {
		tv.tv_usec -= 1000000;
		tv.tv_sec += 1;
	}

	/* Add this to the timer queue. */
	if ((t->cookie = timerqueue_add(Q, &tv, t)) == NULL)
		goto err2;

	/* Success! */
	return (t);

err2:
	free(t);
err1:
	events_freerec(r);
err0:
	/* Failure! */
	return (NULL);
}
Ejemplo n.º 5
0
static int
callback_get(void * cookie, int failed, struct kvldskey * value)
{
	struct hotspotread_state * C = cookie;
	struct timeval tv;

	/* This request is no longer in progress. */
	C->Nip -= 1;

	/* Did we fail? */
	if (failed) {
		C->done = 1;
		C->failed = 1;
	}

	/* If we have a value, free it. */
	if (failed == 0)
		kvldskey_free(value);

	/* Read the current time. */
	if (monoclock_get(&tv)) {
		warnp("Error reading clock");
		goto err0;
	}

	/* Are we finished?  Are we within the 50-60 second range? */
	if ((tv.tv_sec > C->tv_60.tv_sec) ||
	    ((tv.tv_sec == C->tv_60.tv_sec) &&
		(tv.tv_usec > C->tv_60.tv_usec))) {
		C->done = 1;
	} else if ((tv.tv_sec > C->tv_50.tv_sec) ||
	    ((tv.tv_sec == C->tv_50.tv_sec) &&
		(tv.tv_usec > C->tv_50.tv_usec))) {
		C->N += 1;
	}

	/* Send more requests if possible. */
	if (sendbatch(C))
		goto err0;

	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}
Ejemplo n.º 6
0
/**
 * s3_serverpool_pick(SP):
 * Pick an address from ${SP} and return it.  The caller is responsible for
 * freeing the address.
 */
struct sock_addr *
s3_serverpool_pick(struct s3_serverpool * SP)
{
	S3_SERVERPOOL S = (S3_SERVERPOOL)SP;
	struct timeval tv;
	struct timeval * tvo;
	struct sock_addr * sa;
	size_t i;

	/* If we have no endpoints, fail. */
	if (serverpool_getsize(S) == 0)
		goto err0;

	/* Delete expired endpoints; count down to avoid missing anything. */
	if (monoclock_get(&tv))
		goto err0;
	for (i = serverpool_getsize(S); i > 0; i--) {
		/* Is the EOL still in the future? */
		tvo = &serverpool_get(S, i - 1)->eol;
		if ((tvo->tv_sec > tv.tv_sec) ||
		    ((tvo->tv_sec == tv.tv_sec) &&
		     (tvo->tv_usec > tv.tv_usec)))
			continue;

		/* Is this the last remaining endpoint? */
		if (serverpool_getsize(S) == 1)
			continue;

		/* Delete this endpoint. */
		endpoint_free(S, i - 1);
	}

	/* Pick a (non-cryptographically) random endpoint. */
	i = (size_t)rand() % serverpool_getsize(S);

	/* Make a copy of the address. */
	if ((sa = sock_addr_dup(serverpool_get(S, i)->sa)) == NULL)
		goto err0;

	/* Return the address. */
	return (sa);

err0:
	/* Failure! */
	return (NULL);
}
Ejemplo n.º 7
0
/* Set tv := <current time> + tdelta. */
static int
gettimeout(struct timeval * tv, struct timeval * tdelta)
{

	if (monoclock_get(tv))
		goto err0;
	tv->tv_sec += tdelta->tv_sec;
	if ((tv->tv_usec += tdelta->tv_usec) >= 1000000) {
		tv->tv_usec -= 1000000;
		tv->tv_sec += 1;
	}

	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}
Ejemplo n.º 8
0
static void
printperf(struct bulkinsert_state * C)
{
	struct timeval tv;
	double T;
	uint64_t N;

	/* Get current time. */
	if (monoclock_get(&tv)) {
		warnp("Error reading clock");
		return;
	}

	/* Compute time difference. */
	T = (tv.tv_sec - C->tv_saved.tv_sec) +
	    (tv.tv_usec - C->tv_saved.tv_usec) * 0.000001;

	/* Compute number of requests between then and now. */
	N = C->Ndone - C->Ndone_saved;

	/* Everything completed before now was before 10 s. */
	if (T > 10.0) {
		T = 10.0;
		N -= 1;
	}

	/* Avoid microsecond precision rounding resulting in divide-by-0. */
	if (T < 0.000001)
		T = 0.000001;

	/*
	 * Print requests per second.  Skip this if we handled less than 4096
	 * requests, since that could be a burst of responses from a single
	 * bundle.
	 */
	if (N >= 4096)
		printf("%zu %.0f\n", C->Ndone_saved, N / T);

	/* We've printed this performance point. */
	C->Ndone_saved = 0;
}
Ejemplo n.º 9
0
/**
 * events_timer_get(r):
 * Return via ${r} a pointer to an eventrec structure corresponding to an
 * expired timer, and delete said timer; or to NULL if there are no expired
 * timers.  The caller is responsible for freeing the returned pointer.
 */
int
events_timer_get(struct eventrec ** r)
{
	struct timeval tnow;
	struct timerrec * t;

	/* If we have no queue, we have no timers; return NULL. */
	if (Q == NULL) {
		*r = NULL;
		goto done;
	}

	/* Get current time. */
	if (monoclock_get(&tnow))
		goto err0;

	/* Get an expired timer, if there is one. */
	t = timerqueue_getptr(Q, &tnow);

	/* If there is an expired timer... */
	if (t != NULL) {
		/* ... pass back the eventrec and free the timer. */
		*r = t->r;
		free(t);
	} else {
		/* Otherwise, return NULL. */
		*r = NULL;
	}

done:
	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}
Ejemplo n.º 10
0
static int
reconnect(NETPACKET_CONNECTION * NPC)
{
    struct timeval tp;
    int nseconds;

    /* Flush any pending activity on the socket. */
    if (netproto_flush(NPC->NC))
        goto err0;

    /* We're trying to reconnect. */
    NPC->state = 1;

    /* We're not reading a packet any more, if we ever were. */
    NPC->reading = 0;

    /* Have we lost our connection / failed to connect too many times? */
    NPC->ndrops += 1;
    if (tarsnap_opt_retry_forever && NPC->ndrops > MAXRECONNECTS)
        NPC->ndrops = MAXRECONNECTS;
    if ((NPC->ndrops > MAXRECONNECTS) ||
            (NPC->serveralive == 0 && NPC->ndrops > MAXRECONNECTS_AWOL)) {
        warn0("Too many network failures");
        goto err0;
    }

    /* Figure out how long we ought to wait before reconnecting. */
    nseconds = reconnect_wait[NPC->ndrops];

    /*
     * Warn the user that we're waiting, if we haven't already printed a
     * warning message recently.
     */
    if (monoclock_get(&tp))
        goto err0;
    if ((nseconds >= (tarsnap_opt_noisy_warnings ? 1 : 30)) &&
            ((tp.tv_sec > next_connlost_warning.tv_sec) ||
             ((tp.tv_sec == next_connlost_warning.tv_sec) &&
              (tp.tv_usec > next_connlost_warning.tv_usec)))) {
        warn0("Connection lost, "
              "waiting %d seconds before reconnecting", nseconds);
        next_connlost_warning.tv_sec = tp.tv_sec + nseconds;
        next_connlost_warning.tv_usec = tp.tv_usec;

        /*
         * Record that we printed a 'connection lost' warning for
         * this connection.
         */
        NPC->connlostmsgprinted = 1;
    }

    /* Set a callback to reconnect. */
    if (netproto_sleep(NPC->NC, nseconds, callback_reconnect, NPC))
        goto err0;

    /* Success! */
    return (0);

err0:
    /* Failure! */
    return (-1);
}