Hello everyone!
Here's my attempt to add storeio to the GNU/Hurd bootstrap chain to fix
GPLv2 vs. GPLv3 license incompatibility between ext2fs and libparted.
So far, I've managed to add it to the bootstrap chain in grub.cfg:
module /hurd/rumpdisk.static rumpdisk \
--next-task='${storeio-task}' \
'$(disk-task=task-create)'
module /hurd/storeio.static storeio \
--next-task='${fs-task}' -T typed '${root}' \
'$(storeio-task=task-create)'
module /hurd/ext2fs.static ext2fs \
--multiboot-command-line='${kernel-command-line}' \
--exec-server-task='${exec-task}' -T typed '${root}' \
'$(fs-task=task-create)'
The system boots, but I don't fully understand how to access the store
provided
by storeio if I remove the -T typed '${root}' from the ext2fs arguments.
I tried extending libdiskfs/init-main.c so that at system startup, the
store is
accessed via store_create instead of store_parsed_open, which in turn
accesses
the parent task, but boot fails with the error code MIG_BAD_ID. I spent some
time trying to figure this out on my own, but my knowledge is still lacking.
So any advice and comments are welcome!
--
Mikhail Karpov
From 3751be3c72e3b9ac038289e1f003c77bab95fcbe Mon Sep 17 00:00:00 2001
From: Mikhail Karpov <[email protected]>
Date: Fri, 24 Apr 2026 18:50:10 +0700
Subject: [PATCH] Adding storeio to the bootstrap chain
---
libdiskfs/boot-start.c | 2 +-
libdiskfs/diskfs.h | 2 +
libdiskfs/init-main.c | 22 ++++--
libmachdev/trivfs_server.c | 24 +++---
libmachdev/trivfs_server.h | 4 +
storeio/Makefile | 8 +-
storeio/dev.c | 2 +-
storeio/dev.h | 4 +-
storeio/storeio.c | 150 +++++++++++++++++++++++++++++++++----
9 files changed, 178 insertions(+), 40 deletions(-)
diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c
index 93738b42..fcb74afa 100644
--- a/libdiskfs/boot-start.c
+++ b/libdiskfs/boot-start.c
@@ -45,7 +45,7 @@ static struct port_info *bootinfo;
static mach_port_t diskfs_exec_ctl;
extern task_t diskfs_exec_server_task;
extern task_t diskfs_kernel_task;
-static task_t parent_task = MACH_PORT_NULL;
+task_t parent_task = MACH_PORT_NULL;
static pthread_mutex_t execstartlock;
static pthread_cond_t execstarted;
diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index 4473a3c2..b1c06d4a 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -30,6 +30,8 @@
#include <features.h>
#include <refcount.h>
+extern task_t parent_task;
+
#ifdef DISKFS_DEFINE_EXTERN_INLINE
#define DISKFS_EXTERN_INLINE
#else
diff --git a/libdiskfs/init-main.c b/libdiskfs/init-main.c
index 69c30fd1..c2e229c5 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,12 @@ 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 ())
+ // {
+ 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 +67,16 @@ 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 ())
+ // {
+ // err = store_create (parent_task, diskfs_readonly ? STORE_READONLY : 0,
+ // 0, &store);
+ // diskfs_disk_name = "storeio";
+ // }
+ //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/libmachdev/trivfs_server.c b/libmachdev/trivfs_server.c
index 2c905a63..475053ca 100644
--- a/libmachdev/trivfs_server.c
+++ b/libmachdev/trivfs_server.c
@@ -49,12 +49,12 @@
struct port_bucket *port_bucket;
/* Trivfs hooks. */
-int trivfs_fstype = FSTYPE_MISC;
-int trivfs_fsid = 0;
-int trivfs_support_read = 0;
-int trivfs_support_write = 0;
-int trivfs_support_exec = 0;
-int trivfs_allow_open = O_READ | O_WRITE;
+int __attribute__ ((weak)) trivfs_fstype = FSTYPE_MISC;
+int __attribute__ ((weak)) trivfs_fsid = 0;
+int __attribute__ ((weak)) trivfs_support_read = 0;
+int __attribute__ ((weak)) trivfs_support_write = 0;
+int __attribute__ ((weak)) trivfs_support_exec = 0;
+int __attribute__ ((weak)) trivfs_allow_open = O_READ | O_WRITE;
/* Our port classes */
struct port_class *trivfs_cntl_class;
@@ -80,7 +80,7 @@ struct port_class *machdev_shutdown_notify_class;
static void arrange_shutdown_notification (void);
/* Our parent's task, if applicable */
-static task_t parent_task;
+task_t parent_task;
/* Our argument vector */
static char **machdev_argv;
@@ -124,7 +124,7 @@ machdev_is_master_device (mach_port_t port)
return ret;
}
-error_t
+error_t __attribute__ ((weak))
trivfs_append_args (struct trivfs_control *fsys, char **argz, size_t *argz_len)
{
error_t err = 0;
@@ -356,7 +356,7 @@ arrange_shutdown_notification (void)
}
/* Override the privileged ports for booting the system */
-kern_return_t
+kern_return_t __attribute__ ((weak))
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,
@@ -483,7 +483,7 @@ S_startup_dosync (mach_port_t handle)
return 0;
}
-error_t
+error_t __attribute__ ((weak))
trivfs_goaway (struct trivfs_control *fsys, int flags)
{
int count;
@@ -506,7 +506,7 @@ trivfs_goaway (struct trivfs_control *fsys, int flags)
exit (0);
}
-static int
+int
demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
{
mig_routine_t routine;
@@ -524,7 +524,7 @@ demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
return FALSE;
}
-void
+void __attribute__ ((weak))
trivfs_modify_stat (struct trivfs_protid *cred, io_statbuf_t *stat)
{
}
diff --git a/libmachdev/trivfs_server.h b/libmachdev/trivfs_server.h
index 40ae57fe..3818bc72 100644
--- a/libmachdev/trivfs_server.h
+++ b/libmachdev/trivfs_server.h
@@ -26,6 +26,10 @@ extern struct port_bucket *port_bucket;
extern struct port_class *trivfs_protid_class;
extern struct port_class *trivfs_cntl_class;
extern struct port_class *machdev_shutdown_notify_class;
+extern struct trivfs_control *control;
+extern task_t parent_task;
+
+int demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp);
#endif /* _MACHDEV_TRIVFS_SERVER_H */
diff --git a/storeio/Makefile b/storeio/Makefile
index 83b7684d..5d5b8878 100644
--- a/storeio/Makefile
+++ b/storeio/Makefile
@@ -19,11 +19,13 @@
dir := storeio
makemode := server
-target = storeio
+target = storeio storeio.static
SRCS = dev.c storeio.c open.c pager.c io.c
OBJS = $(SRCS:.c=.o)
-HURDLIBS = trivfs pager fshelp iohelp store ports ihash shouldbeinlibc
-LDLIBS = -lpthread
+HURDLIBS = trivfs pager fshelp iohelp store ports ihash shouldbeinlibc machdev
+LDLIBS = -lpthread $(and $(HAVE_LIBBZ2),-lbz2) $(and $(HAVE_LIBZ),-lz)
include ../Makeconf
+
+storeio.static: $(boot-store-types:%=../libstore/libstore_%.a)
diff --git a/storeio/dev.c b/storeio/dev.c
index c87400c0..30dc0354 100644
--- a/storeio/dev.c
+++ b/storeio/dev.c
@@ -143,7 +143,7 @@ dev_buf_rw (struct dev *dev, size_t buf_offs, size_t *io_offs, size_t *len,
/* Called with DEV->lock held. Try to open the store underlying DEV. */
error_t
-dev_open (struct dev *dev)
+dev_open (struct dev *dev, struct trivfs_control *storeio_fsys)
{
error_t err;
const int flags = ((dev->readonly ? STORE_READONLY : 0)
diff --git a/storeio/dev.h b/storeio/dev.h
index eda7a93d..c017eb6e 100644
--- a/storeio/dev.h
+++ b/storeio/dev.h
@@ -26,8 +26,6 @@
#include <hurd/store.h>
#include <hurd/trivfs.h>
-extern struct trivfs_control *storeio_fsys;
-
/* Information about backend store, which we presumptively call a "device". */
struct dev
{
@@ -91,7 +89,7 @@ dev_is_readonly (const struct dev *dev)
}
/* Called with DEV->lock held. Try to open the store underlying DEV. */
-error_t dev_open (struct dev *dev);
+error_t dev_open (struct dev *dev, struct trivfs_control *storeio_fsys);
/* Shut down the store underlying DEV and free any resources it consumes.
DEV itself remains intact so that dev_open can be called again.
diff --git a/storeio/storeio.c b/storeio/storeio.c
index 4e8a9628..081eb277 100644
--- a/storeio/storeio.c
+++ b/storeio/storeio.c
@@ -29,11 +29,14 @@
#include <hurd.h>
#include <hurd/ports.h>
#include <hurd/trivfs.h>
+#include <hurd/fsys.h>
#include <version.h>
#include "open.h"
#include "dev.h"
#include "libtrivfs/trivfs_fsys_S.h"
+#include "libmachdev/machdev.h"
+#include "libmachdev/trivfs_server.h"
static struct argp_option options[] =
{
@@ -48,6 +51,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 +65,8 @@ const char *argp_program_version = STANDARD_HURD_VERSION (storeio);
static bool debug=false;
static char *debug_fname=NULL;
+static mach_port_t next_task;
+
/* Desired store parameters specified by the user. */
struct storeio_argp_params
{
@@ -64,6 +74,63 @@ 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 ();
+ trivfs_cntl_class = ports_create_class (trivfs_clean_cntl, 0);
+ 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, &control);
+ 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 (&control->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 +147,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,7 +205,7 @@ 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
@@ -163,21 +234,39 @@ main (int argc, char *argv[])
{
task_get_bootstrap_port (mach_task_self (), &bootstrap);
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");
+ error (2, 0, "Must be started as a translator");
+
+ if (next_task != MACH_PORT_NULL)
+ {
+ err = storeio_bootstrap_startup (bootstrap);
+ if (err)
+ error (1, err, "storeio_bootstrap_init");
+
+ dev_open (&device, control);
+
+ control->hook = &device;
+
+ /* Launch. */
+ ports_manage_port_operations_multithread (control->pi.bucket,
+ demuxer,
+ 30*1000, 5*60*1000, 0);
+ }
+ 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;
+
+ /* Launch. */
+ ports_manage_port_operations_multithread (storeio_fsys->pi.bucket,
+ trivfs_demuxer,
+ 30*1000, 5*60*1000, 0);
+ }
}
- storeio_fsys->hook = &device;
-
- /* Launch. */
- ports_manage_port_operations_multithread (storeio_fsys->pi.bucket,
- trivfs_demuxer,
- 30*1000, 5*60*1000, 0);
-
return 0;
}
@@ -254,7 +343,11 @@ check_open_hook (struct trivfs_control *trivfs_control,
if (dev->store == NULL)
{
/* Try and open the store. */
- err = dev_open (dev);
+ if (next_task != MACH_PORT_NULL)
+ err = dev_open (dev, control);
+ else
+ err = dev_open (dev, storeio_fsys);
+
if (err && (flags & (O_READ|O_WRITE)) == 0)
/* If we're not opening for read or write, then just ignore the
error, as this allows stat to work correctly. XXX */
@@ -452,3 +545,30 @@ 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)
+{
+ mach_port_t right;
+ if (next_task != MACH_PORT_NULL)
+ right = ports_get_send_right (&control->pi);
+ else
+ right = ports_get_send_right (&storeio_fsys->pi);
+
+ error_t err = get_privileged_ports (host, NULL);
+ if (!err)
+ {
+ *dev = right;
+ *fstask = mach_task_self ();
+ *host_privPoly = *devPoly = MACH_MSG_TYPE_MOVE_SEND;
+ *fstPoly = MACH_MSG_TYPE_COPY_SEND;
+ }
+
+ return err;
+}
--
2.43.0