[libvirt] [PATCH] Fix errno check, prevent spurious errors under heavy load

Eric Blake eblake at redhat.com
Wed Aug 8 21:53:51 UTC 2012


On 08/08/2012 02:59 PM, Peter Feiner wrote:
>>From man poll(2), poll does not set errno=EAGAIN, however it does set
> errno=EINTR. Have libvirt retry on the appropriate errno.

man poll(2) is slightly wrong - according to POSIX, poll may _also_ set
EAGAIN when "The allocation of internal data structures failed but a
subsequent request may succeed."  But you are correct that poll()
interrupted by a signal must be EINTR.

I went looking (git grep -A3 '\bpoll *([a-zA-Z]'), and some of our code
already checks for _both_ EAGAIN and EINTR, so I'd feel safer updating
ALL the code to check for both instead of one.

> 
> 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.
> 
> diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
> index 2530ffa..f2a6922 100644
> --- a/src/rpc/virnetclient.c
> +++ b/src/rpc/virnetclient.c
> @@ -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 == EINTR)
>              goto repoll;
> 
>          ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));
> 

I squashed this into your change, and pushed.  I also added you to
AUTHORS; let me know if you prefer an alternate spelling of name or email.

diff --git i/src/rpc/virnetclient.c w/src/rpc/virnetclient.c
index 2530ffa..42bdc54 100644
--- i/src/rpc/virnetclient.c
+++ w/src/rpc/virnetclient.c
@@ -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));
diff --git i/src/util/event_poll.c w/src/util/event_poll.c
index 1bc1d41..0e7d1c1 100644
--- i/src/util/event_poll.c
+++ w/src/util/event_poll.c
@@ -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",


-- 
Eric Blake   eblake at redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 620 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20120808/de8aa964/attachment-0001.sig>


More information about the libvir-list mailing list