Re: [PATCH] Adding-storeio-to-the-bootstrap-chain.

Mikhail Karpov <[email protected]>
Newsgroups gmane.os.hurd.bugs
Message-ID <[email protected]>
Hello,

On Tue, 28 Apr 2026 23:01:42 Samuel Thibault wrote:

Well, I managed to stop using libmachdev, but I still couldn't get the 
store from storeio.

 > Opening the store can be done provided that you have the bootstrap
 > port.  And you have it from the special port, you can just pick it
 > up with task_get_bootstrap_port and use it. You just need to make
 > sure that storeio resumes the next task after being ready to serve
 > file_get_storage_info.

Passing the storeio_port obtained from task_get_bootstrap_port to 
store_create
doesn't produce an invalid port error, but it turns out that in this case,
cred = NULL is passed to trivfs_S_file_get_storage_info. I discovered 
that the
problem was that trivfs_begin_using_protid_payload couldn't find a suitable
class from trivfs_dynamic_protid_port_classes. I'm also confused about where
and with what parameters fsys_getroot should be called. I tried calling 
it in
storeio_bootstrap_startup after task_resume (next_task) with the
storeio_fsys->underlying parameter (I understand correctly that this is the
storeio process control port, right?), but this doesn't produce any results.

 > Not sure what you mean. You don't need to interact with exec etc. before
 > interacting with storeio and rumpdisk.

As far as I understand, the mechanism for calling exec from ext2fs is 
roughly
analogous to what storeio requires for ext2fs. However, it expects 
fsys_startup
to be called from exec, so I don't think it's very applicable...

Thanks,

-- 
Mikhail Karpov
0001-Adding-storeio-to-the-bootstrap-chain.patch (text/x-patch, 12.2 KB)
From a525e64e2d75d38512eae8e442769f437c43ca52 Mon Sep 17 00:00:00 2001
From: Mikhail Karpov <[email protected]>
Date: Wed, 6 May 2026 09:59:34 +0700
Subject: [PATCH] Adding storeio to the bootstrap chain

---
 libdiskfs/init-main.c |  26 ++++-
 storeio/storeio.c     | 265 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 280 insertions(+), 11 deletions(-)

diff --git a/libdiskfs/init-main.c b/libdiskfs/init-main.c
index 69c30fd1..c257c840 100644
--- a/libdiskfs/init-main.c
+++ b/libdiskfs/init-main.c
@@ -31,6 +31,7 @@ diskfs_init_main (struct argp *startup_argp,
 {
   error_t err;
   struct store_argp_params store_params = { 0 };
+  store_params.store_optional = 1;
   struct store *store;
 
   /* We must use ARGP_IN_ORDER for the parsing of --boot-command to work.  */
@@ -40,9 +41,14 @@ diskfs_init_main (struct argp *startup_argp,
   assert_perror_backtrace (err);
   *store_parsed = store_params.result;
 
-  err = store_parsed_name (*store_parsed, &diskfs_disk_name);
-  if (err)
-    error (2, err, "store_parsed_name");
+  //if (diskfs_boot_filesystem ())
+  //  diskfs_disk_name = "storeio";
+  //else
+  //  {
+      err = store_parsed_name (*store_parsed, &diskfs_disk_name);
+      if (err)
+        error (2, err, "store_parsed_name");
+  //  }
 
   /* This must come after the args have been parsed, as this is where the
      host priv ports are set for booting.  */
@@ -63,8 +69,18 @@ diskfs_init_main (struct argp *startup_argp,
   if (err)
     error (4, err, "diskfs_init_diskfs");
 
-  err = store_parsed_open (*store_parsed, diskfs_readonly ? STORE_READONLY : 0,
-			   &store);
+  //if (diskfs_boot_filesystem ())
+  //  {
+  //    mach_port_t storeio_port;
+  //    task_get_bootstrap_port (mach_task_self (), &storeio_port);
+  //    err = store_create (storeio_port, diskfs_readonly ? STORE_READONLY : 0,
+  //                        0, &store);
+  //    mach_port_deallocate (mach_task_self (), storeio_port);
+  //  }
+  //else
+    err = store_parsed_open (*store_parsed,
+                             diskfs_readonly ? STORE_READONLY : 0, &store);
+
   if (err)
     error (3, err, "%s", diskfs_disk_name);
 
diff --git a/storeio/storeio.c b/storeio/storeio.c
index 4e8a9628..2740e073 100644
--- a/storeio/storeio.c
+++ b/storeio/storeio.c
@@ -23,12 +23,16 @@
 #include <fcntl.h>
 #include <argp.h>
 #include <argz.h>
+#include <sys/mman.h>
 #include <sys/sysmacros.h>
 #include <stdbool.h>
 
 #include <hurd.h>
 #include <hurd/ports.h>
 #include <hurd/trivfs.h>
+#include <hurd/fsys.h>
+#include <hurd/startup.h>
+#include <hurd/paths.h>
 #include <version.h>
 
 #include "open.h"
@@ -48,6 +52,11 @@ static struct argp_option options[] =
   {"rdev",     'n', "ID", 0,
    "The stat rdev number for this node; may be either a"
    " single integer, or of the form MAJOR,MINOR"},
+  {0, 0, 0, 0,              "Boot options:"},
+  {"next-task", 'N', "TASK", 0, "Next bootstrap task"},
+  {"host-priv-port", 'H', "PORT", 0, "Port for bootstrapping host"},
+  {"device-master-port", 'P', "PORT", 0, "Port for bootstrapping device"
+   " master"},
   {0}
 };
 static const char doc[] = "Translator for devices and other stores";
@@ -57,6 +66,23 @@ const char *argp_program_version = STANDARD_HURD_VERSION (storeio);
 static bool debug=false;
 static char *debug_fname=NULL;
 
+/* The FS control port */
+static mach_port_t control_port;
+
+/* Startup and shutdown notifications management */
+struct port_class *shutdown_notify_class;
+
+static char **hurd_init_argv;
+
+struct port_bucket *port_bucket;
+
+/* Our parent's task, if applicable */
+static task_t parent_task;
+
+static task_t next_task;
+
+struct trivfs_control *storeio_fsys;
+
 /* Desired store parameters specified by the user.  */
 struct storeio_argp_params
 {
@@ -64,6 +90,66 @@ struct storeio_argp_params
   struct dev *dev;		/* We fill in its flag members.  */
 };
 
+static error_t
+storeio_bootstrap_startup (mach_port_t bootstrap)
+{
+  port_bucket = ports_create_bucket ();
+  struct port_class *trivfs_cntl_class;
+  trivfs_cntl_class = ports_create_class (trivfs_clean_cntl, 0);
+  struct port_class *trivfs_protid_class;
+  trivfs_protid_class = ports_create_class (trivfs_clean_protid, 0);
+
+  error_t err = trivfs_startup (bootstrap, 0, trivfs_cntl_class, port_bucket,
+                                trivfs_protid_class, 0, &storeio_fsys);
+  if (err)
+    return err;
+
+  err = fsys_getpriv (bootstrap, &_hurd_host_priv,
+                      &_hurd_device_master, &parent_task);
+  if (err)
+   return err;
+
+  mach_port_t right = ports_get_send_right (&storeio_fsys->pi);
+  err = task_set_special_port (next_task, TASK_BOOTSTRAP_PORT, right);
+  if (err)
+    return err;
+
+  err = mach_port_deallocate (mach_task_self (), right);
+  if (err)
+    return err;
+
+  err = task_resume (next_task);
+  if (err)
+    return err;
+
+  /* Make sure we have a console.  */
+  mach_port_t dev;
+  err = get_privileged_ports (NULL, &dev);
+  if (err)
+    return err;
+
+  mach_port_t cons;
+  err = device_open (dev, D_READ | D_WRITE, "console", &cons);
+  if (err)
+    return err;
+
+  err = mach_port_deallocate (mach_task_self (), dev);
+  if (err)
+    return err;
+
+  stdin = mach_open_devstream (cons, "r");
+  stdout = stderr = mach_open_devstream (cons, "w");
+  err = mach_port_deallocate (mach_task_self (), cons);
+  if (err)
+    return err;
+
+  setlinebuf (stderr);
+  printf ("storeio ");
+  fflush (stdout);
+
+  return 0;
+}
+
 /* Parse a single option.  */
 static error_t
 parse_opt (int key, char *arg, struct argp_state *state)
@@ -80,6 +166,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
     case 'e': params->dev->enforced = 1; break;
     case 'F': params->dev->no_fileio = 1; break;
 
+    case 'N': next_task = atoi (arg); break;
+    case 'H': _hurd_host_priv = atoi (arg); break;
+    case 'P': _hurd_device_master = atoi (arg); break;
+
     case 'n':
       {
 	char *start = arg, *end;
@@ -134,8 +224,6 @@ parse_opt (int key, char *arg, struct argp_state *state)
 
 static const struct argp_child argp_kids[] = { { &store_argp }, {0} };
 static const struct argp argp = { options, parse_opt, 0, doc, argp_kids };
-
-struct trivfs_control *storeio_fsys;
 
 int
 main (int argc, char *argv[])
@@ -144,6 +232,7 @@ main (int argc, char *argv[])
   mach_port_t bootstrap;
   struct dev device;
   struct storeio_argp_params params;
+  hurd_init_argv = argv;
 
   memset (&device, 0, sizeof device);
   pthread_mutex_init (&device.lock, NULL);
@@ -165,10 +254,19 @@ main (int argc, char *argv[])
       if (bootstrap == MACH_PORT_NULL)
 	error (2, 0, "Must be started as a translator");
 
-      /* Reply to our parent */
-      err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &storeio_fsys);
-      if (err)
-	error (3, err, "trivfs_startup");
+      if (next_task != MACH_PORT_NULL)
+        {
+          err = storeio_bootstrap_startup (bootstrap);
+          if (err)
+            error (1, err, "storeio_bootstrap_startup");
+        }
+      else
+        {
+          /* Reply to our parent */
+          err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &storeio_fsys);
+          if (err)
+            error (3, err, "trivfs_startup");
+        }
     }
 
   storeio_fsys->hook = &device;
@@ -452,3 +550,158 @@ trivfs_S_fsys_syncfs (struct trivfs_control *cntl,
   else
     return 0;
 }
+
+/* Override the privileged ports for booting the system */
+kern_return_t
+trivfs_S_fsys_getpriv (struct trivfs_control *cntl,
+                       mach_port_t reply,
+                       mach_msg_type_name_t replytype,
+                       mach_port_t *host, mach_msg_type_name_t *host_privPoly,
+                       mach_port_t *dev, mach_msg_type_name_t *devPoly,
+                       mach_port_t *fstask, mach_msg_type_name_t *fstPoly)
+{
+  error_t err = get_privileged_ports (host, dev);
+  if (!err)
+    {
+      *fstask = mach_task_self ();
+      *host_privPoly = *devPoly = MACH_MSG_TYPE_MOVE_SEND;
+      *fstPoly = MACH_MSG_TYPE_COPY_SEND;
+    }
+
+  return err;
+}
+
+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)
+{
+  control_port = cntl;
+  *realnode = MACH_PORT_NULL;
+  *realnodetype = MACH_MSG_TYPE_COPY_SEND;
+
+  mach_port_t mybootport;
+  task_get_bootstrap_port (mach_task_self (), &mybootport);
+  if (mybootport)
+    fsys_startup (mybootport, flags, control_port, MACH_MSG_TYPE_COPY_SEND,
+                  realnode);
+  return 0;
+}
+
+static void
+arrange_shutdown_notification (void)
+{
+  shutdown_notify_class = ports_create_class (0, 0);
+
+  /* Arrange to get notified when the system goes down */
+  struct port_info *pi;
+  error_t err = ports_create_port (shutdown_notify_class, port_bucket,
+                                   sizeof (struct port_info), &pi);
+  if (err)
+    return;
+
+  mach_port_t initport = file_name_lookup (_SERVERS_STARTUP, 0, 0);
+  if (initport == MACH_PORT_NULL)
+    {
+      mach_print ("WARNING: machdev not registered for shutdown\n");
+      return;
+    }
+
+  mach_port_t notify = ports_get_send_right (pi);
+  ports_port_deref (pi);
+  startup_request_notification (initport, notify, MACH_MSG_TYPE_MAKE_SEND,
+                                program_invocation_short_name);
+  mach_port_deallocate (mach_task_self (), notify);
+  mach_port_deallocate (mach_task_self (), initport);
+}
+
+static void
+essential_task (void)
+{
+  mach_port_t host;
+  error_t err = get_privileged_ports (&host, 0);
+  if (err)
+    {
+      mach_print ("WARNING: Cannot register as essential task\n");
+      return;
+    }
+
+  mach_port_t startup = file_name_lookup (_SERVERS_STARTUP, 0, 0);
+  if (startup == MACH_PORT_NULL)
+    {
+      mach_print ("WARNING: Cannot register as essential task\n");
+      mach_port_deallocate (mach_task_self (), host);
+      return;
+    }
+
+  startup_essential_task (startup, mach_task_self (), MACH_PORT_NULL,
+                          program_invocation_short_name, host);
+  mach_port_deallocate (mach_task_self (), startup);
+  mach_port_deallocate (mach_task_self (), host);
+}
+
+kern_return_t
+trivfs_S_fsys_init (struct trivfs_control *fsys,
+                    mach_port_t reply, mach_msg_type_name_t replytype,
+                    mach_port_t procserver,
+                    mach_port_t authhandle)
+{
+  /* Traverse to the bootstrapping server first */
+  error_t err;
+  mach_port_t bootstrap;
+  task_get_bootstrap_port (mach_task_self (), &bootstrap);
+  if (bootstrap)
+    {
+      process_t parent_proc;
+
+      err = proc_task2proc (procserver, parent_task, &parent_proc);
+      assert_perror_backtrace (err);
+
+      /* We don't need this anymore. */
+      mach_port_deallocate (mach_task_self (), parent_task);
+      parent_task = MACH_PORT_NULL;
+
+      proc_mark_exec(parent_proc);
+
+      err = fsys_init (bootstrap, parent_proc, MACH_MSG_TYPE_COPY_SEND, authhandle);
+      assert_perror_backtrace (err);
+
+      mach_port_deallocate (mach_task_self (), parent_proc);
+    }
+
+  mach_port_t root;
+  uid_t idlist[] = {0, 0, 0};
+  retry_type retry;
+  string_t retry_name;
+  err = fsys_getroot (control_port, MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND,
+                      idlist, 3, idlist, 3, 0,
+                      &retry, retry_name, &root);
+  assert_perror_backtrace (err);
+  assert_backtrace (retry == FS_RETRY_NORMAL);
+  assert_backtrace (retry_name[0] == '\0');
+  assert_backtrace (root != MACH_PORT_NULL);
+
+  mach_port_t *portarray = mmap (0, INIT_PORT_MAX * sizeof (*portarray),
+                                 PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
+ for (unsigned int i = 0; i < INIT_PORT_MAX; ++i)
+    portarray[i] = MACH_PORT_NULL;
+  portarray[INIT_PORT_PROC] = procserver;
+  portarray[INIT_PORT_AUTH] = authhandle;
+  portarray[INIT_PORT_CRDIR] = root;
+  portarray[INIT_PORT_CWDIR] = root;
+  _hurd_init (0, hurd_init_argv, portarray, INIT_PORT_MAX, NULL, 0);
+#ifdef HAVE__HURD_LIBC_PROC_INIT
+  _hurd_libc_proc_init (hurd_init_argv);
+#endif
+
+  /* Mark us as essential if bootstrapping.  */
+  essential_task ();
+
+  arrange_shutdown_notification ();
+
+  return 0;
+}
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.