From a9bdef23522b5a2ff2a7ec07c3e0573885b46ecb Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Fri, 26 Jan 2024 17:47:41 -0800 Subject: [PATCH] More accurately replicate Linux's Unix domain socket event notification. The documentation for EPOLLET (which repeatedly instructs users to read/write until EAGAIN or short read) suggests that its intent is to only cause an epoll notification when an FD registered with EPOLLET transitions from not-readable to readable, or not-writable to writable. In practice, however, the actual implementation for at least Unix domain sockets will trigger an epoll notification on *every* send (cf. `net/unix/af_unix.c:unix_stream_sendmsg()` => "`other->sk_data_ready(other)`" => `net/core/sock.c:sock_def_readable()`), and nginx (which registers Unix domain sockets with EPOLLET and - apparently incorrectly - does *not* read from them until EAGAIN or short read) depends on this property. PiperOrigin-RevId: 601911295 --- pkg/sentry/socket/unix/transport/queue.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pkg/sentry/socket/unix/transport/queue.go b/pkg/sentry/socket/unix/transport/queue.go index 5a86e643e..1ea1f8789 100644 --- a/pkg/sentry/socket/unix/transport/queue.go +++ b/pkg/sentry/socket/unix/transport/queue.go @@ -167,7 +167,7 @@ func (q *queue) Enqueue(ctx context.Context, data [][]byte, c ControlMessages, f b = b[n:] } - notify = q.dataList.Front() == nil + notify = true q.used += l q.dataList.PushBack(&message{ Data: v, @@ -200,13 +200,11 @@ func (q *queue) Dequeue() (e *message, notify bool, err *syserr.Error) { return nil, false, err } - notify = !q.bufWritable() - e = q.dataList.Front() q.dataList.Remove(e) q.used -= e.Length() - notify = notify && q.bufWritable() + notify = q.bufWritable() q.mu.Unlock()