aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2024-09-06 21:49:37 +1000
committerStefano Brivio <sbrivio@redhat.com>2024-09-06 13:56:41 +0200
commit11e29054fe91ceaf59d2a500e09c4da262c7b23e (patch)
tree9eec2b38db15bd35649366eb48ff88665b734ba9
parent49fc4e0414610c6eadc6693fee4d5077d2e8097e (diff)
downloadpasst-11e29054fe91ceaf59d2a500e09c4da262c7b23e.tar
passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.tar.gz
passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.tar.bz2
passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.tar.lz
passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.tar.xz
passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.tar.zst
passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.zip
tap: Improve handling of EINTR in tap_passt_input()
When tap_passt_input() gets an error from recv() it (correctly) does not print any error message for EINTR, EAGAIN or EWOULDBLOCK. However in all three cases it returns from the function. That makes sense for EAGAIN and EWOULDBLOCK, since we then want to wait for the next EPOLLIN event before trying again. For EINTR, however, it makes more sense to retry immediately - as it stands we're likely to get a renewer EPOLLIN event immediately in that case, since we're using level triggered signalling. So, handle EINTR separately by immediately retrying until we succeed or get a different type of error. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--tap.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/tap.c b/tap.c
index c8abc06..8977b3f 100644
--- a/tap.c
+++ b/tap.c
@@ -1003,10 +1003,13 @@ static void tap_passt_input(struct ctx *c, const struct timespec *now)
memmove(pkt_buf, partial_frame, partial_len);
}
- n = recv(c->fd_tap, pkt_buf + partial_len, TAP_BUF_BYTES - partial_len,
- MSG_DONTWAIT);
+ do {
+ n = recv(c->fd_tap, pkt_buf + partial_len,
+ TAP_BUF_BYTES - partial_len, MSG_DONTWAIT);
+ } while ((n < 0) && errno == EINTR);
+
if (n < 0) {
- if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) {
+ if (errno != EAGAIN && errno != EWOULDBLOCK) {
err_perror("Receive error on guest connection, reset");
tap_sock_reset(c);
}