Skip to contentSkip to conversation

replacing gettimeofday with clock_gettime in xenconsoled

PATCH New Stefano Stabellini 1 participant 1 message Jul 29, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 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.

---

tools/console/Makefile +1 -1
diff -r a538185695ed tools/console/Makefile
@@ -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) \
tools/console/daemon/io.c +7 -7
diff -r a538185695ed tools/console/daemon/io.c
@@ -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 */