summaryrefslogtreecommitdiff
path: root/debian/patches/0005-proc-call-startup_essential_task-earlier.patch
blob: affb4656f411c3b304270eebfe25648ca7312093 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
From 04f4b23c72c04136b2003dd121009de754fc7fa8 Mon Sep 17 00:00:00 2001
From: Justus Winter <4winter@informatik.uni-hamburg.de>
Date: Wed, 7 Jan 2015 16:05:48 +0100
Subject: [PATCH hurd 05/10] proc: call `startup_essential_task' earlier

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