56 lines
1.9 KiB
Diff
56 lines
1.9 KiB
Diff
From 48136328150bc587178091b5766bda382158cb6c Mon Sep 17 00:00:00 2001
|
||
From: Nir Soffer <nsoffer@redhat.com>
|
||
Date: Sat, 23 Oct 2021 00:08:31 +0300
|
||
Subject: [PATCH] lib/poll.c: Retry poll after EINTR
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
I see a rare random failure when calling BlockStatus via Go binding:
|
||
|
||
block_status: nbd_block_status: poll: Interrupted system call
|
||
|
||
I could not reproduce this with "nbdinfo --map", even after modifying it
|
||
to call nbd_block_status() for every 128 MiB.
|
||
|
||
Fixing this in nbd_unlock_poll() avoids this issue in the entire
|
||
library, when we wait for command completion. This seems more useful
|
||
that fixing it in all libnbd clients.
|
||
|
||
Tested using a go client listing all extents in an image, calling
|
||
BlockStatus for every 128m with fedora 34 qcow2 image. Without this fix,
|
||
this was always failing.
|
||
|
||
$ hyperfine -r1000 --show-output "./client nbd+unix://?socket=/tmp/nbd.sock > /dev/null"
|
||
Benchmark 1: ./client nbd+unix://?socket=/tmp/nbd.sock > /dev/null
|
||
Time (mean ± σ): 31.6 ms ± 3.1 ms [User: 8.8 ms, System: 7.2 ms]
|
||
Range (min … max): 26.1 ms … 52.3 ms 1000 runs
|
||
|
||
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
|
||
(cherry picked from commit b3440853cdeca0e44ad9c526e71faaa6cf344bfc)
|
||
---
|
||
lib/poll.c | 7 +++++--
|
||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||
|
||
diff --git a/lib/poll.c b/lib/poll.c
|
||
index edfcc59..df01d94 100644
|
||
--- a/lib/poll.c
|
||
+++ b/lib/poll.c
|
||
@@ -57,8 +57,11 @@ nbd_unlocked_poll (struct nbd_handle *h, int timeout)
|
||
* would allow other threads to close file descriptors which we have
|
||
* passed to poll.
|
||
*/
|
||
- r = poll (fds, 1, timeout);
|
||
- debug (h, "poll end: r=%d revents=%x", r, fds[0].revents);
|
||
+ do {
|
||
+ r = poll (fds, 1, timeout);
|
||
+ debug (h, "poll end: r=%d revents=%x", r, fds[0].revents);
|
||
+ } while (r == -1 && errno == EINTR);
|
||
+
|
||
if (r == -1) {
|
||
set_error (errno, "poll");
|
||
return -1;
|
||
--
|
||
2.31.1
|
||
|