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


Reply via email to