Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH] libmachdev: Introduce startup notification for clean rumpdisk shutdown

1 view
Skip to first unread message

Damien Zammit

unread,
Jul 25, 2020, 2:52:11 AM7/25/20
to bug-...@gnu.org, Damien Zammit
This still does not work. I get a freeze on reboot command:

root@zamhurd:~# reboot
INIT: Switching to runlevel: 6
INIT: Sending processes configured via /etc/inittab the TERM signal
root@zamhurd:~#
Broadcast message from root@zamhurd (console) (Sun Jul 25 16:32:28 1999):

The system is going down for reboot NOW!
INIT: Sending processes configured via /etc/inittab the KILL signal
Using makefile-style concurrent boot in runlevel 6.
Stopping deferred execution scheduler: atd.
Asking all remaining processes to terminate...

<HANG>

---
libmachdev/Makefile | 6 ++--
libmachdev/startup-ops.c | 36 +++++++++++++++++++++++
libmachdev/startup.c | 58 ++++++++++++++++++++++++++++++++++++++
libmachdev/startup.h | 28 ++++++++++++++++++
libmachdev/trivfs_server.c | 8 ++++--
libmachdev/trivfs_server.h | 30 ++++++++++++++++++++
6 files changed, 161 insertions(+), 5 deletions(-)
create mode 100644 libmachdev/startup-ops.c
create mode 100644 libmachdev/startup.c
create mode 100644 libmachdev/startup.h
create mode 100644 libmachdev/trivfs_server.h

diff --git a/libmachdev/Makefile b/libmachdev/Makefile
index 15b98cf1..a111a2eb 100644
--- a/libmachdev/Makefile
+++ b/libmachdev/Makefile
@@ -19,10 +19,10 @@ dir := libmachdev
makemode := library
libname = libmachdev

-SRCS = ds_routines.c trivfs_server.c \
- deviceServer.c notifyServer.c mach_i386Server.c
+SRCS = ds_routines.c trivfs_server.c startup_notifyServer.c \
+ deviceServer.c notifyServer.c mach_i386Server.c startup.c startup-ops.c

-LCLHDRS = machdev.h machdev-device_emul.h machdev-dev_hdr.h mach_device.h
+LCLHDRS = machdev.h machdev-device_emul.h machdev-dev_hdr.h mach_device.h startup.h
installhdrs = machdev.h machdev-device_emul.h machdev-dev_hdr.h
HURDLIBS = ports trivfs
LDLIBS += -lpthread -lmachuser
diff --git a/libmachdev/startup-ops.c b/libmachdev/startup-ops.c
new file mode 100644
index 00000000..5d46c217
--- /dev/null
+++ b/libmachdev/startup-ops.c
@@ -0,0 +1,36 @@
+/*
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <startup_notify_S.h>
+#include <hurd/trivfs.h>
+#include "startup.h"
+#include "trivfs_server.h"
+
+/* The system is going down. Call trivfs_goaway() */
+error_t
+S_startup_dosync (mach_port_t handle)
+{
+ struct port_info *inpi = ports_lookup_port (port_bucket, handle,
+ machdev_shutdown_notify_class);
+
+ if (!inpi)
+ return EOPNOTSUPP;
+
+ ports_port_deref (inpi);
+
+ return trivfs_goaway (NULL, FSYS_GOAWAY_FORCE);
+}
diff --git a/libmachdev/startup.c b/libmachdev/startup.c
new file mode 100644
index 00000000..fee5a665
--- /dev/null
+++ b/libmachdev/startup.c
@@ -0,0 +1,58 @@
+/*
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Startup and shutdown notifications management */
+
+#include "startup.h"
+#include "trivfs_server.h"
+
+#include <unistd.h>
+#include <hurd/paths.h>
+#include <hurd/startup.h>
+#include <hurd/trivfs.h>
+
+struct port_class *machdev_shutdown_notify_class;
+
+void
+arrange_shutdown_notification ()
+{
+ error_t err;
+ mach_port_t initport, notify;
+ struct port_info *pi;
+
+ machdev_shutdown_notify_class = ports_create_class (0, 0);
+
+ /* Arrange to get notified when the system goes down,
+ but if we fail for some reason, just silently give up. No big deal. */
+
+ err = ports_create_port (machdev_shutdown_notify_class, port_bucket,
+ sizeof (struct port_info), &pi);
+ if (err)
+ return;
+
+ initport = file_name_lookup (_SERVERS_STARTUP, 0, 0);
+ if (initport == MACH_PORT_NULL)
+ return;
+
+ 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);
+}
diff --git a/libmachdev/startup.h b/libmachdev/startup.h
new file mode 100644
index 00000000..2bc6b1d7
--- /dev/null
+++ b/libmachdev/startup.h
@@ -0,0 +1,28 @@
+/*
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef STARTUP_H
+#define STARTUP_H
+
+/* Startup and shutdown notifications management */
+
+/* Port class for startup requests */
+extern struct port_class *machdev_shutdown_notify_class;
+
+void arrange_shutdown_notification (void);
+
+#endif /* STARTUP_H */
diff --git a/libmachdev/trivfs_server.c b/libmachdev/trivfs_server.c
index 93d498ad..64f447b9 100644
--- a/libmachdev/trivfs_server.c
+++ b/libmachdev/trivfs_server.c
@@ -30,12 +30,14 @@
#include <device/device.h> /* mach console */

#include "libdiskfs/diskfs.h"
+#include "startup.h"
+#include "startup_notify_S.h"
#include "device_S.h"
#include "notify_S.h"
#include "fsys_S.h"
#include "mach_i386_S.h"

-static struct port_bucket *port_bucket;
+struct port_bucket *port_bucket;

/* Trivfs hooks. */
int trivfs_fstype = FSTYPE_MISC;
@@ -194,7 +196,6 @@ S_i386_io_perm_create (mach_port_t master_port,
return i386_io_perm_create (_hurd_device_master, from, to, io_perm);
}

-/* This is fraud */
kern_return_t
trivfs_S_fsys_startup (mach_port_t bootport,
mach_port_t reply,
@@ -204,6 +205,8 @@ trivfs_S_fsys_startup (mach_port_t bootport,
mach_port_t *realnode,
mach_msg_type_name_t *realnodetype)
{
+ arrange_shutdown_notification ();
+
*realnode = MACH_PORT_NULL;
*realnodetype = MACH_MSG_TYPE_MOVE_SEND;
return 0;
@@ -327,6 +330,7 @@ demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
if ((routine = device_server_routine (inp)) ||
(routine = notify_server_routine (inp)) ||
(routine = mach_i386_server_routine (inp)) ||
+ (routine = startup_notify_server_routine (inp)) ||
(routine = NULL, trivfs_demuxer (inp, outp)))
{
if (routine)
diff --git a/libmachdev/trivfs_server.h b/libmachdev/trivfs_server.h
new file mode 100644
index 00000000..908feaf6
--- /dev/null
+++ b/libmachdev/trivfs_server.h
@@ -0,0 +1,30 @@
+/*
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+ The GNU Hurd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the GNU Hurd; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef _TRIVFS_SERVER_H
+#define _TRIVFS_SERVER_H
+
+#include <hurd/ports.h>
+#include <hurd/trivfs.h>
+#include <hurd.h>
+
+extern struct port_bucket *port_bucket;
+extern struct port_class *trivfs_protid_class;
+extern struct port_class *trivfs_cntl_class;
+
+#endif
+
--
2.25.1


Samuel Thibault

unread,
Jul 25, 2020, 6:15:44 AM7/25/20
to Damien Zammit, bug-...@gnu.org
Damien Zammit, le sam. 25 juil. 2020 16:51:50 +1000, a ecrit:
> Broadcast message from root@zamhurd (console) (Sun Jul 25 16:32:28 1999):
>
> The system is going down for reboot NOW!
> INIT: Sending processes configured via /etc/inittab the KILL signal
> Using makefile-style concurrent boot in runlevel 6.
> Stopping deferred execution scheduler: atd.
> Asking all remaining processes to terminate...

This is a concern with the reboot command, not with the reboot-hurd
command. Only the latter is concerned with the startup notification
thing. Try to debug with reboot-hurd first, and check what is happening
with reboot only after that.

Samuel

Samuel Thibault

unread,
Jul 25, 2020, 7:26:03 AM7/25/20
to Damien Zammit, bug-...@gnu.org
Damien Zammit, le sam. 25 juil. 2020 16:51:50 +1000, a ecrit:
> -SRCS = ds_routines.c trivfs_server.c \
> - deviceServer.c notifyServer.c mach_i386Server.c
> +SRCS = ds_routines.c trivfs_server.c startup_notifyServer.c \
> + deviceServer.c notifyServer.c mach_i386Server.c startup.c startup-ops.c

I'd say not to split the code into several files. It's already hard to
understand how bootstrap works, putting the different pieces in separate
files will not help people reading it.

> +/* The system is going down. Call trivfs_goaway() */
> +error_t
> +S_startup_dosync (mach_port_t handle)
> +{
> + struct port_info *inpi = ports_lookup_port (port_bucket, handle,
> + machdev_shutdown_notify_class);
> +
> + if (!inpi)
> + return EOPNOTSUPP;
> +
> + ports_port_deref (inpi);
> +
> + return trivfs_goaway (NULL, FSYS_GOAWAY_FORCE);
> +}

That, in particular, should probably interact with machdev_trivfs_init
and machdev_trivfs_server, to let the translator using machdev register
a function to be called at shutdown. In the rump case, it'll have to
flush the disk caches, before startup shuts the system down.

Samuel

Damien Zammit

unread,
Jul 26, 2020, 3:37:47 AM7/26/20
to bug-...@gnu.org, Damien Zammit
This patch almost provides shutdown notification for rumpdisk,
but fails at getproc() which returns 0, I struggle to figure out why.

Currently:

Hurd server bootstrap: ext2fs[part:2:device:/dev/wd0] ...
WARNING: machdev not registered for shutdown

---
libmachdev/Makefile | 6 +--
libmachdev/ds_routines.c | 10 ++++
libmachdev/machdev-device_emul.h | 1 +
libmachdev/machdev.h | 1 +
libmachdev/startup.c | 86 ++++++++++++++++++++++++++++++++
libmachdev/startup.h | 28 +++++++++++
libmachdev/trivfs_server.c | 16 +++++-
libmachdev/trivfs_server.h | 30 +++++++++++
rumpdisk/block-rump.c | 14 ++++++
9 files changed, 187 insertions(+), 5 deletions(-)
create mode 100644 libmachdev/startup.c
create mode 100644 libmachdev/startup.h
create mode 100644 libmachdev/trivfs_server.h

diff --git a/libmachdev/Makefile b/libmachdev/Makefile
index 15b98cf1..bb4fcd8a 100644
--- a/libmachdev/Makefile
+++ b/libmachdev/Makefile
@@ -19,10 +19,10 @@ dir := libmachdev
makemode := library
libname = libmachdev

-SRCS = ds_routines.c trivfs_server.c \
- deviceServer.c notifyServer.c mach_i386Server.c
+SRCS = ds_routines.c trivfs_server.c startup_notifyServer.c \
+ deviceServer.c notifyServer.c mach_i386Server.c startup.c

-LCLHDRS = machdev.h machdev-device_emul.h machdev-dev_hdr.h mach_device.h
+LCLHDRS = machdev.h machdev-device_emul.h machdev-dev_hdr.h mach_device.h startup.h
installhdrs = machdev.h machdev-device_emul.h machdev-dev_hdr.h
HURDLIBS = ports trivfs
LDLIBS += -lpthread -lmachuser
diff --git a/libmachdev/ds_routines.c b/libmachdev/ds_routines.c
index 53e0c080..64080176 100644
--- a/libmachdev/ds_routines.c
+++ b/libmachdev/ds_routines.c
@@ -317,6 +317,16 @@ void machdev_device_init()
}
}

+void machdev_device_shutdown()
+{
+ int i;
+ for (i = 0; i < num_emul; i++)
+ {
+ if (emulation_list[i]->shutdown)
+ emulation_list[i]->shutdown();
+ }
+}
+
static int
demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
{
diff --git a/libmachdev/machdev-device_emul.h b/libmachdev/machdev-device_emul.h
index ab1bd92b..213e079c 100644
--- a/libmachdev/machdev-device_emul.h
+++ b/libmachdev/machdev-device_emul.h
@@ -36,6 +36,7 @@
struct machdev_device_emulation_ops
{
void (*init) (void);
+ void (*shutdown) (void);
void (*reference) (void *);
void (*dealloc) (void *);
mach_port_t (*dev_to_port) (void *);
diff --git a/libmachdev/machdev.h b/libmachdev/machdev.h
index 55a56e0d..5f07d35f 100644
--- a/libmachdev/machdev.h
+++ b/libmachdev/machdev.h
@@ -30,6 +30,7 @@
void machdev_register (struct machdev_device_emulation_ops *ops);

void machdev_device_init(void);
+void machdev_device_shutdown(void);
void * machdev_server(void *);
error_t machdev_create_device_port (size_t size, void *result);
int machdev_trivfs_init(mach_port_t bootstrap_resume_task, const char *name, mach_port_t *bootstrap);
diff --git a/libmachdev/startup.c b/libmachdev/startup.c
new file mode 100644
index 00000000..d8bf00e7
--- /dev/null
+++ b/libmachdev/startup.c
@@ -0,0 +1,86 @@
+/*
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Startup and shutdown notifications management */
+
+#include "startup.h"
+#include "trivfs_server.h"
+#include <startup_notify_S.h>
+#include <unistd.h>
+#include <hurd/paths.h>
+#include <hurd/startup.h>
+#include <hurd/trivfs.h>
+#include "libmachdev/machdev.h"
+
+struct port_class *machdev_shutdown_notify_class;
+
+void
+arrange_shutdown_notification ()
+{
+ error_t err;
+ mach_port_t initport, notify;
+ process_t proc;
+ struct port_info *pi;
+
+ proc = getproc ();
+ // XXX Why does this fail? assert_backtrace (proc);
+
+ machdev_shutdown_notify_class = ports_create_class (0, 0);
+
+ /* Arrange to get notified when the system goes down */
+ err = ports_create_port (machdev_shutdown_notify_class, port_bucket,
+ sizeof (struct port_info), &pi);
+ if (err)
+ return;
+
+ /* Mark us as important. */
+ err = proc_mark_important (proc);
+ mach_port_deallocate (mach_task_self (), proc);
+
+ initport = file_name_lookup (_SERVERS_STARTUP, 0, 0);
+ if (initport == MACH_PORT_NULL)
+ {
+ mach_print ("WARNING: machdev not registered for shutdown\n");
+ return;
+ }
+
+ 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);
+}
+
+/* The system is going down. Sync data, then call trivfs_goaway() */
+error_t
+S_startup_dosync (mach_port_t handle)
+{
+ struct port_info *inpi = ports_lookup_port (port_bucket, handle,
+ machdev_shutdown_notify_class);
+
+ if (!inpi)
+ return EOPNOTSUPP;
+
+ ports_port_deref (inpi);
+
+ /* Sync and close device(s) */
+ machdev_device_shutdown ();
+
+ return trivfs_goaway (NULL, FSYS_GOAWAY_FORCE);
+}
index eec8585e..a7b20cef 100644
--- a/libmachdev/trivfs_server.c
+++ b/libmachdev/trivfs_server.c
@@ -30,12 +30,14 @@
#include <device/device.h> /* mach console */

#include "libdiskfs/diskfs.h"
+#include "startup.h"
+#include "startup_notify_S.h"
#include "device_S.h"
#include "notify_S.h"
#include "fsys_S.h"
#include "mach_i386_S.h"

-static struct port_bucket *port_bucket;
+struct port_bucket *port_bucket;

/* Trivfs hooks. */
int trivfs_fstype = FSTYPE_MISC;
@@ -183,7 +185,16 @@ S_i386_io_perm_create (mach_port_t master_port,
return i386_io_perm_create (_hurd_device_master, from, to, io_perm);
}

-/* This is fraud */
+kern_return_t
+trivfs_S_fsys_init (struct trivfs_control *tc,
+ mach_port_t reply, mach_msg_type_name_t replytype,
+ mach_port_t procserver,
+ mach_port_t authhandle)
+{
+ arrange_shutdown_notification ();
+ return 0;
+}
+
kern_return_t
trivfs_S_fsys_startup (mach_port_t bootport,
mach_port_t reply,
@@ -316,6 +327,7 @@ demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
diff --git a/rumpdisk/block-rump.c b/rumpdisk/block-rump.c
index 474852cd..6cf944a7 100644
--- a/rumpdisk/block-rump.c
+++ b/rumpdisk/block-rump.c
@@ -151,6 +151,19 @@ device_dealloc (void *d)
rump_sys_reboot (0, NULL);
}

+static void
+device_shutdown (void)
+{
+ struct block_data *bd = block_head;
+
+ while (bd)
+ {
+ device_close((void *)bd);
+ bd = bd->next;
+ }
+ rump_sys_reboot (0, NULL);
+}
+
static io_return_t
device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type,
dev_mode_t mode, char *name, device_t * devp,
@@ -345,6 +358,7 @@ device_get_status (void *d, dev_flavor_t flavor, dev_status_t status,
*/
static struct machdev_device_emulation_ops rump_block_emulation_ops = {
device_init,
+ device_shutdown,
NULL,
device_dealloc,
dev_to_port,
--
2.25.1


Samuel Thibault

unread,
Jul 26, 2020, 9:13:02 AM7/26/20
to Damien Zammit, bug-...@gnu.org
Damien Zammit, le dim. 26 juil. 2020 17:37:21 +1000, a ecrit:
> This patch almost provides shutdown notification for rumpdisk,
> but fails at getproc() which returns 0, I struggle to figure out why.


> +void
> +arrange_shutdown_notification ()
> +{
> + error_t err;
> + mach_port_t initport, notify;
> + process_t proc;
> + struct port_info *pi;
> +
> + proc = getproc ();
> + // XXX Why does this fail? assert_backtrace (proc);

See the implementation of getproc in glibc/hurd/hurdports.c, it takes
the port from the glibc's _hurd_ports array. See the bootstrap.html
page, that's only set up by libdiskfs for its children, and rump is a
parent of libdiskfs, so it can't magically inherit it, so you have to
set it by hand, just like other bootstrap translators do, see

git grep _hurd_ports .

Samuel

Samuel Thibault

unread,
Jul 27, 2020, 8:03:20 PM7/27/20
to Damien Zammit, bug-...@gnu.org
Damien Zammit, le dim. 26 juil. 2020 17:37:21 +1000, a ecrit:
> @@ -183,7 +185,16 @@ S_i386_io_perm_create (mach_port_t master_port,
> return i386_io_perm_create (_hurd_device_master, from, to, io_perm);
> }
>
> -/* This is fraud */
> +kern_return_t
> +trivfs_S_fsys_init (struct trivfs_control *tc,
> + mach_port_t reply, mach_msg_type_name_t replytype,
> + mach_port_t procserver,
> + mach_port_t authhandle)
> +{

As discussed on IRC, you need to initialize
_hurd_ports[INIT_PORT_PROC]
_hurd_ports[INIT_PORT_AUTH]
_hurd_ports[INIT_PORT_CRDIR]
_hurd_ports[INIT_PORT_CWDIR]

In order to have things working. You'll also want to attach yourself
onto /dev/rumpdisk, see how startup does it in install_as_translator().
Then you'll be able to use storeio to expose the disk and partitions in
/dev entries.

Samuel

Damien Zammit

unread,
Jul 28, 2020, 6:09:22 AM7/28/20
to bug-...@gnu.org, Damien Zammit
NB: Reboot still hangs on diskfs_S_startup_dosync() even though that
times out and then rumpdisk shuts down cleanly.

---
libmachdev/Makefile | 6 +--
libmachdev/ds_routines.c | 10 ++++
libmachdev/machdev-device_emul.h | 1 +
libmachdev/machdev.h | 1 +
libmachdev/startup.c | 86 ++++++++++++++++++++++++++++++++
libmachdev/startup.h | 28 +++++++++++
libmachdev/trivfs_server.c | 49 +++++++++++++++++-
libmachdev/trivfs_server.h | 30 +++++++++++
rumpdisk/block-rump.c | 16 +++++-
9 files changed, 221 insertions(+), 6 deletions(-)
index ab1bd92b..edf79b96 100644
--- a/libmachdev/machdev-device_emul.h
+++ b/libmachdev/machdev-device_emul.h
@@ -64,6 +64,7 @@ struct machdev_device_emulation_ops
recnum_t, vm_offset_t, vm_size_t);
io_return_t (*writev_trap) (void *, dev_mode_t,
recnum_t, io_buf_vec_t *, vm_size_t);
+ void (*shutdown) (void);
};

#endif /* _MACHDEV_DEVICE_EMUL_H_ */
diff --git a/libmachdev/machdev.h b/libmachdev/machdev.h
index 55a56e0d..5f07d35f 100644
--- a/libmachdev/machdev.h
+++ b/libmachdev/machdev.h
@@ -30,6 +30,7 @@
void machdev_register (struct machdev_device_emulation_ops *ops);

void machdev_device_init(void);
+void machdev_device_shutdown(void);
void * machdev_server(void *);
error_t machdev_create_device_port (size_t size, void *result);
int machdev_trivfs_init(mach_port_t bootstrap_resume_task, const char *name, mach_port_t *bootstrap);
diff --git a/libmachdev/startup.c b/libmachdev/startup.c
new file mode 100644
index 00000000..49eec502
+void
+arrange_shutdown_notification ()
+{
+ error_t err;
+ mach_port_t initport, notify;
+ process_t proc;
+ struct port_info *pi;
+
+ proc = getproc ();
+ assert_backtrace (proc);
index eec8585e..6757b217 100644
--- a/libmachdev/trivfs_server.c
+++ b/libmachdev/trivfs_server.c
@@ -24,18 +24,22 @@
#include <stdio.h>
#include <fcntl.h>
#include <error.h>
+#include <sys/mman.h>
#include <hurd/ports.h>
#include <hurd/trivfs.h>
+#include <hurd/fsys.h>
#include <hurd.h>
#include <device/device.h> /* mach console */

#include "libdiskfs/diskfs.h"
+#include "startup.h"
+#include "startup_notify_S.h"
#include "device_S.h"
#include "notify_S.h"
#include "fsys_S.h"
#include "mach_i386_S.h"

-static struct port_bucket *port_bucket;
+struct port_bucket *port_bucket;

/* Trivfs hooks. */
int trivfs_fstype = FSTYPE_MISC;
@@ -49,6 +53,9 @@ int trivfs_allow_open = O_READ | O_WRITE;
struct port_class *trivfs_protid_class;
struct port_class *trivfs_cntl_class;

+/* Our control port */
+static mach_port_t machdev_ctl;
+
/* Implementation of notify interface */
kern_return_t
do_mach_notify_port_deleted (struct port_info *pi,
@@ -183,7 +190,42 @@ S_i386_io_perm_create (mach_port_t master_port,
return i386_io_perm_create (_hurd_device_master, from, to, io_perm);
}

-/* This is fraud */
+kern_return_t
+trivfs_S_fsys_init (struct trivfs_control *tc,
+ mach_port_t reply, mach_msg_type_name_t replytype,
+ mach_port_t procserver,
+ mach_port_t authhandle)
+{
+ error_t err;
+ mach_port_t *portarray;
+ unsigned int i;
+ uid_t idlist[] = {0, 0, 0};
+ mach_port_t root;
+ retry_type retry;
+ string_t retry_name;
+
+ err = fsys_getroot (machdev_ctl, 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);
+
+ portarray = mmap (0, INIT_PORT_MAX * sizeof *portarray,
+ PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
+ for (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, NULL, portarray, INIT_PORT_MAX, NULL, 0);
+
+ arrange_shutdown_notification ();
+ return 0;
+}
+
kern_return_t
trivfs_S_fsys_startup (mach_port_t bootport,
mach_port_t reply,
@@ -193,6 +235,8 @@ trivfs_S_fsys_startup (mach_port_t bootport,
mach_port_t *realnode,
mach_msg_type_name_t *realnodetype)
{
+ machdev_ctl = cntl;
+
*realnode = MACH_PORT_NULL;
*realnodetype = MACH_MSG_TYPE_MOVE_SEND;
return 0;
@@ -316,6 +360,7 @@ demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
index 474852cd..e094a199 100644
--- a/rumpdisk/block-rump.c
+++ b/rumpdisk/block-rump.c
@@ -151,6 +151,19 @@ device_dealloc (void *d)
rump_sys_reboot (0, NULL);
}

+static void
+device_shutdown (void)
+{
+ struct block_data *bd = block_head;
+
+ while (bd)
+ {
+ device_close((void *)bd);
+ bd = bd->next;
+ }
+ rump_sys_reboot (0, NULL);
+}
+
static io_return_t
device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type,
dev_mode_t mode, char *name, device_t * devp,
@@ -360,7 +373,8 @@ static struct machdev_device_emulation_ops rump_block_emulation_ops = {
NULL,
NULL,
NULL,
- NULL
+ NULL,
+ device_shutdown
};

void
--
2.25.1


Samuel Thibault

unread,
Jul 30, 2020, 6:03:45 PM7/30/20
to Damien Zammit, bug-...@gnu.org
Damien Zammit, le mar. 28 juil. 2020 20:08:36 +1000, a ecrit:
> +++ b/libmachdev/startup.c
> --- a/libmachdev/trivfs_server.c

As mentioned previously, please keep it inside trivfs_server.c. The
bootstrap process is already hairy by happening in different
translators, let's not add complexity by having several files.

Samuel

Damien Zammit

unread,
Aug 1, 2020, 1:06:00 AM8/1/20
to bug-...@gnu.org, Damien Zammit
---
libmachdev/Makefile | 4 +-
libmachdev/ds_routines.c | 10 +++
libmachdev/machdev-device_emul.h | 1 +
libmachdev/machdev.h | 1 +
libmachdev/trivfs_server.c | 116 ++++++++++++++++++++++++++++++-
libmachdev/trivfs_server.h | 33 +++++++++
rumpdisk/block-rump.c | 16 ++++-
7 files changed, 175 insertions(+), 6 deletions(-)
create mode 100644 libmachdev/trivfs_server.h

diff --git a/libmachdev/Makefile b/libmachdev/Makefile
index 15b98cf1..3cd278f2 100644
--- a/libmachdev/Makefile
+++ b/libmachdev/Makefile
@@ -19,10 +19,10 @@ dir := libmachdev
makemode := library
libname = libmachdev

-SRCS = ds_routines.c trivfs_server.c \
+SRCS = ds_routines.c trivfs_server.c startup_notifyServer.c \
deviceServer.c notifyServer.c mach_i386Server.c

-LCLHDRS = machdev.h machdev-device_emul.h machdev-dev_hdr.h mach_device.h
+LCLHDRS = machdev.h machdev-device_emul.h machdev-dev_hdr.h mach_device.h trivfs_server.h
diff --git a/libmachdev/trivfs_server.c b/libmachdev/trivfs_server.c
index eec8585e..3390684e 100644
--- a/libmachdev/trivfs_server.c
+++ b/libmachdev/trivfs_server.c
@@ -21,21 +21,30 @@
/* This manages the master ports obtained when opening the libmachdev-based
translator node. */

+#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <error.h>
+#include <sys/mman.h>
#include <hurd/ports.h>
#include <hurd/trivfs.h>
+#include <hurd/fsys.h>
+#include <hurd/paths.h>
+#include <hurd/startup.h>
#include <hurd.h>
#include <device/device.h> /* mach console */

#include "libdiskfs/diskfs.h"
+#include "startup_notify_S.h"
#include "device_S.h"
#include "notify_S.h"
#include "fsys_S.h"
#include "mach_i386_S.h"

-static struct port_bucket *port_bucket;
+#include "trivfs_server.h"
+#include "libmachdev/machdev.h"
+
+struct port_bucket *port_bucket;

/* Trivfs hooks. */
int trivfs_fstype = FSTYPE_MISC;
@@ -49,6 +58,69 @@ int trivfs_allow_open = O_READ | O_WRITE;
struct port_class *trivfs_protid_class;
struct port_class *trivfs_cntl_class;

+/* Our control port */
+static mach_port_t machdev_ctl;
+
+/* Startup and shutdown notifications management */
+struct port_class *machdev_shutdown_notify_class;
+
+void
+arrange_shutdown_notification (void)
+
/* Implementation of notify interface */
kern_return_t
do_mach_notify_port_deleted (struct port_info *pi,
@@ -183,7 +255,42 @@ S_i386_io_perm_create (mach_port_t master_port,
@@ -193,6 +300,8 @@ trivfs_S_fsys_startup (mach_port_t bootport,
mach_port_t *realnode,
mach_msg_type_name_t *realnodetype)
{
+ machdev_ctl = cntl;
+
*realnode = MACH_PORT_NULL;
*realnodetype = MACH_MSG_TYPE_MOVE_SEND;
return 0;
@@ -260,7 +369,7 @@ resume_bootstrap_server(mach_port_t server_task, const char *server_name)
stdout = stderr = mach_open_devstream (cons, "w");
mach_port_deallocate (mach_task_self (), cons);

- printf (" %s", server_name);
+ printf ("Hurd bootstrap %s ", server_name);
fflush (stdout);
}

@@ -316,6 +425,7 @@ demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
if ((routine = device_server_routine (inp)) ||
(routine = notify_server_routine (inp)) ||
(routine = mach_i386_server_routine (inp)) ||
+ (routine = startup_notify_server_routine (inp)) ||
(routine = NULL, trivfs_demuxer (inp, outp)))
{
if (routine)
diff --git a/libmachdev/trivfs_server.h b/libmachdev/trivfs_server.h
new file mode 100644
index 00000000..a27da1b9
--- /dev/null
+++ b/libmachdev/trivfs_server.h
@@ -0,0 +1,33 @@
+extern struct port_class *machdev_shutdown_notify_class;
+
+void arrange_shutdown_notification (void);
+
+#endif /* _TRIVFS_SERVER_H */

Damien Zammit

unread,
Aug 1, 2020, 1:10:07 AM8/1/20
to bug-...@gnu.org
Hi,

I figured out why it was hanging on reboot:
netdde was frozen because pci-arbiter was not working
with my setup that used x86 method of pci access for rumpdisk.

When I removed the translators from /dev/netdde and /servers/bus/pci,
reboot-hurd rebooted cleanly with this patch.

Damien

Samuel Thibault

unread,
Aug 2, 2020, 5:16:31 PM8/2/20
to Damien Zammit, bug-...@gnu.org
Hello,

Damien Zammit, le sam. 01 août 2020 15:09:57 +1000, a ecrit:
Even if that'll be fixed properly long-term by making pci-arbiter a
bootstrap translator, I'm a bit surprised that it breaks: once rumpdisk
is initialized it doesn't actually call libpciaccess, does it? Or is
netdde hanging because of the PCI config port exclusion within the
kernel?

Samuel

Samuel Thibault

unread,
Aug 2, 2020, 5:18:15 PM8/2/20
to Damien Zammit, bug-...@gnu.org
Samuel Thibault, le dim. 02 août 2020 23:16:22 +0200, a ecrit:
Or perhaps it's simply because you haven't thought of rebuilding netdde,
which does use libmachdev as well, and doesn't provide a shutdown
pointer yet, and thus libmachdev will call into void at shutdown.

Samuel

Samuel Thibault

unread,
Aug 2, 2020, 5:20:07 PM8/2/20
to Damien Zammit, bug-...@gnu.org
Damien Zammit, le sam. 01 août 2020 15:05:38 +1000, a ecrit:
> +static void
> +device_shutdown (void)
> +{
> + struct block_data *bd = block_head;
> +
> + while (bd)
> + {
> + device_close((void *)bd);
> + bd = bd->next;
> + }
> + rump_sys_reboot (0, NULL);
> +}

Did you check that it actually flushes the disk caches? We really need
this otherwise we'll get intermitent FS corruptions.

Samuel

Samuel Thibault

unread,
Aug 2, 2020, 5:35:42 PM8/2/20
to Damien Zammit, bug-...@gnu.org
I applied, thanks!

Just one thing: I moved the functions so as to get the code in the
execution order: fsys_startup, then fsys_init, then
arrange_shutdown_notification, and S_startup_dosync before
trivfs_goaway.

Samuel

0 new messages