summaryrefslogtreecommitdiffstats
path: root/support/nfs/svc_socket.c
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2007-02-05 15:37:55 +1100
committerNeil Brown <neilb@suse.de>2007-02-05 15:37:55 +1100
commit58e58ffbc0b12efbe00c9ad5f23d71d75790b524 (patch)
tree578568c1fe693ecdc16be671630c342b734b8aa5 /support/nfs/svc_socket.c
parent36959539fad2a5f125151a2e8bedb284d53b8c74 (diff)
downloadnfs-utils-58e58ffbc0b12efbe00c9ad5f23d71d75790b524.tar.gz
nfs-utils-58e58ffbc0b12efbe00c9ad5f23d71d75790b524.tar.xz
nfs-utils-58e58ffbc0b12efbe00c9ad5f23d71d75790b524.zip
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" <vm.krishna@gmail.com> for highlighting the problem.
Diffstat (limited to 'support/nfs/svc_socket.c')
-rw-r--r--support/nfs/svc_socket.c19
1 files 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)
{