summaryrefslogtreecommitdiff
path: root/proc
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2017-03-09 23:10:05 +0100
committerJustus Winter <justus@gnupg.org>2017-03-09 23:55:41 +0100
commitfb3698ebbb375472832939d5534363d42de624f2 (patch)
treed0287347546182f573ab20a442fd8abdc55d5e0c /proc
parentb66e7d0f2c4e0754e51ffce14386e1884c29d08e (diff)
proc: Remove erroneous process entry.
Previously, there was a spurious copy of PID 1 in the process table, usually PID 8. PID 1, usually a sysvinit compatible process, needs to be PID 1 even though it is not actually the first process on the Hurd. To this end, PID 1 is reserved, and the task is later supplied to proc via proc_set_init_task once startup starts sysvinit. Fixes 8d16db0cc28b2d911aee918d5c3582ad29ddfeed. * proc/mgt.c (S_proc_set_init_task): Check if sysvinit's task already made it into the process table, and remove it if so.
Diffstat (limited to 'proc')
-rw-r--r--proc/mgt.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/proc/mgt.c b/proc/mgt.c
index dc3a19ee..831a3510 100644
--- a/proc/mgt.c
+++ b/proc/mgt.c
@@ -966,17 +966,46 @@ genpid ()
return nextpid++;
}
+
+
+/* Support for making sysvinit PID 1. */
+
+/* We reserve PID 1 for sysvinit. However, proc may pick up the task
+ when it is created and reserve an entry in the process table for
+ it. When startup tells us the task that it created for sysvinit,
+ we need to locate this preliminary entry and remove it. Otherwise,
+ we end up with two entries for sysvinit with the same task. */
+
+/* XXX: This is a mess. It would be nicer if startup gave us the
+ ports (e.g. sysvinit's task, the kernel task...) before starting
+ us, communicating the names using command line options. */
+
/* Implement proc_set_init_task as described in <hurd/process.defs>. */
error_t
S_proc_set_init_task(struct proc *callerp,
task_t task)
{
+ struct proc *shadow;
+
if (! callerp)
return EOPNOTSUPP;
if (callerp != startup_proc)
return EPERM;
+ /* Check if TASK already made it into the process table, and if so
+ remove it. */
+ shadow = task_find_nocreate (task);
+ if (shadow)
+ {
+ /* Cheat a little so we can use complete_exit. */
+ shadow->p_dead = 1;
+ shadow->p_waited = 1;
+ mach_port_deallocate (mach_task_self (), shadow->p_task);
+ shadow->p_task = MACH_PORT_NULL;
+ complete_exit (shadow);
+ }
+
init_proc->p_task = task;
proc_death_notify (init_proc);
add_proc_to_hash (init_proc);
@@ -984,6 +1013,8 @@ S_proc_set_init_task(struct proc *callerp,
return 0;
}
+
+
/* Implement proc_mark_important as described in <hurd/process.defs>. */
kern_return_t
S_proc_mark_important (struct proc *p)