nbd: Don't read after client sends NBD_CMD_DISC
commitc70616f87c72ae1e10c29d91609fc3760fd96a95
authorEric Blake <eblake@redhat.com>
Thu, 19 Apr 2018 01:32:21 +0000 (18 20:32 -0500)
committerEric Blake <eblake@redhat.com>
Thu, 19 Apr 2018 02:43:14 +0000 (18 21:43 -0500)
treec1177cc27ed8c40e8d17cc45112650a9d4febc39
parent430f81410260d847ad46b1369024c079f7153578
nbd: Don't read after client sends NBD_CMD_DISC

According to the NBD spec, the server should close the connection
rather than replying to NBD_CMD_DISC (after flushing any pending
replies to earlier commands), and a compliant client should not
send any data after that command.  However, when nbdkit is
running multithreaded, we already have multiple threads competing
for a read lock, and each of those threads would try to read()
from the socket, which will never make progress unless the client
hangs up so that the read fails with EOF.

But if the client waits to close its end until after seeing EOF
from the server (as was the case with the nbd plugin as the client
until the previous patch), then both sides are deadlocked on a
read.  We already short-circuit a read attempt when the socket
is closed; we should likewise avoid a read attempt after the
client has requested a disconnect, so that we aren't at the
mercy of the client properly using shutdown().

Note that this patch in isolation without the previous patch to
the nbd plugin is sufficient to make the testsuite deadlock go
away.

Signed-off-by: Eric Blake <eblake@redhat.com>
src/connections.c