aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block.c1
-rw-r--r--qemu-nbd.c1
-rw-r--r--softmmu/runstate.c9
-rw-r--r--storage-daemon/qemu-storage-daemon.c1
4 files changed, 11 insertions, 1 deletions
diff --git a/block.c b/block.c
index 5c428e1595..4e52b1c588 100644
--- a/block.c
+++ b/block.c
@@ -4435,7 +4435,6 @@ static void bdrv_close(BlockDriverState *bs)
void bdrv_close_all(void)
{
assert(job_next(NULL) == NULL);
- blk_exp_close_all();
/* Drop references from requests still in flight, such as canceled block
* jobs whose AIO context has not been polled yet */
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 0d513cb38c..608c63e82a 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -503,6 +503,7 @@ static const char *socket_activation_validate_opts(const char *device,
static void qemu_nbd_shutdown(void)
{
job_cancel_sync_all();
+ blk_exp_close_all();
bdrv_close_all();
}
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
index beee050815..a7fcb603f7 100644
--- a/softmmu/runstate.c
+++ b/softmmu/runstate.c
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "audio/audio.h"
#include "block/block.h"
+#include "block/export.h"
#include "chardev/char.h"
#include "crypto/cipher.h"
#include "crypto/init.h"
@@ -785,6 +786,14 @@ void qemu_cleanup(void)
migration_shutdown();
/*
+ * Close the exports before draining the block layer. The export
+ * drivers may have coroutines yielding on it, so we need to clean
+ * them up before the drain, as otherwise they may be get stuck in
+ * blk_wait_while_drained().
+ */
+ blk_exp_close_all();
+
+ /*
* We must cancel all block jobs while the block layer is drained,
* or cancelling will be affected by throttling and thus may block
* for an extended period of time.
diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c
index e0c87edbdd..d8d172cc60 100644
--- a/storage-daemon/qemu-storage-daemon.c
+++ b/storage-daemon/qemu-storage-daemon.c
@@ -314,6 +314,7 @@ int main(int argc, char *argv[])
main_loop_wait(false);
}
+ blk_exp_close_all();
bdrv_drain_all_begin();
bdrv_close_all();