This is an automated email from the git hooks/post-receive script. sthibault pushed a commit to branch master in repository hurd.
commit 30c93fccf806748def668db5c2667e8add7ce03d Author: Samuel Thibault <[email protected]> Date: Thu Mar 9 23:09:35 2017 +0000 New upstream snapshot --- boot/boot.c | 6 ++++-- proc/main.c | 50 ++++++++++++++++++++++++++++++++++++++------------ proc/mgt.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- proc/proc.h | 2 ++ 4 files changed, 95 insertions(+), 23 deletions(-) diff --git a/boot/boot.c b/boot/boot.c index 9c2a021..950aedb 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -128,6 +128,10 @@ mach_port_t task_notification_port; mach_port_t dead_task_notification_port; auth_t authserver; +/* The proc server registers for new task notifications which we will + send to this port. */ +mach_port_t new_task_notification; + struct store *root_store; pthread_spinlock_t queuelock = PTHREAD_SPINLOCK_INITIALIZER; @@ -1920,8 +1924,6 @@ S_host_processor_set_priv (mach_port_t host_priv, return KERN_SUCCESS; } -mach_port_t new_task_notification; - kern_return_t S_register_new_task_notification (mach_port_t host_priv, mach_port_t notification) diff --git a/proc/main.c b/proc/main.c index 2c5ce55..d97650f 100644 --- a/proc/main.c +++ b/proc/main.c @@ -99,6 +99,30 @@ increase_priority (void) return err; } +/* Get our stderr set up to print on the console, in case we have to + panic or something. */ +error_t +open_console (mach_port_t device_master) +{ + static int got_console = 0; + mach_port_t cons; + error_t err; + + if (got_console) + return 0; + + err = device_open (device_master, D_READ|D_WRITE, "console", &cons); + if (err) + return err; + + stdin = mach_open_devstream (cons, "r"); + stdout = stderr = mach_open_devstream (cons, "w"); + + got_console = 1; + mach_port_deallocate (mach_task_self (), cons); + return 0; +} + int main (int argc, char **argv, char **envp) { @@ -146,6 +170,10 @@ main (int argc, char **argv, char **envp) assert_perror (err); mach_port_deallocate (mach_task_self (), startup_port); + /* Get our stderr set up to print on the console, in case we have + to panic or something. */ + open_console (_hurd_device_master); + mach_port_mod_refs (mach_task_self (), authserver, MACH_PORT_RIGHT_SEND, 1); _hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], authserver); mach_port_deallocate (mach_task_self (), boot); @@ -163,23 +191,21 @@ main (int argc, char **argv, char **envp) if (err && err != EPERM) error (0, err, "Increasing priority failed"); + /* Get a list of all tasks to find the kernel. */ + /* XXX: I't be nice if GNU Mach would hand us the task port. */ + add_tasks (MACH_PORT_NULL); + kernel_proc = pid_find (HURD_PID_KERNEL); + + /* Register for new task notifications using the kernel's process as + the port. */ err = register_new_task_notification (_hurd_host_priv, - generic_port, + kernel_proc + ? ports_get_right (kernel_proc) + : generic_port, MACH_MSG_TYPE_MAKE_SEND); if (err) error (0, err, "Registering task notifications failed"); - { - /* Get our stderr set up to print on the console, in case we have - to panic or something. */ - mach_port_t cons; - err = device_open (_hurd_device_master, D_READ|D_WRITE, "console", &cons); - assert_perror (err); - stdin = mach_open_devstream (cons, "r"); - stdout = stderr = mach_open_devstream (cons, "w"); - mach_port_deallocate (mach_task_self (), cons); - } - startup = file_name_lookup (_SERVERS_STARTUP, 0, 0); if (MACH_PORT_VALID (startup)) { diff --git a/proc/mgt.c b/proc/mgt.c index 8dc82f1..87a7c96 100644 --- a/proc/mgt.c +++ b/proc/mgt.c @@ -733,6 +733,22 @@ new_proc (task_t task) return p; } +/* Find the creator of the task namespace that P is in. */ +struct proc * +namespace_find_root (struct proc *p) +{ + for (; + MACH_PORT_VALID (p->p_parent->p_task_namespace); + p = p->p_parent) + { + /* Walk up the process hierarchy until we find the creator of + the task namespace. The last process we encounter that has a + valid task_namespace must be the creator. */ + } + + return p; +} + /* Used with prociterate to terminate all tasks in a task namespace. */ static void @@ -785,14 +801,7 @@ process_has_exited (struct proc *p) if (MACH_PORT_VALID (p->p_task_namespace)) { - for (tp = p; - MACH_PORT_VALID (tp->p_parent->p_task_namespace); - tp = tp->p_parent) - { - /* Walk up the process hierarchy until we find the - creator of the task namespace. */ - } - + tp = namespace_find_root (p); if (p == tp) { /* The creator of the task namespace died. Terminate @@ -966,17 +975,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 +1022,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) @@ -1055,7 +1095,9 @@ S_mach_notify_new_task (struct port_info *notify, { struct proc *parentp, *childp; - if (! notify || notify->class != generic_port_class) + if (! notify + || (kernel_proc == NULL && notify->class != generic_port_class) + || (kernel_proc != NULL && notify != (struct port_info *) kernel_proc)) return EOPNOTSUPP; parentp = task_find_nocreate (parent); diff --git a/proc/proc.h b/proc/proc.h index 2c08fd1..c069614 100644 --- a/proc/proc.h +++ b/proc/proc.h @@ -148,6 +148,7 @@ struct port_class *generic_port_class; struct port_class *exc_class; mach_port_t generic_port; /* messages not related to a specific proc */ +struct proc *kernel_proc; pthread_mutex_t global_lock; @@ -200,6 +201,7 @@ void leave_pgrp (struct proc *); void join_pgrp (struct proc *); void boot_setsid (struct proc *); +struct proc *namespace_find_root (struct proc *); void process_has_exited (struct proc *); void alert_parent (struct proc *); void reparent_zombies (struct proc *); -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hurd/hurd.git
