On 7/1/20 2:17 AM, Richard W.M. Jones wrote:
This option didn't work except when using --foreground (or using
another option that implies this). This is because it creates a
background reader thread, but that thread is invalidated if nbdkit
forks, resulting in deadlocks because the worker threads are
fruitlessly sending notifications to a background thread that no
longer exists.
The fix is to move this work to .after_fork.
---
plugins/nbd/nbd.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
Good catch.
diff --git a/plugins/nbd/nbd.c b/plugins/nbd/nbd.c
index 05f78777..91ed91e0 100644
--- a/plugins/nbd/nbd.c
+++ b/plugins/nbd/nbd.c
@@ -109,7 +109,7 @@ static void nbdplug_close_handle (struct handle *h);
static void
nbdplug_unload (void)
{
- if (shared)
+ if (shared && shared_handle)
nbdplug_close_handle (shared_handle);
free (sockname);
free (tls_certificates);
@@ -266,8 +266,15 @@ nbdplug_config_complete (void)
}
nbd_close (nbd);
}
+ return 0;
+}
- /* Create the shared connection. */
+/* Create the shared connection. Because this may create a background
+ * thread it must be done after we fork.
+ */
+static int
+nbdplug_after_fork (void)
+{
if (shared && (shared_handle = nbdplug_open_handle (false)) == NULL)
return -1;
return 0;
@@ -858,6 +865,7 @@ static struct nbdkit_plugin plugin = {
.config_complete = nbdplug_config_complete,
.config_help = nbdplug_config_help,
.magic_config_key = "uri",
+ .after_fork = nbdplug_after_fork,
.dump_plugin = nbdplug_dump_plugin,
.open = nbdplug_open,
.close = nbdplug_close,
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization:
qemu.org |
libvirt.org