]> xenbits.xensource.com Git - libvirt.git/commitdiff
Fix errno check, prevent spurious errors under heavy load
authorPeter Feiner <peter@gridcentric.ca>
Wed, 8 Aug 2012 20:59:41 +0000 (16:59 -0400)
committerEric Blake <eblake@redhat.com>
Wed, 8 Aug 2012 21:50:58 +0000 (15:50 -0600)
From man poll(2), poll does not set errno=EAGAIN on interrupt, however
it does set errno=EINTR. Have libvirt retry on the appropriate errno.

Under heavy load, a program of mine kept getting libvirt errors 'poll on
socket failed: Interrupted system call'. The signals were SIGCHLD from
processes forked by threads unrelated to those using libvirt.

AUTHORS
src/rpc/virnetclient.c
src/util/event_poll.c

diff --git a/AUTHORS b/AUTHORS
index 1a7a4aceb5c719fd2590291c4559d0292f60fc45..a9accb20c843c0c872f8824f01f943feb2383cfd 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -253,6 +253,7 @@ Patches have also been contributed by:
   Ata E Husain Bohra   <ata.husain@hotmail.com>
   Ján Tomko            <jtomko@redhat.com>
   Richa Marwaha        <rmarwah@linux.vnet.ibm.com>
+  Peter Feiner         <peter@gridcentric.ca>
 
   [....send patches to get your name here....]
 
index 2530ffaecf7ef96b77ff09c35c3055afccd6f6fd..42bdc54d45f507b86b130dadde4068c050b7cd8c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * virnetclient.c: generic network RPC client
  *
- * Copyright (C) 2006-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2012 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -651,7 +651,7 @@ int virNetClientSetTLSSession(virNetClientPtr client,
 
     repoll:
         ret = poll(fds, ARRAY_CARDINALITY(fds), -1);
-        if (ret < 0 && errno == EAGAIN)
+        if (ret < 0 && (errno == EAGAIN || errno == EINTR))
             goto repoll;
 
         ignore_value(pthread_sigmask(SIG_BLOCK, &oldmask, NULL));
@@ -675,7 +675,7 @@ int virNetClientSetTLSSession(virNetClientPtr client,
 
     repoll2:
     ret = poll(fds, ARRAY_CARDINALITY(fds), -1);
-    if (ret < 0 && errno == EAGAIN)
+    if (ret < 0 && (errno == EAGAIN || errno == EINTR))
         goto repoll2;
 
     ignore_value(pthread_sigmask(SIG_BLOCK, &oldmask, NULL));
@@ -1374,7 +1374,7 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
 
     repoll:
         ret = poll(fds, ARRAY_CARDINALITY(fds), timeout);
-        if (ret < 0 && errno == EAGAIN)
+        if (ret < 0 && (errno == EAGAIN || errno == EINTR))
             goto repoll;
 
         ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));
index 1bc1d41329c62c0650d099baaef9c9940670db6e..0e7d1c119cb1887d3172859cfc9f817f3cac4313 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * event.c: event loop for monitoring file handles
  *
- * Copyright (C) 2007, 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2007, 2010-2012 Red Hat, Inc.
  * Copyright (C) 2007 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -615,7 +615,7 @@ int virEventPollRunOnce(void) {
     ret = poll(fds, nfds, timeout);
     if (ret < 0) {
         EVENT_DEBUG("Poll got error event %d", errno);
-        if (errno == EINTR) {
+        if (errno == EINTR || errno == EAGAIN) {
             goto retry;
         }
         virReportSystemError(errno, "%s",