bug-hurd
[Top][All Lists]
Advanced

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

[PATCH hurd 7/7] proc: call `startup_essential_task' earlier


From: Justus Winter
Subject: [PATCH hurd 7/7] proc: call `startup_essential_task' earlier
Date: Sat, 17 Jan 2015 18:26:46 +0100

Previously, the proc server did not call `startup_essential_task'
until it got the message port of the startup server using
`proc_setmsgport'.

Now that we have `/servers/startup', we can do this in main, before we
start our message service loop.

A complication arises because the traditional startup server is
single-threaded.  Handle this by tweaking startup not to bind itself
to `/servers/startup' before it is ready.

* proc/main.c (main): Try to lookup `/servers/startup' and send the
message here, or...
* proc/msg.c (S_proc_setmsgport): ... fall back to the old way here.
* proc/proc.h (startup_fallback): New variable.
* startup/startup.c (main): Move code installing ourself on `/servers/startup'
(install_as_translator): ... here.
(launch_core_servers): And use it here, just before we reply to `/hurd/auth'.
---
 proc/main.c       | 23 +++++++++++++++++++++++
 proc/msg.c        |  2 +-
 proc/proc.h       |  2 ++
 startup/startup.c | 44 ++++++++++++++++++++++++++++++++------------
 4 files changed, 58 insertions(+), 13 deletions(-)

diff --git a/proc/main.c b/proc/main.c
index b4288fb..6df4141 100644
--- a/proc/main.c
+++ b/proc/main.c
@@ -22,6 +22,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 #include <mach.h>
 #include <hurd/hurd_types.h>
 #include <hurd.h>
+#include <hurd/paths.h>
 #include <hurd/startup.h>
 #include <device/device.h>
 #include <assert.h>
@@ -62,6 +63,7 @@ message_demuxer (mach_msg_header_t *inp,
 }
 
 pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER;
+int startup_fallback;
 
 error_t
 increase_priority (void)
@@ -99,6 +101,7 @@ main (int argc, char **argv, char **envp)
   error_t err;
   void *genport;
   process_t startup_port;
+  mach_port_t startup;
   struct argp argp = { 0, 0, 0, "Hurd process server" };
 
   argp_parse (&argp, argc, argv, 0, 0, 0);
@@ -173,6 +176,26 @@ main (int argc, char **argv, char **envp)
     mach_port_deallocate (mach_task_self (), cons);
   }
 
+  startup = file_name_lookup (_SERVERS_STARTUP, 0, 0);
+  if (MACH_PORT_VALID (startup))
+    {
+      err = startup_essential_task (startup, mach_task_self (),
+                                   MACH_PORT_NULL, "proc", _hurd_host_priv);
+      if (err)
+       /* Due to the single-threaded nature of /hurd/startup, it can
+          only handle requests once the core server bootstrap has
+          completed.  Therefore, it does not bind itself to
+          /servers/startup until it is ready.  */
+       /* Fall back to abusing the message port lookup.  */
+       startup_fallback = 1;
+
+      err = mach_port_deallocate (mach_task_self (), startup);
+      assert_perror (err);
+    }
+  else
+    /* Fall back to abusing the message port lookup.   */
+    startup_fallback = 1;
+
   while (1)
     ports_manage_port_operations_multithread (proc_bucket,
                                              message_demuxer,
diff --git a/proc/msg.c b/proc/msg.c
index 796cae3..c7bab99 100644
--- a/proc/msg.c
+++ b/proc/msg.c
@@ -63,7 +63,7 @@ S_proc_setmsgport (struct proc *p,
     prociterate (check_message_return, p);
   p->p_checkmsghangs = 0;
 
-  if (p == startup_proc)
+  if (p == startup_proc && startup_fallback)
     {
     /* Init is single threaded, so we can't delay our reply for
        the essential task RPC; spawn a thread to do it. */
diff --git a/proc/proc.h b/proc/proc.h
index a056d18..4be1de4 100644
--- a/proc/proc.h
+++ b/proc/proc.h
@@ -151,6 +151,8 @@ mach_port_t generic_port;   /* messages not related to a 
specific proc */
 
 pthread_mutex_t global_lock;
 
+extern int startup_fallback;   /* (ab)use /hurd/startup's message port */
+
 /* Forward declarations */
 void complete_wait (struct proc *, int);
 int check_uid (struct proc *, uid_t);
diff --git a/startup/startup.c b/startup/startup.c
index c9fe215..e01d2a8 100644
--- a/startup/startup.c
+++ b/startup/startup.c
@@ -514,6 +514,32 @@ demuxer (mach_msg_header_t *inp,
          startup_server (inp, outp));
 }
 
+error_t
+install_as_translator (void)
+{
+  error_t err;
+  file_t node;
+
+  node = file_name_lookup (_SERVERS_STARTUP, O_NOTRANS, 0);
+  if (! MACH_PORT_VALID (node))
+    {
+      if (errno == ENOENT)
+       {
+         /* Degrade gracefully if the node does not exist.  */
+         error (0, errno, "%s", _SERVERS_STARTUP);
+         return 0;
+       }
+      return errno;
+    }
+
+  err = file_set_translator (node,
+                            0, FS_TRANS_SET, 0,
+                            NULL, 0,
+                            startup, MACH_MSG_TYPE_COPY_SEND);
+  mach_port_deallocate (mach_task_self (), node);
+  return err;
+}
+
 static int
 parse_opt (int key, char *arg, struct argp_state *state)
 {
@@ -587,18 +613,6 @@ main (int argc, char **argv, char **envp)
   /* Crash if the boot filesystem task dies.  */
   request_dead_name (fstask);
 
-  file_t node = file_name_lookup (_SERVERS_STARTUP, O_NOTRANS, 0);
-  if (node == MACH_PORT_NULL)
-    error (0, errno, "%s", _SERVERS_STARTUP);
-  else
-    {
-      file_set_translator (node,
-                          0, FS_TRANS_SET, 0,
-                          NULL, 0,
-                          startup, MACH_MSG_TYPE_COPY_SEND);
-      mach_port_deallocate (mach_task_self (), node);
-    }
-
   /* Set up the set of ports we will pass to the programs we exec.  */
   for (i = 0; i < INIT_PORT_MAX; i++)
     switch (i)
@@ -672,6 +686,12 @@ launch_core_servers (void)
   proc_task2proc (procserver, authtask, &authproc);
   proc_mark_important (authproc);
   proc_mark_exec (authproc);
+
+  err = install_as_translator ();
+  if (err)
+    /* Good luck.  Who knows, maybe it's an old installation.  */
+    error (0, err, "Failed to bind to " _SERVERS_STARTUP);
+
   startup_authinit_reply (authreply, authreplytype, 0, authproc,
                          MACH_MSG_TYPE_COPY_SEND);
   mach_port_deallocate (mach_task_self (), authproc);
-- 
2.1.4




reply via email to

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