Stefano Stabellini
2008-Jul-29 15:31 UTC
[Xen-devel] [PATCH] replacing gettimeofday with clock_gettime in xenconsoled
Hi all, 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> --- diff -r a538185695ed tools/console/Makefile --- a/tools/console/Makefile Tue Jul 29 15:10:58 2008 +0100 +++ b/tools/console/Makefile Tue Jul 29 15:47:29 2008 +0100 @@ -21,7 +21,7 @@ clean: xenconsoled: $(patsubst %.c,%.o,$(wildcard daemon/*.c)) $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) \ - $(UTIL_LIBS) $(SOCKET_LIBS) + $(UTIL_LIBS) $(SOCKET_LIBS) -lrt xenconsole: $(patsubst %.c,%.o,$(wildcard client/*.c)) $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) \ diff -r a538185695ed tools/console/daemon/io.c --- a/tools/console/daemon/io.c Tue Jul 29 15:10:58 2008 +0100 +++ b/tools/console/daemon/io.c Tue Jul 29 15:44:59 2008 +0100 @@ -622,9 +622,9 @@ static struct domain *create_domain(int { struct domain *dom; char *s; - struct timeval tv; - - if (gettimeofday(&tv, NULL) < 0) { + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) { dolog(LOG_ERR, "Cannot get time of day %s:%s:L%d", __FILE__, __FUNCTION__, __LINE__); return NULL; @@ -666,7 +666,7 @@ static struct domain *create_domain(int dom->buffer.capacity = 0; dom->buffer.max_capacity = 0; dom->event_count = 0; - dom->next_period = (tv.tv_sec * 1000) + (tv.tv_usec / 1000) + RATE_LIMIT_PERIOD; + dom->next_period = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000) + RATE_LIMIT_PERIOD; dom->next = NULL; dom->ring_ref = -1; @@ -971,7 +971,7 @@ void handle_io(void) struct domain *d, *n; int max_fd = -1; struct timeval timeout; - struct timeval tv; + struct timespec ts; long long now, next_timeout = 0; FD_ZERO(&readfds); @@ -985,9 +985,9 @@ void handle_io(void) max_fd = MAX(xc_evtchn_fd(xce_handle), max_fd); } - if (gettimeofday(&tv, NULL) < 0) + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) return; - now = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); + now = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); /* Re-calculate any event counter allowances & unblock domains with new allowance */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel