ia64/xen-unstable

changeset 18194:6cd615adaac7

xenconsoled: replace gettimeofday with clock_gettime

Currently if someone changes the date on the host, xenconsoled may
behave incorrectly due to the use of gettimeofday for the rate control
algorithm. For example I was able to hang the console connected to a
guest just setting the date forward 20 years. To solve the problem we
need to use a time source that doesn't change start point, that is
clock_gettime with CLOCK_MONOTONIC. The only bad side effect is that
it introduces a dependency to librt, but I think is well worth it.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jul 30 09:18:35 2008 +0100 (2008-07-30)
parents 39cb0de3ee2f
children b613bf4c4289
files tools/console/Makefile tools/console/daemon/io.c
line diff
     1.1 --- a/tools/console/Makefile	Tue Jul 29 17:00:29 2008 +0100
     1.2 +++ b/tools/console/Makefile	Wed Jul 30 09:18:35 2008 +0100
     1.3 @@ -21,7 +21,7 @@ clean:
     1.4  
     1.5  xenconsoled: $(patsubst %.c,%.o,$(wildcard daemon/*.c))
     1.6  	$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) \
     1.7 -              $(UTIL_LIBS) $(SOCKET_LIBS)
     1.8 +              $(UTIL_LIBS) $(SOCKET_LIBS) -lrt
     1.9  
    1.10  xenconsole: $(patsubst %.c,%.o,$(wildcard client/*.c))
    1.11  	$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) \
     2.1 --- a/tools/console/daemon/io.c	Tue Jul 29 17:00:29 2008 +0100
     2.2 +++ b/tools/console/daemon/io.c	Wed Jul 30 09:18:35 2008 +0100
     2.3 @@ -622,9 +622,9 @@ static struct domain *create_domain(int 
     2.4  {
     2.5  	struct domain *dom;
     2.6  	char *s;
     2.7 -	struct timeval tv;
     2.8 +	struct timespec ts;
     2.9  
    2.10 -	if (gettimeofday(&tv, NULL) < 0) {
    2.11 +	if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) {
    2.12  		dolog(LOG_ERR, "Cannot get time of day %s:%s:L%d",
    2.13  		      __FILE__, __FUNCTION__, __LINE__);
    2.14  		return NULL;
    2.15 @@ -666,7 +666,7 @@ static struct domain *create_domain(int 
    2.16  	dom->buffer.capacity = 0;
    2.17  	dom->buffer.max_capacity = 0;
    2.18  	dom->event_count = 0;
    2.19 -	dom->next_period = (tv.tv_sec * 1000) + (tv.tv_usec / 1000) + RATE_LIMIT_PERIOD;
    2.20 +	dom->next_period = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000) + RATE_LIMIT_PERIOD;
    2.21  	dom->next = NULL;
    2.22  
    2.23  	dom->ring_ref = -1;
    2.24 @@ -971,7 +971,7 @@ void handle_io(void)
    2.25  		struct domain *d, *n;
    2.26  		int max_fd = -1;
    2.27  		struct timeval timeout;
    2.28 -		struct timeval tv;
    2.29 +		struct timespec ts;
    2.30  		long long now, next_timeout = 0;
    2.31  
    2.32  		FD_ZERO(&readfds);
    2.33 @@ -985,9 +985,9 @@ void handle_io(void)
    2.34  			max_fd = MAX(xc_evtchn_fd(xce_handle), max_fd);
    2.35  		}
    2.36  
    2.37 -		if (gettimeofday(&tv, NULL) < 0)
    2.38 +		if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0)
    2.39  			return;
    2.40 -		now = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
    2.41 +		now = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
    2.42  
    2.43  		/* Re-calculate any event counter allowances & unblock
    2.44  		   domains with new allowance */