Nothing in the second loop of nbd_reader() was ever setting
quit; the only way the loop could end was via SEGV for
dereferencing NULL or abort() when attempting to write to
an invalid fd. Finish the implementation to properly mop
up stranded in-flight requests.
The testsuite did not exercise the case of quitting
nbdkit while a transaction was in flight, but was relying
on SIGTERM exiting the entire process before all threads
were reaped; otherwise, I might have spotted this sooner.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
plugins/nbd/nbd.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/plugins/nbd/nbd.c b/plugins/nbd/nbd.c
index a4a9639..df49a1d 100644
--- a/plugins/nbd/nbd.c
+++ b/plugins/nbd/nbd.c
@@ -384,15 +384,16 @@ nbd_reader (void *handle)
}
/* Clean up any stranded in-flight requests */
- done = false;
r = ESHUTDOWN;
- while (!done) {
+ while (1) {
struct transaction *trans;
nbd_lock (h);
trans = h->trans;
- h->trans = trans->next;
+ h->trans = trans ? trans->next : NULL;
nbd_unlock (h);
+ if (!trans)
+ break;
if (write (trans->u.fds[1], &r, sizeof r) != sizeof r) {
nbdkit_error ("failed to write pipe: %m");
abort ();
--
2.13.6