aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorYumei Huang <yuhuang@redhat.com>2025-09-12 16:17:05 +0800
committerStefano Brivio <sbrivio@redhat.com>2025-09-25 20:25:46 +0200
commite81c692e460ad3d0b717eeea8e7c16d93ea207fe (patch)
tree4e6b3e8055e2a2c4b4f0c9cd135a370706f83683
parent623dbf6f16d8dedac5a361a0d1daadc772ac842b (diff)
downloadpasst-e81c692e460ad3d0b717eeea8e7c16d93ea207fe.tar
passt-e81c692e460ad3d0b717eeea8e7c16d93ea207fe.tar.gz
passt-e81c692e460ad3d0b717eeea8e7c16d93ea207fe.tar.bz2
passt-e81c692e460ad3d0b717eeea8e7c16d93ea207fe.tar.lz
passt-e81c692e460ad3d0b717eeea8e7c16d93ea207fe.tar.xz
passt-e81c692e460ad3d0b717eeea8e7c16d93ea207fe.tar.zst
passt-e81c692e460ad3d0b717eeea8e7c16d93ea207fe.zip
tap: Drop frames if no client connected
If no client is attached, discard outgoing frames and report them as sent. Without this we will get an EBADF in either writev() (pasta) or sendmsg() (passt). That's basically harmless, but a bit ugly. Explicitly catching this case results in behaviour that's probably a bit clearer to debug if we hit it. There are several different approaches we can take here. Here's some reasoning as David explained: * Don't listen() until the tap connection is ready - It's not clear that the host rejecting the connection is better than the host accepting, then the connection stalling until the guest is ready. - Would require substantial rework because we currently listen() as we parse the command line and don't store the information we'd need to do it later. * Don't accept() until the tap connection is ready - To the peer, will behave basically the same as this patch - the host will complete the TCP handshake, then the connection will stall until the guest is ready. - More work to implement, because essentially every sock-side handler has to check fd_tap and abort early * Drop packets in tap_send_frames(), but return 0 - To the peer, would behave basically the same - Would make the TCP code do a bunch of busy work attempting to resend, probably to no avail - Handling of errors returned by tap_send_frames() is on the basis that it's probably a transient fault (buffer full) and we want to resend very soon. That approach doesn't make sense for a missing guest. Suggested-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Yumei Huang <yuhuang@redhat.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--tap.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/tap.c b/tap.c
index 399eeaa..95d309b 100644
--- a/tap.c
+++ b/tap.c
@@ -507,13 +507,16 @@ static size_t tap_send_frames_passt(const struct ctx *c,
* @iov must have total length @bufs_per_frame * @nframes, with each set of
* @bufs_per_frame contiguous buffers representing a single frame.
*
- * Return: number of frames actually sent
+ * Return: number of frames actually sent, or accounted as sent
*/
size_t tap_send_frames(const struct ctx *c, const struct iovec *iov,
size_t bufs_per_frame, size_t nframes)
{
size_t m;
+ if (c->fd_tap == -1)
+ return nframes;
+
if (!nframes)
return 0;