From 58e58ffbc0b12efbe00c9ad5f23d71d75790b524 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 5 Feb 2007 15:37:55 +1100 Subject: [PATCH 1/1] Make UDP sockets not blocking This is needs if mountd is running multithreaded else multiple threads will be blocked on a UDP port with nothing to read and so won't be able to serve up-calls from the kernel. Thanks to "Murali Krishna V" for highlighting the problem. --- support/nfs/svc_socket.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/support/nfs/svc_socket.c b/support/nfs/svc_socket.c index d712cab..3307600 100644 --- a/support/nfs/svc_socket.c +++ b/support/nfs/svc_socket.c @@ -113,11 +113,22 @@ svc_socket (u_long number, int type, int protocol, int reuse) } } - if (sock >= 0 && protocol == IPPROTO_TCP) + if (sock >= 0) { - /* Make the TCP rendezvous socket non-block to avoid - * problems with blocking in accept() after a spurious - * wakeup from the kernel */ + /* This socket might be shared among multiple processes + * if mountd is run multi-threaded. So it is safest to + * make it non-blocking, else all threads might wake + * one will get the data, and the others will block + * indefinitely. + * In all cases, transaction on this socket are atomic + * (accept for TCP, packet-read and packet-write for UDP) + * so O_NONBLOCK will not confuse unprepared code causing + * it to corrupt messages. + * It generally safest to have O_NONBLOCK when doing an accept + * as if we get a RST after the SYN and before accept runs, + * we can block despite being told there was an acceptable + * connection. + */ int flags; if ((flags = fcntl(sock, F_GETFL)) < 0) { -- 2.39.2