Currently, rumpdisk initializes the Rump kernel and probes the PCI bus
immediately during main(). When rumpdisk is configured as a passive translator
(e.g., for /dev/rumpusbdisk), a simple stat or ls on the node triggers
translator startup. This causes a second Rump instance to attempt to probe
hardware already owned by the primary disk driver, leading to a system-wide
deadlock.
To reproduce:
stat /dev/rumpdiskusb
(rump starts again ... deadlock)
With this patch:
stat /dev/rumpdiskusb
(normal printout of stats, no deadlock)
---
rumpdisk/main.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/rumpdisk/main.c b/rumpdisk/main.c
index 3676b472..0bd753e2 100644
--- a/rumpdisk/main.c
+++ b/rumpdisk/main.c
@@ -40,6 +40,15 @@
mach_port_t bootstrap_resume_task = MACH_PORT_NULL;
+static pthread_once_t rump_hw_initialized = PTHREAD_ONCE_INIT;
+
+static void
+do_rump_hw_init (void)
+{
+ mach_print("rumpdisk: Initializing Rump block device layer...\n");
+ rump_register_block ();
+}
+
static const struct argp_option options[] = {
{"host-priv-port", 'h', "PORT", 0, "Host private port PORT"},
{"device-master-port",'d', "PORT", 0, "Device master port PORT"},
@@ -102,6 +111,7 @@ static const struct argp *rumpdisk_argp_bootup =
&rumpdisk_argp;
static int __thread wired = 0;
static int rumpdisk_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
{
+ pthread_once (&rump_hw_initialized, do_rump_hw_init);
/* FIXME: we are not wired while receiving our first message. */
if (!wired)
{
@@ -150,7 +160,6 @@ main (int argc, char **argv)
error(1, err, "Missing parameters for bootstrap");
}
- rump_register_block ();
machdev_trivfs_init (argc, argv, bootstrap_resume_task, RUMPNAME, "/dev/"
RUMPNAME, &bootstrap);
/* Make sure we will not swap out, in case we drive the disk used for
@@ -162,6 +171,9 @@ main (int argc, char **argv)
if (err != KERN_SUCCESS)
error (1, err, "cannot get vm_privilege");
+ if (bootstrap_resume_task != MACH_PORT_NULL)
+ pthread_once (&rump_hw_initialized, do_rump_hw_init);
+
machdev_device_init ();
err = pthread_create (&t, NULL, rumpdisk_multithread_server, NULL);
if (err)
--
2.52.0