VDDK creates background threads. fork kills these, resulting in the
library hanging or failing completely in certain configurations.
---
plugins/vddk/vddk.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c
index e6639b4d..a481e8bf 100644
--- a/plugins/vddk/vddk.c
+++ b/plugins/vddk/vddk.c
@@ -431,12 +431,31 @@ vddk_config_complete (void)
return 0;
}
+#define vddk_config_help \
+ "[file=]<FILENAME> (required) The filename (eg. VMDK file) to
serve.\n" \
+ "Many optional parameters are supported, see nbdkit-vddk-plugin(3)."
+
static int
vddk_get_ready (void)
{
- VixError err;
-
load_library (true);
+ return 0;
+}
+
+/* Defer VDDK initialization until after fork because it is known to
+ * create background threads from VixDiskLib_InitEx. Unfortunately
+ * error reporting from this callback is difficult, but we have
+ * already checked in .get_ready that the library is dlopenable.
+ *
+ * For various hangs and failures which were caused by background
+ * threads and fork see:
+ *
https://bugzilla.redhat.com/show_bug.cgi?id=1846309#c9
+ *
https://www.redhat.com/archives/libguestfs/2019-April/msg00090.html
+ */
+static int
+vddk_after_fork (void)
+{
+ VixError err;
/* Initialize VDDK library. */
DEBUG_CALL ("VixDiskLib_InitEx",
@@ -457,10 +476,6 @@ vddk_get_ready (void)
return 0;
}
-#define vddk_config_help \
- "[file=]<FILENAME> (required) The filename (eg. VMDK file) to
serve.\n" \
- "Many optional parameters are supported, see nbdkit-vddk-plugin(3)."
-
static void
vddk_dump_plugin (void)
{
@@ -959,6 +974,7 @@ static struct nbdkit_plugin plugin = {
.magic_config_key = "file",
.dump_plugin = vddk_dump_plugin,
.get_ready = vddk_get_ready,
+ .after_fork = vddk_after_fork,
.open = vddk_open,
.close = vddk_close,
.get_size = vddk_get_size,
--
2.25.0