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(-) 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, -- 2.25.0