bug-hurd
[Top][All Lists]
Advanced

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

[PATCH v2] machdev,pci,rump: Rework bootstrap


From: Damien Zammit
Subject: [PATCH v2] machdev,pci,rump: Rework bootstrap
Date: Mon, 15 Mar 2021 20:37:48 +1100

* libmachdev/machdev.h
(machdev_trivfs_init): Add controlport output parameter
* libmachdev/trivfs_server.c
Rework the bootstrapping of machdev
* pci-arbiter/Makefile
Remove startup.c
* pci-arbiter/startup.{c,h}
Delete files
* pci-arbiter/main.c
(main): Rework bootstrap, remove notification, add controlport
* rumpdisk/main.c
(main): Don't pretend to be the arbiter anymore, add controlport

---
 libmachdev/machdev.h       |   5 +-
 libmachdev/trivfs_server.c | 103 ++++++++++++++++++++++++++++---------
 pci-arbiter/Makefile       |   2 +-
 pci-arbiter/main.c         |  29 ++++-------
 pci-arbiter/startup.c      |  60 ---------------------
 pci-arbiter/startup.h      |  31 -----------
 rumpdisk/main.c            |   8 +--
 7 files changed, 93 insertions(+), 145 deletions(-)
 delete mode 100644 pci-arbiter/startup.c
 delete mode 100644 pci-arbiter/startup.h

diff --git a/libmachdev/machdev.h b/libmachdev/machdev.h
index 8f613b35..c45f3d67 100644
--- a/libmachdev/machdev.h
+++ b/libmachdev/machdev.h
@@ -33,8 +33,9 @@ void machdev_device_init(void);
 void machdev_device_shutdown(mach_port_t dosync_handle);
 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, 
const char *path, mach_port_t *bootstrap);
-void machdev_trivfs_server(mach_port_t bootstrap);
+int machdev_trivfs_init(mach_port_t bootstrap_resume_task, const char *name, 
const char *path,
+                        mach_port_t *bootstrap, mach_port_t *controlport);
+void machdev_trivfs_server(mach_port_t controlport);
 boolean_t machdev_is_master_device (mach_port_t port);
 
 #endif
diff --git a/libmachdev/trivfs_server.c b/libmachdev/trivfs_server.c
index e3e4045d..adf111bf 100644
--- a/libmachdev/trivfs_server.c
+++ b/libmachdev/trivfs_server.c
@@ -63,7 +63,7 @@ struct port_class *trivfs_protid_class;
 struct trivfs_control *control;
 
 /* Are we providing bootstrap translator? */
-static boolean_t bootstrapped;
+static boolean_t bootstrapping;
 
 /* Our underlying node in the FS for bootstrap */
 static mach_port_t underlying;
@@ -239,12 +239,37 @@ trivfs_S_fsys_startup (mach_port_t bootport,
                        mach_port_t *realnode,
                        mach_msg_type_name_t *realnodetype)
 {
+  mach_port_t mybootport;
+
   control_port = cntl;
   *realnode = MACH_PORT_NULL;
-  *realnodetype = MACH_MSG_TYPE_MOVE_SEND;
+  *realnodetype = MACH_MSG_TYPE_COPY_SEND;
+
+  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
+essential_task (void)
+{
+  mach_port_t host, startup;
+
+  get_privileged_ports (&host, 0);
+  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,
@@ -255,11 +280,19 @@ trivfs_S_fsys_init (struct trivfs_control *fsys,
   mach_port_t *portarray;
   unsigned int i;
   uid_t idlist[] = {0, 0, 0};
-  mach_port_t root;
+  mach_port_t root, bootstrap;
   retry_type retry;
   string_t retry_name;
   mach_port_t right = MACH_PORT_NULL;
+  process_t proc;
 
+  /* Traverse to the bootstrapping server first */
+  task_get_bootstrap_port (mach_task_self (), &bootstrap);
+  if (bootstrap)
+    {
+      err = fsys_init (bootstrap, procserver, MACH_MSG_TYPE_COPY_SEND, 
authhandle);
+      assert_perror_backtrace (err);
+    }
   err = fsys_getroot (control_port, MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND,
                       idlist, 3, idlist, 3, 0,
                       &retry, retry_name, &root);
@@ -278,16 +311,32 @@ trivfs_S_fsys_init (struct trivfs_control *fsys,
   portarray[INIT_PORT_CWDIR] = root;
   _hurd_init (0, NULL, portarray, INIT_PORT_MAX, NULL, 0);
 
-  arrange_shutdown_notification ();
+  /* Mark us as important.  */
+  proc = getproc ();
+  assert_backtrace (proc);
+  err = proc_mark_important (proc);
+  assert_perror_backtrace (err);
+  err = proc_mark_exec (proc);
+  assert_perror_backtrace (err);
+  proc_set_exe (proc, program_invocation_short_name);
+  mach_port_deallocate (mach_task_self (), proc);
 
-  /* Install the bootstrap port on /dev/something so users
-   * can still access the bootstrapped device */
-  if (bootstrapped && devnode)
+  if (bootstrapping)
     {
-      right = ports_get_send_right (&control->pi);
-      install_as_translator (right);
-      control->underlying = underlying;
+      if (devnode)
+        {
+          /* Install the bootstrap port on /dev/something so users
+           * can still access the bootstrapped device */
+          right = ports_get_send_right (&control->pi);
+          install_as_translator (right);
+          control->underlying = underlying;
+        }
+      /* Mark us as essential if bootstrapping */
+      essential_task ();
     }
+
+  arrange_shutdown_notification ();
+
   return 0;
 }
 
@@ -296,12 +345,8 @@ arrange_shutdown_notification (void)
 {
   error_t err;
   mach_port_t initport, notify;
-  process_t proc;
   struct port_info *pi;
 
-  proc = getproc ();
-  assert_backtrace (proc);
-
   machdev_shutdown_notify_class = ports_create_class (0, 0);
 
   /* Arrange to get notified when the system goes down */
@@ -310,10 +355,6 @@ arrange_shutdown_notification (void)
   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)
     {
@@ -380,37 +421,49 @@ 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 ("Hurd bootstrap %s ", server_name);
+  printf ("%s ", server_name);
   fflush (stdout);
 }
 
 int
-machdev_trivfs_init(mach_port_t bootstrap_resume_task, const char *name, const 
char *path, mach_port_t *bootstrap)
+machdev_trivfs_init(mach_port_t bootstrap_resume_task, const char *name, const 
char *path,
+                    mach_port_t *bootstrap, mach_port_t *controlport)
 {
+  mach_port_t mybootstrap = MACH_PORT_NULL;
+  task_t parent_task;
   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);
   trivfs_create_control (MACH_PORT_NULL, trivfs_cntl_class, port_bucket,
                          trivfs_protid_class, 0, &control);
 
+  *bootstrap = MACH_PORT_NULL;
+
+  task_get_bootstrap_port (mach_task_self (), &mybootstrap);
+  if (mybootstrap)
+    {
+      *bootstrap = mybootstrap;
+      fsys_getpriv (*bootstrap, &_hurd_host_priv, &_hurd_device_master, 
&parent_task);
+    }
+
   if (bootstrap_resume_task != MACH_PORT_NULL)
     {
       if (path)
        devnode = strdup(path);
       resume_bootstrap_server(bootstrap_resume_task, name);
-      *bootstrap = ports_get_send_right (&control->pi);
+      *controlport = ports_get_send_right (&control->pi);
 
       /* We need to install as a translator later */
-      bootstrapped = TRUE;
+      bootstrapping = TRUE;
     }
   else
     {
-      task_get_bootstrap_port (mach_task_self (), bootstrap);
       if (*bootstrap == MACH_PORT_NULL)
         error (1, 0, "must be started as a translator");
+      *controlport = MACH_PORT_NULL;
 
       /* We do not need to install as a translator later */
-      bootstrapped = FALSE;
+      bootstrapping = FALSE;
     }
 
   return 0;
@@ -502,7 +555,7 @@ machdev_trivfs_server(mach_port_t bootstrap)
   int err;
   pthread_t t;
 
-  if (bootstrapped == FALSE)
+  if (bootstrapping == FALSE)
     {
       /* This path is executed when a parent exists */
       err = trivfs_startup (bootstrap, 0,
diff --git a/pci-arbiter/Makefile b/pci-arbiter/Makefile
index b32bc579..d3d205ec 100644
--- a/pci-arbiter/Makefile
+++ b/pci-arbiter/Makefile
@@ -21,7 +21,7 @@ makemode      = server
 PORTDIR = $(srcdir)/port
 
 SRCS           = main.c pci-ops.c netfs_impl.c \
-                 pcifs.c ncache.c options.c func_files.c startup.c \
+                 pcifs.c ncache.c options.c func_files.c \
                  pciServer.c startup_notifyServer.c
 OBJS           = $(SRCS:.c=.o) $(MIGSTUBS)
 
diff --git a/pci-arbiter/main.c b/pci-arbiter/main.c
index efb9f65c..d43afe3f 100644
--- a/pci-arbiter/main.c
+++ b/pci-arbiter/main.c
@@ -43,7 +43,6 @@
 #include <pciaccess.h>
 #include <pthread.h>
 #include "pcifs.h"
-#include "startup.h"
 
 struct pcifs *fs;
 volatile struct mapped_time_value *pcifs_maptime;
@@ -106,17 +105,9 @@ pci_device_close (void *d)
 static void
 pci_device_shutdown (mach_port_t dosync_handle)
 {
-  struct port_info *inpi = ports_lookup_port (netfs_port_bucket, dosync_handle,
-                                             pci_shutdown_notify_class);
-
-  if (!inpi)
-    return;
-
   // Free all libpciaccess resources
   pci_system_cleanup ();
 
-  ports_port_deref (inpi);
-
   ports_destroy_right (&pci_control_port);
 
   netfs_shutdown (FSYS_GOAWAY_FORCE);
@@ -182,7 +173,6 @@ netfs_server_func (void *arg)
   return NULL;
 }
 
-
 static mach_port_t
 pcifs_startup(mach_port_t bootstrap, int flags)
 {
@@ -209,7 +199,7 @@ int
 main (int argc, char **argv)
 {
   error_t err;
-  mach_port_t bootstrap;
+  mach_port_t bootstrap, controlport = MACH_PORT_NULL;
   mach_port_t disk_server_task;
   pthread_t t, nt;
 
@@ -221,8 +211,8 @@ main (int argc, char **argv)
   if (disk_server_task != MACH_PORT_NULL)
     {
       machdev_register (&pci_arbiter_emulation_ops);
+      machdev_trivfs_init (disk_server_task, "pci", "/servers/bus/pci", 
&bootstrap, &controlport);
       machdev_device_init ();
-      machdev_trivfs_init (disk_server_task, "pci", "/servers/bus/pci", 
&bootstrap);
       err = pthread_create (&t, NULL, machdev_server, NULL);
       if (err)
         error (1, err, "Creating machdev thread");
@@ -250,14 +240,19 @@ main (int argc, char **argv)
 
   if (disk_server_task != MACH_PORT_NULL)
     machdev_trivfs_server(bootstrap);
-    /* Timer started, quickly do all these next, before we call rump_init */
 
   /* Create the root node first */
   err = init_root_node ();
   if (err)
     error (1, err, "Creating the root node");
   
-  pcifs_startup (bootstrap, O_READ);
+  /* If we have a controlport, we are the bootstrap fs
+   * so we need to call fsys_startup on ourselves
+   * otherwise call it on our bootstrap port */
+  if (controlport)
+    pcifs_startup (controlport, O_READ);
+  else
+    pcifs_startup (bootstrap, O_READ);
 
   err = init_file_system (fs);
   if (err)
@@ -278,12 +273,6 @@ main (int argc, char **argv)
     error (1, err, "Creating netfs loop thread");
   pthread_detach (nt);
 
-  /*
-   * Ask init to tell us when the system is going down,
-   * so we can try to be friendly to our correspondents on the network.
-   */
-  arrange_shutdown_notification ();
-
   /* Let the other threads do their job */
   pthread_exit(NULL);
   /* Never reached */
diff --git a/pci-arbiter/startup.c b/pci-arbiter/startup.c
deleted file mode 100644
index 421c9e24..00000000
--- a/pci-arbiter/startup.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-   Copyright (C) 2017 Free Software Foundation, Inc.
-   Written by Michael I. Bushnell, p/BSG.
-
-   This file is part of the GNU Hurd.
-
-   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 <unistd.h>
-#include <hurd/paths.h>
-#include <hurd/startup.h>
-#include <hurd/netfs.h>
-
-struct port_class *pci_shutdown_notify_class;
-
-void
-arrange_shutdown_notification ()
-{
-  error_t err;
-  mach_port_t initport, notify;
-  struct port_info *pi;
-
-  pci_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 (pci_shutdown_notify_class, netfs_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/pci-arbiter/startup.h b/pci-arbiter/startup.h
deleted file mode 100644
index 416b84d6..00000000
--- a/pci-arbiter/startup.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-   Copyright (C) 2017 Free Software Foundation, Inc.
-   Written by Michael I. Bushnell, p/BSG.
-
-   This file is part of the GNU Hurd.
-
-   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 *pci_shutdown_notify_class;
-
-void arrange_shutdown_notification (void);
-
-#endif /* STARTUP_H */
diff --git a/rumpdisk/main.c b/rumpdisk/main.c
index a26e17cb..c4faec85 100644
--- a/rumpdisk/main.c
+++ b/rumpdisk/main.c
@@ -31,11 +31,6 @@
 #include <pthread.h>
 #include <mach.h>
 
-/* TODO: Add api to pciaccess to allow selecting backend.
- * For now we pretend to be the arbiter and claim x86 method.
- */
-char *netfs_server_name = "pci-arbiter";
-
 mach_port_t bootstrap_resume_task = MACH_PORT_NULL;
 
 static const struct argp_option options[] = {
@@ -101,6 +96,7 @@ int
 main (int argc, char **argv)
 {
   mach_port_t bootstrap = MACH_PORT_NULL;
+  mach_port_t controlport;
   int err;
   pthread_t t;
 
@@ -117,8 +113,8 @@ main (int argc, char **argv)
     }
 
   rump_register_block ();
+  machdev_trivfs_init (bootstrap_resume_task, "rumpdisk", "/dev/rumpdisk", 
&bootstrap, &controlport);
   machdev_device_init ();
-  machdev_trivfs_init (bootstrap_resume_task, "rumpdisk", "/dev/rumpdisk", 
&bootstrap);
   err = pthread_create (&t, NULL, machdev_server, NULL);
   if (err)
     return err;
-- 
2.30.1




reply via email to

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