bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 2/5] libmachdev: Add resume for bootstrap server


From: Damien Zammit
Subject: [PATCH v2 2/5] libmachdev: Add resume for bootstrap server
Date: Sat, 25 Jul 2020 11:18:44 +1000

---
 libmachdev/ds_routines.c   |  15 +++-
 libmachdev/machdev.h       |   5 +-
 libmachdev/trivfs_server.c | 154 ++++++++++++++++++++++++++++++++-----
 3 files changed, 148 insertions(+), 26 deletions(-)

diff --git a/libmachdev/ds_routines.c b/libmachdev/ds_routines.c
index da5e47e2..53e0c080 100644
--- a/libmachdev/ds_routines.c
+++ b/libmachdev/ds_routines.c
@@ -65,6 +65,7 @@
 
 #include <hurd.h>
 #include <mach.h>
+#include <device/device.h> /* fallback to kernel device */
 
 #include "device_S.h"
 #include "notify_S.h"
@@ -94,7 +95,8 @@ ds_device_open (mach_port_t open_port, mach_port_t reply_port,
                 char *name, device_t *devp, mach_msg_type_name_t *devicePoly)
 {
   int i;
-  io_return_t err;
+  mach_port_t dev_master;
+  io_return_t err = D_NO_SUCH_DEVICE;
 
   /* Open must be called on the master device port.  */
   if (!machdev_is_master_device (open_port))
@@ -108,11 +110,18 @@ ds_device_open (mach_port_t open_port, mach_port_t 
reply_port,
   for (i = 0; i < num_emul; i++)
     {
       err = (*emulation_list[i]->open) (reply_port, reply_port_type,
-                                       mode, name, devp, devicePoly);
+                                        mode, name, devp, devicePoly);
       if (err != D_NO_SUCH_DEVICE)
-       break;
+        break;
     }
 
+  /* Fall back to opening kernel device master */
+  if (err)
+    {
+      get_privileged_ports(NULL, &dev_master);
+      err = device_open (dev_master, mode, name, devp);
+      *devicePoly = MACH_MSG_TYPE_MOVE_SEND;
+    }
   return err;
 }
 
diff --git a/libmachdev/machdev.h b/libmachdev/machdev.h
index 9b2dbd31..55a56e0d 100644
--- a/libmachdev/machdev.h
+++ b/libmachdev/machdev.h
@@ -32,9 +32,8 @@ void machdev_register (struct machdev_device_emulation_ops 
*ops);
 void machdev_device_init(void);
 void * machdev_server(void *);
 error_t machdev_create_device_port (size_t size, void *result);
-
-int machdev_trivfs_init(void);
-void machdev_trivfs_server(void);
+int machdev_trivfs_init(mach_port_t bootstrap_resume_task, const char *name, 
mach_port_t *bootstrap);
+void machdev_trivfs_server(mach_port_t bootstrap);
 boolean_t machdev_is_master_device (mach_port_t port);
 
 #endif
diff --git a/libmachdev/trivfs_server.c b/libmachdev/trivfs_server.c
index d6bafccb..05efde2e 100644
--- a/libmachdev/trivfs_server.c
+++ b/libmachdev/trivfs_server.c
@@ -27,9 +27,12 @@
 #include <hurd/ports.h>
 #include <hurd/trivfs.h>
 #include <hurd.h>
+#include <device/device.h> /* mach console */
 
+#include "libdiskfs/diskfs.h"
 #include "device_S.h"
 #include "notify_S.h"
+#include "fsys_S.h"
 
 static struct port_bucket *port_bucket;
 
@@ -90,13 +93,31 @@ do_mach_notify_dead_name (struct port_info *pi,
 boolean_t
 machdev_is_master_device (mach_port_t port)
 {
-  struct port_info *pi = ports_lookup_port (port_bucket, port,
+  struct port_info *pi0 = ports_lookup_port (port_bucket, port,
                                            trivfs_protid_class);
-  if (pi == NULL)
-    return FALSE;
+  struct port_info *pi1 = ports_lookup_port (port_bucket, port,
+                                           trivfs_cntl_class);
+  if (pi0 == NULL)
+    {
+      if (pi1 == NULL)
+        {
+          return FALSE;
+        }
+      else
+        {
+          ports_port_deref (pi1);
+          return TRUE;
+        }
+    }
+  else
+    {
+      ports_port_deref (pi0);
 
-  ports_port_deref (pi);
-  return TRUE;
+      if (pi1 != NULL)
+        ports_port_deref (pi1);
+
+      return TRUE;
+    }
 }
 
 error_t
@@ -114,11 +135,106 @@ trivfs_append_args (struct trivfs_control *fsys, char 
**argz, size_t *argz_len)
   return err;
 }
 
-int machdev_trivfs_init()
+/* This is fraud */
+kern_return_t
+trivfs_S_fsys_startup (mach_port_t bootport,
+                       mach_port_t reply,
+                       mach_msg_type_name_t replytype,
+                       int flags,
+                       mach_port_t cntl,
+                       mach_port_t *realnode,
+                       mach_msg_type_name_t *realnodetype)
+{
+  *realnode = MACH_PORT_NULL;
+  *realnodetype = MACH_MSG_TYPE_MOVE_SEND;
+  return 0;
+}
+
+/* Override the privileged ports for booting the system */
+kern_return_t
+trivfs_S_fsys_getpriv (struct diskfs_control *init_bootstrap_port,
+                       mach_port_t reply, mach_msg_type_name_t reply_type,
+                       mach_port_t *host_priv, mach_msg_type_name_t *hp_type,
+                       mach_port_t *dev_master, mach_msg_type_name_t *dm_type,
+                       mach_port_t *fstask, mach_msg_type_name_t *task_type)
+{
+  error_t err;
+  mach_port_t right;
+  struct port_info *server_info;
+
+  err = ports_create_port (trivfs_protid_class, port_bucket,
+                           sizeof (struct port_info), &server_info);
+  assert_perror_backtrace (err);
+  right = ports_get_send_right (server_info);
+  ports_port_deref (server_info);
+
+  err = get_privileged_ports (host_priv, NULL);
+  if (!err)
+    {
+      *dev_master = right;
+      *fstask = mach_task_self ();
+      *hp_type = *dm_type = MACH_MSG_TYPE_COPY_SEND;
+      *task_type = MACH_MSG_TYPE_COPY_SEND;
+    }
+  return err;
+}
+
+static void
+resume_bootstrap_server(mach_port_t server_task, const char *server_name)
+{
+  error_t err;
+  mach_port_t right;
+  mach_port_t dev, cons;
+  struct port_info *server_info;
+
+  assert_backtrace (server_task != MACH_PORT_NULL);
+
+  err = ports_create_port (trivfs_cntl_class, port_bucket,
+                           sizeof (struct port_info), &server_info);
+  assert_perror_backtrace (err);
+  right = ports_get_send_right (server_info);
+  ports_port_deref (server_info);
+  err = task_set_special_port (server_task, TASK_BOOTSTRAP_PORT, right);
+  assert_perror_backtrace (err);
+  err = mach_port_deallocate (mach_task_self (), right);
+  assert_perror_backtrace (err);
+
+  err = task_resume (server_task);
+  assert_perror_backtrace (err);
+
+  /* Make sure we have a console */
+  err = get_privileged_ports (NULL, &dev);
+  assert_perror_backtrace (err);
+  err = device_open (dev, D_READ|D_WRITE, "console", &cons);
+  mach_port_deallocate (mach_task_self (), dev);
+  assert_perror_backtrace (err);
+  stdin = mach_open_devstream (cons, "r");
+  stdout = stderr = mach_open_devstream (cons, "w");
+  mach_port_deallocate (mach_task_self (), cons);
+
+  printf (" %s", server_name);
+  fflush (stdout);
+}
+
+int
+machdev_trivfs_init(mach_port_t bootstrap_resume_task, const char *name, 
mach_port_t *bootstrap)
 {
   port_bucket = ports_create_bucket ();
   trivfs_cntl_class = ports_create_class (trivfs_clean_cntl, 0);
   trivfs_protid_class = ports_create_class (trivfs_clean_protid, 0);
+
+  if (bootstrap_resume_task != MACH_PORT_NULL)
+    {
+      resume_bootstrap_server(bootstrap_resume_task, name);
+      *bootstrap = MACH_PORT_NULL;
+    }
+  else
+    {
+      task_get_bootstrap_port (mach_task_self (), bootstrap);
+      if (*bootstrap == MACH_PORT_NULL)
+        error (1, 0, "must be started as a translator");
+    }
+
   return 0;
 }
 
@@ -166,23 +282,21 @@ trivfs_modify_stat (struct trivfs_protid *cred, 
io_statbuf_t *stat)
 {
 }
 
-void machdev_trivfs_server()
+void
+machdev_trivfs_server(mach_port_t bootstrap)
 {
-  mach_port_t bootstrap;
-  struct trivfs_control *fsys;
+  struct trivfs_control *fsys = NULL;
   int err;
 
-  task_get_bootstrap_port (mach_task_self (), &bootstrap);
-  if (bootstrap == MACH_PORT_NULL)
-    error (1, 0, "must be started as a translator");
-
-  /* Reply to our parent.  */
-  err = trivfs_startup (bootstrap, 0,
-                       trivfs_cntl_class, port_bucket,
-                       trivfs_protid_class, port_bucket, &fsys);
-  mach_port_deallocate (mach_task_self (), bootstrap);
-  if (err)
-    error (1, err, "Contacting parent");
+  if (bootstrap != MACH_PORT_NULL)
+    {
+      err = trivfs_startup (bootstrap, 0,
+                            trivfs_cntl_class, port_bucket,
+                            trivfs_protid_class, port_bucket, &fsys);
+      mach_port_deallocate (mach_task_self (), bootstrap);
+      if (err)
+        error (1, err, "Contacting parent");
+    }
 
   /* Launch.  */
   do
-- 
2.25.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]