diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-11-21 06:03:02 +0100 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-11-21 06:03:02 +0100 |
commit | bc2df54e33fd813aeaa43ef038a8b88446d6cb54 (patch) | |
tree | 0fb789de28e02b2feef21e51b054fba78134080b | |
parent | f8b1a9ceb00c1729c6b9aaa74b503d01f0becf57 (diff) |
drop merged or obsoleted patches
14 files changed, 23 insertions, 5813 deletions
diff --git a/debian/patches/external-splitinit.patch b/debian/patches/external-splitinit.patch deleted file mode 100644 index c0f05fee..00000000 --- a/debian/patches/external-splitinit.patch +++ /dev/null @@ -1,55 +0,0 @@ -Include procfs, random, and DDE in the build - -diff --git a/Makefile b/Makefile -index 0b9eff2..12b56f0 100644 ---- a/Makefile -+++ b/Makefile -@@ -28,7 +28,8 @@ include ./Makeconf - # Hurd libraries - lib-subdirs = libshouldbeinlibc libihash libiohelp libports libthreads \ - libpager libfshelp libdiskfs libtrivfs libps \ -- libnetfs libpipe libstore libhurdbugaddr libftpconn libcons -+ libnetfs libpipe libstore libhurdbugaddr libftpconn libcons \ -+ libmachdev libbpf libddekit libhurd-slab eth-filter eth-multiplexer - - # Hurd programs - prog-subdirs = auth proc exec term \ -@@ -40,8 +41,9 @@ prog-subdirs = auth proc exec init term \ - benchmarks fstests \ - random \ - procfs \ - startup \ - init \ -+ devnode \ - - ifeq ($(HAVE_SUN_RPC),yes) - prog-subdirs += nfs nfsd -diff --git a/configure.ac b/configure.ac -index 05b959b..68ec159 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -227,6 +227,12 @@ AC_SUBST(boot_store_types)dnl - AC_MSG_CHECKING(boot store types) - AC_MSG_RESULT($boot_store_types) - -+AC_CHECK_LIB(pciaccess, pci_system_init, LIBPCIACCESS=-lpciaccess, LIBPCIACCESS=no) -+AC_SUBST(LIBPCIACCESS) -+if test "$LIBPCIACCESS" = "no"; then -+ AC_MSG_ERROR([libpciaccess must be install in order to use libddekit]) -+fi -+ - # Check for ncursesw, which is needed for the console-curses client. - hurd_LIB_NCURSESW - -diff --git a/Makeconf b/Makeconf -index 5439913..1d70e53 100644 ---- a/Makeconf -+++ b/Makeconf -@@ -582,6 +582,7 @@ mach_defs_names = bootstrap exc mach mach4 \ - mach_debug_defs_names = mach_debug - device_defs_names = dev_forward device device_reply device_request - -+mach_defs_names += experimental - mach_defs = $(addsuffix .defs,$(mach_defs_names)) - mach_debug_defs = $(addsuffix .defs,$(mach_debug_defs_names)) - device_defs = $(addsuffix .defs,$(device_defs_names)) diff --git a/debian/patches/external.patch b/debian/patches/external.patch index 05a00c93..c0f05fee 100644 --- a/debian/patches/external.patch +++ b/debian/patches/external.patch @@ -13,27 +13,17 @@ index 0b9eff2..12b56f0 100644 + libmachdev libbpf libddekit libhurd-slab eth-filter eth-multiplexer # Hurd programs - prog-subdirs = auth proc exec init term \ -@@ -40,6 +41,7 @@ prog-subdirs = auth proc exec init term \ + prog-subdirs = auth proc exec term \ +@@ -40,8 +41,9 @@ prog-subdirs = auth proc exec init term \ benchmarks fstests \ random \ procfs \ + startup \ + init \ + devnode \ ifeq ($(HAVE_SUN_RPC),yes) prog-subdirs += nfs nfsd ---- hurd-debian.orig/Makeconf -+++ hurd-debian/Makeconf -@@ -548,6 +548,6 @@ vpath %.defs $(top_srcdir)/hurd - # These we want to find in the libc include directory... - mach_defs_names = bootstrap exc mach mach4 \ - mach_host mach_port mach_timer_reply memory_object \ -- memory_object_default notify -+ memory_object_default notify experimental - mach_debug_defs_names = mach_debug - device_defs_names = dev_forward device device_reply device_request - - mach_defs = $(addsuffix .defs,$(mach_defs_names)) diff --git a/configure.ac b/configure.ac index 05b959b..68ec159 100644 --- a/configure.ac @@ -51,3 +41,15 @@ index 05b959b..68ec159 100644 # Check for ncursesw, which is needed for the console-curses client. hurd_LIB_NCURSESW +diff --git a/Makeconf b/Makeconf +index 5439913..1d70e53 100644 +--- a/Makeconf ++++ b/Makeconf +@@ -582,6 +582,7 @@ mach_defs_names = bootstrap exc mach mach4 \ + mach_debug_defs_names = mach_debug + device_defs_names = dev_forward device device_reply device_request + ++mach_defs_names += experimental + mach_defs = $(addsuffix .defs,$(mach_defs_names)) + mach_debug_defs = $(addsuffix .defs,$(mach_debug_defs_names)) + device_defs = $(addsuffix .defs,$(device_defs_names)) diff --git a/debian/patches/libexec-splitinit.patch b/debian/patches/libexec-splitinit.patch deleted file mode 100644 index 18634a35..00000000 --- a/debian/patches/libexec-splitinit.patch +++ /dev/null @@ -1,88 +0,0 @@ -diff --git a/config/ttys b/config/ttys -index 6a548d5..d10bfcc 100644 ---- a/config/ttys -+++ b/config/ttys -@@ -4,11 +4,11 @@ - - # name program type status comments - --console "/libexec/getty 9600" mach-gnu-color on secure trusted console --tty1 "/libexec/getty 38400" hurd on secure trusted console --tty2 "/libexec/getty 38400" hurd on secure trusted console --tty3 "/libexec/getty 38400" hurd on secure trusted console --tty4 "/libexec/getty 38400" hurd on secure trusted console --tty5 "/libexec/getty 38400" hurd on secure trusted console --tty6 "/libexec/getty 38400" hurd on secure trusted console --#com0 "/libexec/getty 9600" dialup on secure -+console "/sbin/getty 9600" mach-gnu-color on secure trusted console -+tty1 "/sbin/getty 38400" hurd on secure trusted console -+tty2 "/sbin/getty 38400" hurd on secure trusted console -+tty3 "/sbin/getty 38400" hurd on secure trusted console -+tty4 "/sbin/getty 38400" hurd on secure trusted console -+tty5 "/sbin/getty 38400" hurd on secure trusted console -+tty6 "/sbin/getty 38400" hurd on secure trusted console -+#com0 "/sbin/getty 9600" dialup on secure -diff --git a/daemons/runsystem.sh b/daemons/runsystem.sh -index c3cb2d6..0ce4f59 100644 ---- a/daemons/runsystem.hurd -+++ b/daemons/runsystem.hurd -@@ -23,8 +23,8 @@ fallback_shells='/bin/sh /bin/bash /bin/csh /bin/ash /bin/shd' - SHELL=/bin/sh - - # Programs that do multi-user startup. --RUNCOM=/libexec/rc --RUNTTYS=/libexec/runttys -+RUNCOM=/etc/hurd/rc -+RUNTTYS=/sbin/runttys - # Signals that we should pass down to runttys. - runttys_sigs='TERM INT HUP TSTP' - -diff --git a/init/init.c b/init/init.c -index d66bee0..14d822e 100644 ---- a/startup/startup.c -+++ b/startup/startup.c -@@ -888,7 +888,7 @@ frob_kernel_process (void) - /** Running userland. **/ - - /* In the "split-init" setup, we just run a single program (usually -- /libexec/runsystem) that is not expected to ever exit (or stop). -+ /etc/hurd/runsystem) that is not expected to ever exit (or stop). - If it does exit (or can't be started), we go to an emergency single-user - shell as a fallback. */ - -@@ -1004,7 +1004,7 @@ process_signal (int signo) - } - } - --/* Start the child program PROG. It is run via /libexec/console-run -+/* Start the child program PROG. It is run via /sbin/console-run - with the given additional arguments. */ - static int - start_child (const char *prog, char **progargs) -@@ -1016,7 +1016,7 @@ start_child (const char *prog, char **progargs) - - if (progargs == 0) - { -- const char *argv[] = { "/libexec/console-run", prog, 0 }; -+ const char *argv[] = { "/sbin/console-run", prog, 0 }; - err = argz_create ((char **) argv, &args, &arglen); - } - else -@@ -1026,7 +1026,7 @@ start_child (const char *prog, char **progargs) - ++argc; - { - const char *argv[2 + argc + 1]; -- argv[0] = "/libexec/console-run"; -+ argv[0] = "/sbin/console-run"; - argv[1] = prog; - argv[2 + argc] = 0; - while (argc-- > 0) -@@ -1086,7 +1086,7 @@ launch_something (const char *why) - static unsigned int try; - static const char *const tries[] = - { -- "/libexec/runsystem", -+ "/etc/hurd/runsystem", - _PATH_BSHELL, - "/bin/shd", /* XXX */ - }; diff --git a/debian/patches/libexec.patch b/debian/patches/libexec.patch index 12b5a01d..18634a35 100644 --- a/debian/patches/libexec.patch +++ b/debian/patches/libexec.patch @@ -24,8 +24,8 @@ index 6a548d5..d10bfcc 100644 +#com0 "/sbin/getty 9600" dialup on secure diff --git a/daemons/runsystem.sh b/daemons/runsystem.sh index c3cb2d6..0ce4f59 100644 ---- a/daemons/runsystem.sh -+++ b/daemons/runsystem.sh +--- a/daemons/runsystem.hurd ++++ b/daemons/runsystem.hurd @@ -23,8 +23,8 @@ fallback_shells='/bin/sh /bin/bash /bin/csh /bin/ash /bin/shd' SHELL=/bin/sh @@ -37,23 +37,10 @@ index c3cb2d6..0ce4f59 100644 # Signals that we should pass down to runttys. runttys_sigs='TERM INT HUP TSTP' -diff --git a/doc/hurd.texi b/doc/hurd.texi -index ea73a4c..7d7af39 100644 ---- a/doc/hurd.texi -+++ b/doc/hurd.texi -@@ -570,7 +570,7 @@ The @option{--multiboot-command-line} option tells the file system server that - it is a root filesystem, which triggers it to run @command{/hurd/init} as PID - 1. @command{/hurd/init} starts the @command{/hurd/proc} and - @command{/hurd/auth} servers. After the servers are launched --@command{/hurd/init} starts the @command{/libexec/runsystem.sh} script to -+@command{/hurd/init} starts the @command{/etc/hurd/runsystem.sh} script to - finish booting. - - After the Hurd has been booted, other sets of core Hurd servers can be diff --git a/init/init.c b/init/init.c index d66bee0..14d822e 100644 ---- a/init/init.c -+++ b/init/init.c +--- a/startup/startup.c ++++ b/startup/startup.c @@ -888,7 +888,7 @@ frob_kernel_process (void) /** Running userland. **/ @@ -90,14 +77,12 @@ index d66bee0..14d822e 100644 argv[1] = prog; argv[2 + argc] = 0; while (argc-- > 0) -@@ -1086,8 +1086,8 @@ launch_something (const char *why) +@@ -1086,7 +1086,7 @@ launch_something (const char *why) static unsigned int try; static const char *const tries[] = { - "/libexec/runsystem", -- "/libexec/runsystem.gnu", + "/etc/hurd/runsystem", -+ "/etc/hurd/runsystem.gnu", _PATH_BSHELL, "/bin/shd", /* XXX */ }; diff --git a/debian/patches/proc_set_init_task.patch b/debian/patches/proc_set_init_task.patch deleted file mode 100644 index fe76ac02..00000000 --- a/debian/patches/proc_set_init_task.patch +++ /dev/null @@ -1,284 +0,0 @@ ---- a/hurd/process.defs -+++ b/hurd/process.defs -@@ -373,7 +373,11 @@ routine proc_getnports ( - - /*** Routines related to early server bootstrapping ***/ - --skip; /* Reserved for proc_set_init_task */ -+/* Set the task of process HURD_PID_INIT. Only the startup process -+ HURD_PID_STARTUP may use this interface. */ -+routine proc_set_init_task ( -+ process: process_t; -+ task: task_t); - - /* Inform the process server that the process is important. */ - routine proc_mark_important ( ---- a/hurd/process_request.defs -+++ b/hurd/process_request.defs -@@ -374,7 +374,10 @@ simpleroutine proc_getnports_request ( - - /*** Routines related to early server bootstrapping ***/ - --skip; /* Reserved for proc_set_init_task */ -+simpleroutine proc_set_init_task_request ( -+ process: process_t; -+ ureplyport reply: reply_port_t; -+ task: task_t); - - /* Inform the process server that the process is important. */ - simpleroutine proc_mark_important_request ( ---- a/include/pids.h -+++ b/include/pids.h -@@ -22,8 +22,9 @@ - #ifndef _HURD_PROCESSES_H - #define _HURD_PROCESSES_H - --#define HURD_PID_STARTUP 1 --#define HURD_PID_KERNEL 2 --#define HURD_PID_PROC 3 -+#define HURD_PID_INIT 1 -+#define HURD_PID_STARTUP 2 -+#define HURD_PID_KERNEL 3 -+#define HURD_PID_PROC 4 - - #endif /* _HURD_PROCESSES_H */ ---- a/init/init.c -+++ b/init/init.c -@@ -1089,7 +1089,7 @@ start_child (const char *prog, char **pr - NULL, 0, /* OSF Mach */ - #endif - 0, &child_task); -- proc_child (procserver, child_task); -+ proc_set_init_task (procserver, child_task); - proc_task2pid (procserver, child_task, &child_pid); - proc_task2proc (procserver, child_task, &default_ports[INIT_PORT_PROC]); - ---- a/proc/main.c -+++ b/proc/main.c -@@ -1,5 +1,5 @@ - /* Initialization of the proc server -- Copyright (C) 1993,94,95,96,97,99,2000,01 Free Software Foundation, Inc. -+ Copyright (C) 1993,94,95,96,97,99,2000,01,13 Free Software Foundation, Inc. - - This file is part of the GNU Hurd. - -@@ -88,7 +88,12 @@ main (int argc, char **argv, char **envp - generic_port = ports_get_right (genport); - - /* Create the initial proc object for init (PID 1). */ -- startup_proc = create_startup_proc (); -+ init_proc = create_init_proc (); -+ -+ /* Create the startup proc object for /hurd/init (PID 2). */ -+ startup_proc = allocate_proc (MACH_PORT_NULL); -+ startup_proc->p_deadmsg = 1; -+ complete_proc (startup_proc, HURD_PID_STARTUP); - - /* Create our own proc object. */ - self_proc = allocate_proc (mach_task_self ()); ---- a/proc/mgt.c -+++ b/proc/mgt.c -@@ -1,5 +1,6 @@ - /* Process management -- Copyright (C) 1992,93,94,95,96,99,2000,01,02 Free Software Foundation, Inc. -+ Copyright (C) 1992,93,94,95,96,99,2000,01,02,13 -+ Free Software Foundation, Inc. - - This file is part of the GNU Hurd. - -@@ -184,7 +185,7 @@ S_proc_child (struct proc *parentp, - /* Process hierarchy. Remove from our current location - and place us under our new parent. Sanity check to make sure - parent is currently init. */ -- assert (childp->p_parent == startup_proc); -+ assert (childp->p_parent == init_proc); - if (childp->p_sib) - childp->p_sib->p_prevsib = childp->p_prevsib; - *childp->p_prevsib = childp->p_sib; -@@ -587,7 +588,7 @@ allocate_proc (task_t task) - /* Allocate and initialize the proc structure for init (PID 1), - the original parent of all other procs. */ - struct proc * --create_startup_proc (void) -+create_init_proc (void) - { - static const uid_t zero; - struct proc *p; -@@ -596,7 +597,7 @@ create_startup_proc (void) - p = allocate_proc (MACH_PORT_NULL); - assert (p); - -- p->p_pid = HURD_PID_STARTUP; -+ p->p_pid = HURD_PID_INIT; - - p->p_parent = p; - p->p_sib = 0; -@@ -644,7 +645,7 @@ proc_death_notify (struct proc *p) - } - - /* Complete a new process that has been allocated but not entirely initialized. -- This gets called for every process except startup_proc (PID 1). */ -+ This gets called for every process except init_proc (PID 1). */ - void - complete_proc (struct proc *p, pid_t pid) - { -@@ -667,30 +668,47 @@ complete_proc (struct proc *p, pid_t pid - snprintf (name, sizeof name, "with pid %i", pid); - task_set_name (p->p_task, name); - -- ids_ref (&nullids); -- p->p_id = &nullids; -+ if (pid == HURD_PID_STARTUP) -+ { -+ /* Equip HURD_PID_STARTUP with the same credentials as -+ HURD_PID_INIT. */ -+ static const uid_t zero; -+ p->p_id = make_ids (&zero, 1); -+ assert (p->p_id); -+ } -+ else -+ { -+ ids_ref (&nullids); -+ p->p_id = &nullids; -+ } - - p->p_login = nulllogin; - p->p_login->l_refcnt++; - - /* Our parent is init for now. */ -- p->p_parent = startup_proc; -+ p->p_parent = init_proc; - -- p->p_sib = startup_proc->p_ochild; -- p->p_prevsib = &startup_proc->p_ochild; -+ p->p_sib = init_proc->p_ochild; -+ p->p_prevsib = &init_proc->p_ochild; - if (p->p_sib) - p->p_sib->p_prevsib = &p->p_sib; -- startup_proc->p_ochild = p; -+ init_proc->p_ochild = p; - p->p_loginleader = 0; - p->p_ochild = 0; - p->p_parentset = 0; - - p->p_noowner = 1; - -- p->p_pgrp = startup_proc->p_pgrp; -+ p->p_pgrp = init_proc->p_pgrp; - -- proc_death_notify (p); -- add_proc_to_hash (p); -+ /* At this point, we do not know the task of the startup process, -+ defer registering death notifications and adding it to the hash -+ tables. */ -+ if (pid != HURD_PID_STARTUP) -+ { -+ proc_death_notify (p); -+ add_proc_to_hash (p); -+ } - join_pgrp (p); - } - -@@ -752,7 +770,7 @@ process_has_exited (struct proc *p) - nowait_msg_proc_newids (tp->p_msgport, tp->p_task, - 1, tp->p_pgrp->pg_pgid, - !tp->p_pgrp->pg_orphcnt); -- tp->p_parent = startup_proc; -+ tp->p_parent = init_proc; - if (tp->p_dead) - isdead = 1; - } -@@ -760,17 +778,17 @@ process_has_exited (struct proc *p) - nowait_msg_proc_newids (tp->p_msgport, tp->p_task, - 1, tp->p_pgrp->pg_pgid, - !tp->p_pgrp->pg_orphcnt); -- tp->p_parent = startup_proc; -+ tp->p_parent = init_proc; - - /* And now append the lists. */ -- tp->p_sib = startup_proc->p_ochild; -+ tp->p_sib = init_proc->p_ochild; - if (tp->p_sib) - tp->p_sib->p_prevsib = &tp->p_sib; -- startup_proc->p_ochild = p->p_ochild; -- p->p_ochild->p_prevsib = &startup_proc->p_ochild; -+ init_proc->p_ochild = p->p_ochild; -+ p->p_ochild->p_prevsib = &init_proc->p_ochild; - - if (isdead) -- alert_parent (startup_proc); -+ alert_parent (init_proc); - } - - /* If an operation is in progress for this process, cause it -@@ -950,3 +968,21 @@ S_proc_get_code (struct proc *callerp, - - return 0; - } -+ -+/* Implement proc_set_init_task as described in <hurd/process.defs>. */ -+error_t -+S_proc_set_init_task(struct proc *callerp, -+ task_t task) -+{ -+ if (! callerp) -+ return EOPNOTSUPP; -+ -+ if (callerp != startup_proc) -+ return EPERM; -+ -+ init_proc->p_task = task; -+ proc_death_notify (init_proc); -+ add_proc_to_hash (init_proc); -+ -+ return 0; -+} ---- a/proc/proc.h -+++ b/proc/proc.h -@@ -1,5 +1,6 @@ - /* Process server definitions -- Copyright (C) 1992,93,94,95,96,99,2000,01 Free Software Foundation, Inc. -+ Copyright (C) 1992,93,94,95,96,99,2000,01,13 -+ Free Software Foundation, Inc. - - This file is part of the GNU Hurd. - -@@ -134,7 +135,8 @@ struct exc - - mach_port_t authserver; - struct proc *self_proc; /* process HURD_PID_PROC (us) */ --struct proc *startup_proc; /* process 1 (init) */ -+struct proc *init_proc; /* process 1 (sysvinit) */ -+struct proc *startup_proc; /* process 2 (hurd/init) */ - - struct port_bucket *proc_bucket; - struct port_class *proc_class; -@@ -190,7 +192,7 @@ void exc_clean (void *); - struct proc *add_tasks (task_t); - int pidfree (pid_t); - --struct proc *create_startup_proc (void); -+struct proc *create_init_proc (void); - struct proc *allocate_proc (task_t); - void proc_death_notify (struct proc *); - void complete_proc (struct proc *, pid_t); ---- a/procfs/main.c -+++ b/procfs/main.c -@@ -42,7 +42,7 @@ uid_t opt_anon_owner; - #define OPT_CLK_TCK sysconf(_SC_CLK_TCK) - #define OPT_STAT_MODE 0400 - #define OPT_FAKE_SELF -1 --#define OPT_KERNEL_PID 2 -+#define OPT_KERNEL_PID 3 - #define OPT_ANON_OWNER 0 - - #define NODEV_KEY -1 /* <= 0, so no short option. */ -@@ -153,7 +153,7 @@ struct argp_option common_options[] = { - { "kernel-process", 'k', "PID", 0, - "Process identifier for the kernel, used to retreive its command " - "line, as well as the global up and idle times. " -- "(default: 2)" }, -+ "(default: 3)" }, - { "compatible", 'c', NULL, 0, - "Try to be compatible with the Linux procps utilities. " - "Currently equivalent to -h 100 -s 0444 -S 1." }, diff --git a/debian/patches/series b/debian/patches/series index 0204b51a..61635f44 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,12 +1,4 @@ -startup-0001-Add-proc_set_init_task-make-runsystem-pid-1.patch -startup-0002-procfs-do-not-hard-code-the-default-argument-values.patch -startup-0003-startup-rename-hurd-init-to-hurd-startup.patch -startup-0004-init-add-a-minimalist-init-program.patch -startup-0005-startup-do-not-pass-signals-on-to-the-child.patch -startup-0006-startup-be-more-specific-in-the-shutdown-message.patch -startup-0007-startup-fix-the-declaration-of-the-_server-functions.patch -startup-0008-startup-bind-the-startup-server-to-servers-startup.patch -libexec-splitinit.patch +libexec.patch diskfs_no_inherit_dir_group.patch makedev.diff @@ -16,14 +8,12 @@ tmp_exec_startup.patch uptime_w_path_fix.patch stat_round.patch -#external.patch -external-splitinit.patch +external.patch console_ignore_bdf_err.patch posix-sigcodes.patch random-default-fast.patch -#libexec.patch libdde_netdev_tx_t.patch libdde_pci-needs_freset.patch @@ -46,9 +36,6 @@ libdde_rx_queue.patch libdde_rcu.patch mount.patch -### disabled for splitinit -# proc_set_init_task.patch - xkb-compat.patch #trans-crash-add-verbose.patch diff --git a/debian/patches/startup-0001-Add-proc_set_init_task-make-runsystem-pid-1.patch b/debian/patches/startup-0001-Add-proc_set_init_task-make-runsystem-pid-1.patch deleted file mode 100644 index e9d6f9d4..00000000 --- a/debian/patches/startup-0001-Add-proc_set_init_task-make-runsystem-pid-1.patch +++ /dev/null @@ -1,392 +0,0 @@ -From 7814f2ef1f48d90b15c12c5521c9c1193fe80a7b Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Wed, 18 Sep 2013 15:59:31 +0200 -Subject: [PATCH 1/8] Add proc_set_init_task, make runsystem pid 1 - -* hurd/process.defs (proc_set_init_task): New procedure. -* hurd/process_reply.defs (proc_set_init_task): Likewise. -* hurd/process_request.defs (proc_set_init_task): Likewise. -* include/pids.h: Add HURD_PID_INIT as 1, adjust others accordingly. -* init/init.c (start_child): Register the child task. -* proc/proc.h (init_proc): New variable. -(create_startup_proc): Rename to create_init_proc. -* proc/main.c (main): Create placeholder proc object for pid 1. -* proc/mgt.c: Use init_proc instead of startup_proc, as the former is -the new root of the process tree. -(create_startup_proc): Rename to create_init_proc. -(S_proc_set_init_task): New function. -* doc/hurd.texi (Server Bootstrap): Update accordingly. -* procfs/main.c: Do not hard-code kernel pid, use pids.h instead. ---- - doc/hurd.texi | 2 +- - hurd/process.defs | 6 +++- - hurd/process_reply.defs | 2 +- - hurd/process_request.defs | 7 ++++- - include/pids.h | 7 +++-- - init/init.c | 2 +- - proc/main.c | 9 ++++-- - proc/mgt.c | 76 ++++++++++++++++++++++++++++++++++------------- - proc/proc.h | 8 +++-- - procfs/main.c | 9 ++++-- - 10 files changed, 93 insertions(+), 35 deletions(-) - -diff --git a/doc/hurd.texi b/doc/hurd.texi -index 8fa6da7..697cce7 100644 ---- a/doc/hurd.texi -+++ b/doc/hurd.texi -@@ -564,7 +564,7 @@ the root filesystem and the exec server. - - The @option{--multiboot-command-line} option tells the file system server that - it is a root filesystem, which triggers it to run @command{/hurd/init} as PID --1. @command{/hurd/init} starts the @command{/hurd/proc} and -+2. @command{/hurd/init} starts the @command{/hurd/proc} and - @command{/hurd/auth} servers. After the servers are launched - @command{/hurd/init} starts the @command{/libexec/runsystem.sh} script to - finish booting. -diff --git a/hurd/process.defs b/hurd/process.defs -index bf90556..498faba 100644 ---- a/hurd/process.defs -+++ b/hurd/process.defs -@@ -373,7 +373,11 @@ routine proc_getnports ( - - /*** Routines related to early server bootstrapping ***/ - --skip; /* Reserved for proc_set_init_task */ -+/* Set the task of process HURD_PID_INIT. Only the startup process -+ HURD_PID_STARTUP may use this interface. */ -+routine proc_set_init_task ( -+ process: process_t; -+ task: task_t); - - /* Inform the process server that the process is important. */ - routine proc_mark_important ( -diff --git a/hurd/process_reply.defs b/hurd/process_reply.defs -index ed46d55..80454a6 100644 ---- a/hurd/process_reply.defs -+++ b/hurd/process_reply.defs -@@ -177,7 +177,7 @@ simpleroutine proc_getnports_reply ( - - /*** Routines related to early server bootstrapping ***/ - --skip; /* Reserved for proc_set_init_task */ -+skip; /* proc_set_init_task */ - skip; /* proc_mark_important */ - - simpleroutine proc_is_important_reply ( -diff --git a/hurd/process_request.defs b/hurd/process_request.defs -index 38e7146..7565f03 100644 ---- a/hurd/process_request.defs -+++ b/hurd/process_request.defs -@@ -374,7 +374,12 @@ simpleroutine proc_getnports_request ( - - /*** Routines related to early server bootstrapping ***/ - --skip; /* Reserved for proc_set_init_task */ -+/* Set the task of process HURD_PID_INIT. Only the startup process -+ HURD_PID_STARTUP may use this interface. */ -+simpleroutine proc_set_init_task_request ( -+ process: process_t; -+ ureplyport reply: reply_port_t; -+ task: task_t); - - /* Inform the process server that the process is important. */ - simpleroutine proc_mark_important_request ( -diff --git a/include/pids.h b/include/pids.h -index 22415f4..dff7635 100644 ---- a/include/pids.h -+++ b/include/pids.h -@@ -22,8 +22,9 @@ - #ifndef _HURD_PROCESSES_H - #define _HURD_PROCESSES_H - --#define HURD_PID_STARTUP 1 --#define HURD_PID_KERNEL 2 --#define HURD_PID_PROC 3 -+#define HURD_PID_INIT 1 -+#define HURD_PID_STARTUP 2 -+#define HURD_PID_KERNEL 3 -+#define HURD_PID_PROC 4 - - #endif /* _HURD_PROCESSES_H */ -diff --git a/init/init.c b/init/init.c -index b7b40bd..6bc6701 100644 ---- a/init/init.c -+++ b/init/init.c -@@ -1058,7 +1058,7 @@ start_child (const char *prog, char **progargs) - NULL, 0, /* OSF Mach */ - #endif - 0, &child_task); -- proc_child (procserver, child_task); -+ proc_set_init_task (procserver, child_task); - proc_task2pid (procserver, child_task, &child_pid); - proc_task2proc (procserver, child_task, &default_ports[INIT_PORT_PROC]); - -diff --git a/proc/main.c b/proc/main.c -index 73742ed..f1f4e1b 100644 ---- a/proc/main.c -+++ b/proc/main.c -@@ -1,5 +1,5 @@ - /* Initialization of the proc server -- Copyright (C) 1993,94,95,96,97,99,2000,01 Free Software Foundation, Inc. -+ Copyright (C) 1993,94,95,96,97,99,2000,01,13 Free Software Foundation, Inc. - - This file is part of the GNU Hurd. - -@@ -88,7 +88,12 @@ main (int argc, char **argv, char **envp) - generic_port = ports_get_right (genport); - - /* Create the initial proc object for init (PID 1). */ -- startup_proc = create_startup_proc (); -+ init_proc = create_init_proc (); -+ -+ /* Create the startup proc object for /hurd/init (PID 2). */ -+ startup_proc = allocate_proc (MACH_PORT_NULL); -+ startup_proc->p_deadmsg = 1; -+ complete_proc (startup_proc, HURD_PID_STARTUP); - - /* Create our own proc object. */ - self_proc = allocate_proc (mach_task_self ()); -diff --git a/proc/mgt.c b/proc/mgt.c -index b8aa0fc..02d69db 100644 ---- a/proc/mgt.c -+++ b/proc/mgt.c -@@ -1,5 +1,6 @@ - /* Process management -- Copyright (C) 1992,93,94,95,96,99,2000,01,02 Free Software Foundation, Inc. -+ Copyright (C) 1992,93,94,95,96,99,2000,01,02,13 -+ Free Software Foundation, Inc. - - This file is part of the GNU Hurd. - -@@ -184,7 +185,7 @@ S_proc_child (struct proc *parentp, - /* Process hierarchy. Remove from our current location - and place us under our new parent. Sanity check to make sure - parent is currently init. */ -- assert (childp->p_parent == startup_proc); -+ assert (childp->p_parent == init_proc); - if (childp->p_sib) - childp->p_sib->p_prevsib = childp->p_prevsib; - *childp->p_prevsib = childp->p_sib; -@@ -586,7 +587,7 @@ allocate_proc (task_t task) - /* Allocate and initialize the proc structure for init (PID 1), - the original parent of all other procs. */ - struct proc * --create_startup_proc (void) -+create_init_proc (void) - { - static const uid_t zero; - struct proc *p; -@@ -595,7 +596,7 @@ create_startup_proc (void) - p = allocate_proc (MACH_PORT_NULL); - assert (p); - -- p->p_pid = HURD_PID_STARTUP; -+ p->p_pid = HURD_PID_INIT; - - p->p_parent = p; - p->p_sib = 0; -@@ -643,7 +644,7 @@ proc_death_notify (struct proc *p) - } - - /* Complete a new process that has been allocated but not entirely initialized. -- This gets called for every process except startup_proc (PID 1). */ -+ This gets called for every process except init_proc (PID 1). */ - void - complete_proc (struct proc *p, pid_t pid) - { -@@ -662,30 +663,47 @@ complete_proc (struct proc *p, pid_t pid) - - p->p_pid = pid; - -- ids_ref (&nullids); -- p->p_id = &nullids; -+ if (pid == HURD_PID_STARTUP) -+ { -+ /* Equip HURD_PID_STARTUP with the same credentials as -+ HURD_PID_INIT. */ -+ static const uid_t zero; -+ p->p_id = make_ids (&zero, 1); -+ assert (p->p_id); -+ } -+ else -+ { -+ ids_ref (&nullids); -+ p->p_id = &nullids; -+ } - - p->p_login = nulllogin; - p->p_login->l_refcnt++; - - /* Our parent is init for now. */ -- p->p_parent = startup_proc; -+ p->p_parent = init_proc; - -- p->p_sib = startup_proc->p_ochild; -- p->p_prevsib = &startup_proc->p_ochild; -+ p->p_sib = init_proc->p_ochild; -+ p->p_prevsib = &init_proc->p_ochild; - if (p->p_sib) - p->p_sib->p_prevsib = &p->p_sib; -- startup_proc->p_ochild = p; -+ init_proc->p_ochild = p; - p->p_loginleader = 0; - p->p_ochild = 0; - p->p_parentset = 0; - - p->p_noowner = 1; - -- p->p_pgrp = startup_proc->p_pgrp; -+ p->p_pgrp = init_proc->p_pgrp; - -- proc_death_notify (p); -- add_proc_to_hash (p); -+ /* At this point, we do not know the task of the startup process, -+ defer registering death notifications and adding it to the hash -+ tables. */ -+ if (pid != HURD_PID_STARTUP) -+ { -+ proc_death_notify (p); -+ add_proc_to_hash (p); -+ } - join_pgrp (p); - } - -@@ -747,7 +765,7 @@ process_has_exited (struct proc *p) - nowait_msg_proc_newids (tp->p_msgport, tp->p_task, - 1, tp->p_pgrp->pg_pgid, - !tp->p_pgrp->pg_orphcnt); -- tp->p_parent = startup_proc; -+ tp->p_parent = init_proc; - if (tp->p_dead) - isdead = 1; - } -@@ -755,17 +773,17 @@ process_has_exited (struct proc *p) - nowait_msg_proc_newids (tp->p_msgport, tp->p_task, - 1, tp->p_pgrp->pg_pgid, - !tp->p_pgrp->pg_orphcnt); -- tp->p_parent = startup_proc; -+ tp->p_parent = init_proc; - - /* And now append the lists. */ -- tp->p_sib = startup_proc->p_ochild; -+ tp->p_sib = init_proc->p_ochild; - if (tp->p_sib) - tp->p_sib->p_prevsib = &tp->p_sib; -- startup_proc->p_ochild = p->p_ochild; -- p->p_ochild->p_prevsib = &startup_proc->p_ochild; -+ init_proc->p_ochild = p->p_ochild; -+ p->p_ochild->p_prevsib = &init_proc->p_ochild; - - if (isdead) -- alert_parent (startup_proc); -+ alert_parent (init_proc); - } - - /* If an operation is in progress for this process, cause it -@@ -883,6 +901,24 @@ genpid () - return nextpid++; - } - -+/* Implement proc_set_init_task as described in <hurd/process.defs>. */ -+error_t -+S_proc_set_init_task(struct proc *callerp, -+ task_t task) -+{ -+ if (! callerp) -+ return EOPNOTSUPP; -+ -+ if (callerp != startup_proc) -+ return EPERM; -+ -+ init_proc->p_task = task; -+ proc_death_notify (init_proc); -+ add_proc_to_hash (init_proc); -+ -+ return 0; -+} -+ - /* Implement proc_mark_important as described in <hurd/process.defs>. */ - kern_return_t - S_proc_mark_important (struct proc *p) -diff --git a/proc/proc.h b/proc/proc.h -index a2e3c53..6196697 100644 ---- a/proc/proc.h -+++ b/proc/proc.h -@@ -1,5 +1,6 @@ - /* Process server definitions -- Copyright (C) 1992,93,94,95,96,99,2000,01 Free Software Foundation, Inc. -+ Copyright (C) 1992,93,94,95,96,99,2000,01,13 -+ Free Software Foundation, Inc. - - This file is part of the GNU Hurd. - -@@ -134,7 +135,8 @@ struct exc - - mach_port_t authserver; - struct proc *self_proc; /* process HURD_PID_PROC (us) */ --struct proc *startup_proc; /* process 1 (init) */ -+struct proc *init_proc; /* process 1 (sysvinit) */ -+struct proc *startup_proc; /* process 2 (hurd/init) */ - - struct port_bucket *proc_bucket; - struct port_class *proc_class; -@@ -183,7 +185,7 @@ void exc_clean (void *); - struct proc *add_tasks (task_t); - int pidfree (pid_t); - --struct proc *create_startup_proc (void); -+struct proc *create_init_proc (void); - struct proc *allocate_proc (task_t); - void proc_death_notify (struct proc *); - void complete_proc (struct proc *, pid_t); -diff --git a/procfs/main.c b/procfs/main.c -index 54e9682..f3067d9 100644 ---- a/procfs/main.c -+++ b/procfs/main.c -@@ -25,6 +25,7 @@ - #include <argz.h> - #include <hurd/netfs.h> - #include <ps.h> -+#include <pids.h> - #include "procfs.h" - #include "proclist.h" - #include "rootdir.h" -@@ -42,7 +43,7 @@ uid_t opt_anon_owner; - #define OPT_CLK_TCK sysconf(_SC_CLK_TCK) - #define OPT_STAT_MODE 0400 - #define OPT_FAKE_SELF -1 --#define OPT_KERNEL_PID 2 -+#define OPT_KERNEL_PID HURD_PID_KERNEL - #define OPT_ANON_OWNER 0 - - #define NODEV_KEY -1 /* <= 0, so no short option. */ -@@ -137,6 +138,8 @@ argp_parser (int key, char *arg, struct argp_state *state) - } - - struct argp_option common_options[] = { -+#define STR(X) XSTR (X) -+#define XSTR(X) #X - { "clk-tck", 'h', "HZ", 0, - "Unit used for the values expressed in system clock ticks " - "(default: sysconf(_SC_CLK_TCK))" }, -@@ -153,7 +156,7 @@ struct argp_option common_options[] = { - { "kernel-process", 'k', "PID", 0, - "Process identifier for the kernel, used to retreive its command " - "line, as well as the global up and idle times. " -- "(default: 2)" }, -+ "(default: " STR (OPT_KERNEL_PID) ")" }, - { "compatible", 'c', NULL, 0, - "Try to be compatible with the Linux procps utilities. " - "Currently equivalent to -h 100 -s 0444 -S 1." }, -@@ -169,6 +172,8 @@ struct argp_option common_options[] = { - { "nosuid", NOSUID_KEY, NULL, 0, - "Ignored for compatibility with Linux' procfs." }, - {} -+#undef XSTR -+#undef STR - }; - - struct argp argp = { --- -2.1.0 - diff --git a/debian/patches/startup-0002-procfs-do-not-hard-code-the-default-argument-values.patch b/debian/patches/startup-0002-procfs-do-not-hard-code-the-default-argument-values.patch deleted file mode 100644 index 70b41c14..00000000 --- a/debian/patches/startup-0002-procfs-do-not-hard-code-the-default-argument-values.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 7a0bc7740d665cf8ea3442960fde67d28dda4ecf Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Fri, 5 Sep 2014 10:34:24 +0200 -Subject: [PATCH 2/8] procfs: do not hard-code the default argument values - -* procfs/main.c (common_options): If possible, do not hard-code the -default values. ---- - procfs/main.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/procfs/main.c b/procfs/main.c -index f3067d9..36a2d25 100644 ---- a/procfs/main.c -+++ b/procfs/main.c -@@ -142,13 +142,13 @@ struct argp_option common_options[] = { - #define XSTR(X) #X - { "clk-tck", 'h', "HZ", 0, - "Unit used for the values expressed in system clock ticks " -- "(default: sysconf(_SC_CLK_TCK))" }, -+ "(default: " STR (OPT_CLK_TCK) ")" }, - { "stat-mode", 's', "MODE", 0, - "The [pid]/stat file publishes information which on Hurd is only " - "available to the process owner. " - "You can use this option to override its mode to be more permissive " - "for compatibility purposes. " -- "(default: 0400)" }, -+ "(default: " STR (OPT_STAT_MODE) ")" }, - { "fake-self", 'S', "PID", OPTION_ARG_OPTIONAL, - "Provide a fake \"self\" symlink to the given PID, for compatibility " - "purposes. If PID is omitted, \"self\" will point to init. " -@@ -164,7 +164,7 @@ struct argp_option common_options[] = { - "Make USER the owner of files related to processes without one. " - "Be aware that USER will be granted access to the environment and " - "other sensitive information about the processes in question. " -- "(default: use uid 0)" }, -+ "(default: use uid " STR (OPT_ANON_OWNER) ")" }, - { "nodev", NODEV_KEY, NULL, 0, - "Ignored for compatibility with Linux' procfs." }, - { "noexec", NOEXEC_KEY, NULL, 0, --- -2.1.0 - diff --git a/debian/patches/startup-0003-startup-rename-hurd-init-to-hurd-startup.patch b/debian/patches/startup-0003-startup-rename-hurd-init-to-hurd-startup.patch deleted file mode 100644 index 7a874ab6..00000000 --- a/debian/patches/startup-0003-startup-rename-hurd-init-to-hurd-startup.patch +++ /dev/null @@ -1,3678 +0,0 @@ -From 3ead9b6a0328e8aa85d652bcabdb76ce86360907 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Tue, 17 Sep 2013 13:44:44 +0200 -Subject: [PATCH 3/8] startup: rename /hurd/init to /hurd/startup - -This patch series splits /hurd/init into two programs. As a first -step, this patch renames /hurd/init to /hurd/startup. It is called -startup because it speaks the startup protocol. - -* startup: Rename init to startup. Adjust accordingly. -* Makefile (prog-subdirs): Likewise. -* doc/hurd.texi (Server Bootstrap): Likewise. -* hurd/paths.h (_HURD_STARTUP): Likewise. -* libdiskfs/boot-start.c (diskfs_boot_init_program): Likewise. -* libdiskfs/opts-std-startup.c (startup_options): Likewise. ---- - Makefile | 3 +- - doc/hurd.texi | 6 +- - hurd/paths.h | 2 +- - init/Makefile | 31 - - init/init.c | 1593 ------------------------------------------ - init/stubs.c | 139 ---- - libdiskfs/boot-start.c | 2 +- - libdiskfs/opts-std-startup.c | 2 +- - startup/Makefile | 31 + - startup/startup.c | 1593 ++++++++++++++++++++++++++++++++++++++++++ - startup/stubs.c | 139 ++++ - 11 files changed, 1771 insertions(+), 1770 deletions(-) - delete mode 100644 init/Makefile - delete mode 100644 init/init.c - delete mode 100644 init/stubs.c - create mode 100644 startup/Makefile - create mode 100644 startup/startup.c - create mode 100644 startup/stubs.c - -diff --git a/Makefile b/Makefile -index 0b9eff2..455df67 100644 ---- a/Makefile -+++ b/Makefile -@@ -31,7 +31,7 @@ lib-subdirs = libshouldbeinlibc libihash libiohelp libports libthreads \ - libnetfs libpipe libstore libhurdbugaddr libftpconn libcons - - # Hurd programs --prog-subdirs = auth proc exec init term \ -+prog-subdirs = auth proc exec term \ - ext2fs isofs tmpfs fatfs \ - storeio pflocal pfinet defpager mach-defpager \ - login daemons boot console \ -@@ -40,6 +40,7 @@ prog-subdirs = auth proc exec init term \ - benchmarks fstests \ - random \ - procfs \ -+ startup \ - - ifeq ($(HAVE_SUN_RPC),yes) - prog-subdirs += nfs nfsd -diff --git a/doc/hurd.texi b/doc/hurd.texi -index 697cce7..7e7b5ee 100644 ---- a/doc/hurd.texi -+++ b/doc/hurd.texi -@@ -563,10 +563,10 @@ bootstrapped by starting the GNU Mach microkernel and two programs: - the root filesystem and the exec server. - - The @option{--multiboot-command-line} option tells the file system server that --it is a root filesystem, which triggers it to run @command{/hurd/init} as PID --2. @command{/hurd/init} starts the @command{/hurd/proc} and -+it is a root filesystem, which triggers it to run @command{/hurd/startup} as PID -+2. @command{/hurd/startup} starts the @command{/hurd/proc} and - @command{/hurd/auth} servers. After the servers are launched --@command{/hurd/init} starts the @command{/libexec/runsystem.sh} script to -+@command{/hurd/startup} starts the @command{/libexec/runsystem.sh} script to - finish booting. - - After the Hurd has been booted, other sets of core Hurd servers can be -diff --git a/hurd/paths.h b/hurd/paths.h -index 4877132..489da57 100644 ---- a/hurd/paths.h -+++ b/hurd/paths.h -@@ -39,7 +39,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - the canonical pathname being /hurd/foo. */ - - #define _HURD "/hurd/" --#define _HURD_INIT _HURD "init" -+#define _HURD_STARTUP _HURD "startup" - #define _HURD_PROC _HURD "proc" - #define _HURD_AUTH _HURD "auth" - -diff --git a/init/Makefile b/init/Makefile -deleted file mode 100644 -index ffb82ff..0000000 ---- a/init/Makefile -+++ /dev/null -@@ -1,31 +0,0 @@ --# --# Copyright (C) 1994,95,96,99,2001 Free Software Foundation, Inc. --# --# This program 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. --# --# This program 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 this program; if not, write to the Free Software --# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- --dir := init --makemode := server -- --SRCS = init.c stubs.c --OBJS = $(SRCS:.c=.o) \ -- startupServer.o notifyServer.o startup_replyUser.o msgServer.o \ -- startup_notifyUser.o --target = init --HURDLIBS = shouldbeinlibc -- --include ../Makeconf -- --mung_msg_S.h: msg_S.h -- sed 's/msg_server/mung_msg_server/' < $< > $@ -diff --git a/init/init.c b/init/init.c -deleted file mode 100644 -index 6bc6701..0000000 ---- a/init/init.c -+++ /dev/null -@@ -1,1593 +0,0 @@ --/* Start and maintain hurd core servers and system run state -- -- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -- 2005, 2008, 2013 Free Software Foundation, Inc. -- 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; see the file COPYING. If not, write to -- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -- --/* Written by Michael I. Bushnell and Roland McGrath. */ -- --/* This is probably more include files than I've ever seen before for -- one file. */ --#include <hurd.h> --#include <hurd/fs.h> --#include <hurd/fsys.h> --#include <device/device.h> --#include <stdio.h> --#include <assert.h> --#include <hurd/paths.h> --#include <sys/reboot.h> --#include <sys/file.h> --#include <unistd.h> --#include <string.h> --#include <mach/notify.h> --#include <stdlib.h> --#include <hurd/msg.h> --#include <hurd/term.h> --#include <hurd/fshelp.h> --#include <paths.h> --#include <sys/mman.h> --#include <hurd/msg_server.h> --#include <wire.h> --#include <sys/wait.h> --#include <error.h> --#include <hurd/msg_reply.h> --#include <argz.h> --#include <maptime.h> --#include <version.h> --#include <argp.h> --#include <pids.h> -- --#include "startup_notify_U.h" --#include "startup_reply_U.h" --#include "startup_S.h" --#include "notify_S.h" --#include "mung_msg_S.h" -- --/* host_reboot flags for when we crash. */ --static int crash_flags = RB_AUTOBOOT; -- --#define BOOT(flags) ((flags & RB_HALT) ? "halt" : "reboot") -- -- --const char *argp_program_version = STANDARD_HURD_VERSION (init); -- --static struct argp_option --options[] = --{ -- {"single-user", 's', 0, 0, "Startup system in single-user mode"}, -- {"query", 'q', 0, 0, "Ask for the names of servers to start"}, -- {"init-name", 'n', 0, 0 }, -- {"crash-debug", 'H', 0, 0, "On system crash, go to kernel debugger"}, -- {"debug", 'd', 0, 0 }, -- {"fake-boot", 'f', 0, 0, "This hurd hasn't been booted on the raw machine"}, -- {0, 'x', 0, OPTION_HIDDEN}, -- {0} --}; -- --static char doc[] = "Start and maintain hurd core servers and system run state"; -- --static int booted; /* Set when the core servers are up. */ -- --/* This structure keeps track of each notified task. */ --struct ntfy_task -- { -- mach_port_t notify_port; -- struct ntfy_task *next; -- char *name; -- }; -- --/* This structure keeps track of each registered essential task. */ --struct ess_task -- { -- struct ess_task *next; -- task_t task_port; -- char *name; -- }; -- --/* These are linked lists of all of the registered items. */ --static struct ess_task *ess_tasks; --static struct ntfy_task *ntfy_tasks; -- -- --/* Our receive right */ --static mach_port_t startup; -- --/* Ports to the kernel */ --static mach_port_t host_priv, device_master; -- --/* Args to bootstrap, expressed as flags */ --static int bootstrap_args = 0; -- --/* Stored information for returning proc and auth startup messages. */ --static mach_port_t procreply, authreply; --static mach_msg_type_name_t procreplytype, authreplytype; -- --/* Our ports to auth and proc. */ --static mach_port_t authserver; --static mach_port_t procserver; -- --/* Our bootstrap port, on which we call fsys_getpriv and fsys_init. */ --static mach_port_t bootport; -- --/* Set iff we are a `fake' bootstrap. */ --static int fakeboot; -- --/* The tasks of auth and proc and the bootstrap filesystem. */ --static task_t authtask, proctask, fstask; -- --static mach_port_t default_ports[INIT_PORT_MAX]; --static mach_port_t default_dtable[3]; --static int default_ints[INIT_INT_MAX]; -- --static char **global_argv; --static char *startup_envz; --static size_t startup_envz_len; -- --void launch_system (void); --void process_signal (int signo); -- --/** Utility functions **/ -- --/* Read a string from stdin into BUF. */ --static int --getstring (char *buf, size_t bufsize) --{ -- if (fgets (buf, bufsize, stdin) != NULL && buf[0] != '\0') -- { -- size_t len = strlen (buf); -- if (buf[len - 1] == '\n' || buf[len - 1] == '\r') -- buf[len - 1] = '\0'; -- return 1; -- } -- return 0; --} -- -- --/** System shutdown **/ -- --/* Reboot the microkernel. */ --void --reboot_mach (int flags) --{ -- if (fakeboot) -- { -- printf ("%s: Would %s Mach with flags %#x\n", -- program_invocation_short_name, BOOT (flags), flags); -- fflush (stdout); -- exit (1); -- } -- else -- { -- error_t err; -- printf ("%s: %sing Mach (flags %#x)...\n", -- program_invocation_short_name, BOOT (flags), flags); -- fflush (stdout); -- sleep (5); -- while ((err = host_reboot (host_priv, flags))) -- error (0, err, "reboot"); -- for (;;); -- } --} -- --/* Reboot the microkernel, specifying that this is a crash. */ --void --crash_mach (void) --{ -- reboot_mach (crash_flags); --} -- --/* Notify all tasks that have requested shutdown notifications */ --void --notify_shutdown (const char *msg) --{ -- struct ntfy_task *n; -- -- for (n = ntfy_tasks; n != NULL; n = n->next) -- { -- error_t err; -- printf ("%s: notifying %s of %s...", -- program_invocation_short_name, n->name, msg); -- fflush (stdout); -- err = startup_dosync (n->notify_port, 60000); /* 1 minute to reply */ -- if (err == MACH_SEND_INVALID_DEST) -- puts ("(no longer present)"); -- else if (err) -- puts (strerror (err)); -- else -- puts ("done"); -- fflush (stdout); -- } --} -- --/* Reboot the Hurd. */ --void --reboot_system (int flags) --{ -- notify_shutdown ("shutdown"); -- -- if (fakeboot) -- { -- pid_t *pp; -- size_t npids = 0; -- error_t err; -- int ind; -- -- err = proc_getallpids (procserver, &pp, &npids); -- if (err == MACH_SEND_INVALID_DEST) -- { -- procbad: -- /* The procserver must have died. Give up. */ -- error (0, 0, "Can't simulate crash; proc has died"); -- reboot_mach (flags); -- } -- for (ind = 0; ind < npids; ind++) -- { -- task_t task; -- -- err = proc_pid2task (procserver, pp[ind], &task); -- if (err == MACH_SEND_INVALID_DEST) -- goto procbad; -- else if (err) -- { -- error (0, err, "Getting task for pid %d", pp[ind]); -- continue; -- } -- -- /* Postpone self so we can finish; postpone proc -- so that we can finish. */ -- if (task != mach_task_self () && task != proctask) -- { -- struct procinfo *pi = 0; -- size_t pisize = 0; -- char *noise; -- size_t noise_len = 0; -- int flags; -- err = proc_getprocinfo (procserver, pp[ind], &flags, -- (int **)&pi, &pisize, -- &noise, &noise_len); -- if (err == MACH_SEND_INVALID_DEST) -- goto procbad; -- if (err) -- { -- error (0, err, "Getting procinfo for pid %d", pp[ind]); -- continue; -- } -- if (!(pi->state & PI_NOPARENT)) -- { -- printf ("%s: Killing pid %d\n", -- program_invocation_short_name, pp[ind]); -- fflush (stdout); -- task_terminate (task); -- } -- if (noise_len > 0) -- munmap (noise, noise_len); -- } -- } -- printf ("%s: Killing proc server\n", program_invocation_short_name); -- fflush (stdout); -- task_terminate (proctask); -- printf ("%s: Exiting", program_invocation_short_name); -- fflush (stdout); -- } -- reboot_mach (flags); --} -- --/* Reboot the Hurd, specifying that this is a crash. */ --void --crash_system (void) --{ -- reboot_system (crash_flags); --} -- -- -- --/* Request a dead-name notification sent to our port. */ --static void --request_dead_name (mach_port_t name) --{ -- mach_port_t prev; -- mach_port_request_notification (mach_task_self (), name, -- MACH_NOTIFY_DEAD_NAME, 1, startup, -- MACH_MSG_TYPE_MAKE_SEND_ONCE, &prev); -- if (prev != MACH_PORT_NULL) -- mach_port_deallocate (mach_task_self (), prev); --} -- --/* Record an essential task in the list. */ --static error_t --record_essential_task (const char *name, task_t task) --{ -- struct ess_task *et; -- /* Record this task as essential. */ -- et = malloc (sizeof (struct ess_task)); -- if (et == NULL) -- return ENOMEM; -- et->task_port = task; -- et->name = strdup (name); -- if (et->name == NULL) -- { -- free (et); -- return ENOMEM; -- } -- et->next = ess_tasks; -- ess_tasks = et; -- -- /* Dead-name notification on the task port will tell us when it dies. */ -- request_dead_name (task); -- --#if 0 -- /* Taking over the exception port will give us a better chance -- if the task tries to get wedged on a fault. */ -- task_set_special_port (task, TASK_EXCEPTION_PORT, startup); --#endif -- -- return 0; --} -- -- --/** Starting programs **/ -- --/* Run SERVER, giving it INIT_PORT_MAX initial ports from PORTS. -- Set TASK to be the task port of the new image. */ --void --run (const char *server, mach_port_t *ports, task_t *task) --{ -- char buf[BUFSIZ]; -- const char *prog = server; -- -- if (bootstrap_args & RB_INITNAME) -- { -- printf ("Server file name (default %s): ", server); -- if (getstring (buf, sizeof (buf))) -- prog = buf; -- } -- -- while (1) -- { -- file_t file; -- error_t err; -- -- file = file_name_lookup (prog, O_EXEC, 0); -- if (file == MACH_PORT_NULL) -- error (0, errno, "%s", prog); -- else -- { -- task_create (mach_task_self (), --#ifdef KERN_INVALID_LEDGER -- NULL, 0, /* OSF Mach */ --#endif -- 0, task); -- if (bootstrap_args & RB_KDB) -- { -- printf ("Pausing for %s\n", prog); -- getchar (); -- } -- err = file_exec (file, *task, 0, -- (char *)prog, strlen (prog) + 1, /* Args. */ -- startup_envz, startup_envz_len, -- default_dtable, MACH_MSG_TYPE_COPY_SEND, 3, -- ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, -- default_ints, INIT_INT_MAX, -- NULL, 0, NULL, 0); -- if (!err) -- break; -- -- error (0, err, "%s", prog); -- } -- -- printf ("File name for server %s (or nothing to reboot): ", server); -- if (getstring (buf, sizeof (buf))) -- prog = buf; -- else -- crash_system (); -- } -- --#if 0 -- printf ("started %s\n", prog); -- fflush (stdout); --#endif -- -- /* Dead-name notification on the task port will tell us when it dies, -- so we can crash if we don't make it to a fully bootstrapped Hurd. */ -- request_dead_name (*task); --} -- --/* Run FILENAME as root with ARGS as its argv (length ARGLEN). Return -- the task that we started. If CTTY is set, then make that the -- controlling terminal of the new process and put it in its own login -- collection. If SETSID is set, put it in a new session. Return -- 0 if the task was not created successfully. */ --pid_t --run_for_real (char *filename, char *args, int arglen, mach_port_t ctty, -- int setsid) --{ -- file_t file; -- error_t err; -- task_t task; -- char *progname; -- int pid; -- --#if 0 -- char buf[512]; -- do -- { -- printf ("File name [%s]: ", filename); -- if (getstring (buf, sizeof (buf)) && *buf) -- filename = buf; -- file = file_name_lookup (filename, O_EXEC, 0); -- if (file == MACH_PORT_NULL) -- error (0, errno, "%s", filename); -- } -- while (file == MACH_PORT_NULL); --#else -- file = file_name_lookup (filename, O_EXEC, 0); -- if (file == MACH_PORT_NULL) -- { -- error (0, errno, "%s", filename); -- return 0; -- } --#endif -- -- task_create (mach_task_self (), --#ifdef KERN_INVALID_LEDGER -- NULL, 0, /* OSF Mach */ --#endif -- 0, &task); -- proc_child (procserver, task); -- proc_task2pid (procserver, task, &pid); -- proc_task2proc (procserver, task, &default_ports[INIT_PORT_PROC]); -- proc_mark_exec (default_ports[INIT_PORT_PROC]); -- if (setsid) -- proc_setsid (default_ports[INIT_PORT_PROC]); -- if (ctty != MACH_PORT_NULL) -- { -- term_getctty (ctty, &default_ports[INIT_PORT_CTTYID]); -- io_mod_owner (ctty, -pid); -- proc_make_login_coll (default_ports[INIT_PORT_PROC]); -- } -- if (bootstrap_args & RB_KDB) -- { -- printf ("Pausing for %s\n", filename); -- getchar (); -- } -- progname = strrchr (filename, '/'); -- if (progname) -- ++progname; -- else -- progname = filename; -- err = file_exec (file, task, 0, -- args, arglen, -- startup_envz, startup_envz_len, -- default_dtable, MACH_MSG_TYPE_COPY_SEND, 3, -- default_ports, MACH_MSG_TYPE_COPY_SEND, -- INIT_PORT_MAX, -- default_ints, INIT_INT_MAX, -- NULL, 0, NULL, 0); -- mach_port_deallocate (mach_task_self (), default_ports[INIT_PORT_PROC]); -- mach_port_deallocate (mach_task_self (), task); -- if (ctty != MACH_PORT_NULL) -- { -- mach_port_deallocate (mach_task_self (), -- default_ports[INIT_PORT_CTTYID]); -- default_ports[INIT_PORT_CTTYID] = MACH_PORT_NULL; -- } -- mach_port_deallocate (mach_task_self (), file); -- if (err) -- { -- error (0, err, "Cannot execute %s", filename); -- return 0; -- } -- return pid; --} -- -- --/** Main program and setup **/ -- --static int --demuxer (mach_msg_header_t *inp, -- mach_msg_header_t *outp) --{ -- extern int notify_server (), startup_server (), msg_server (); -- -- return (notify_server (inp, outp) || -- msg_server (inp, outp) || -- startup_server (inp, outp)); --} -- --static int --parse_opt (int key, char *arg, struct argp_state *state) --{ -- switch (key) -- { -- case 'q': bootstrap_args |= RB_ASKNAME; break; -- case 's': bootstrap_args |= RB_SINGLE; break; -- case 'd': bootstrap_args |= RB_KDB; break; -- case 'n': bootstrap_args |= RB_INITNAME; break; -- case 'f': fakeboot = 1; break; -- case 'H': crash_flags = RB_DEBUGGER; break; -- case 'x': /* NOP */ break; -- default: return ARGP_ERR_UNKNOWN; -- } -- return 0; --} -- --int --main (int argc, char **argv, char **envp) --{ -- volatile int err; -- int i; -- int flags; -- mach_port_t consdev; -- struct argp argp = { options, parse_opt, 0, doc }; -- -- /* Parse the arguments. We don't want the vector reordered, we -- should pass on to our child the exact arguments we got and just -- ignore any arguments that aren't flags for us. ARGP_NO_ERRS -- suppresses --help and --version, so we only use that option if we -- are booting. */ -- flags = ARGP_IN_ORDER; -- if (getpid () == 0) -- flags |= ARGP_NO_ERRS; -- argp_parse (&argp, argc, argv, flags, 0, 0); -- -- if (getpid () > 0) -- error (2, 0, "can only be run by bootstrap filesystem"); -- -- global_argv = argv; -- -- /* Fetch a port to the bootstrap filesystem, the host priv and -- master device ports, and the console. */ -- if (task_get_bootstrap_port (mach_task_self (), &bootport) -- || fsys_getpriv (bootport, &host_priv, &device_master, &fstask) -- || device_open (device_master, D_WRITE, "console", &consdev)) -- crash_mach (); -- -- wire_task_self (); -- -- /* Clear our bootstrap port so our children don't inherit it. */ -- task_set_bootstrap_port (mach_task_self (), MACH_PORT_NULL); -- -- stderr = stdout = mach_open_devstream (consdev, "w"); -- stdin = mach_open_devstream (consdev, "r"); -- if (stdout == NULL || stdin == NULL) -- crash_mach (); -- setbuf (stdout, NULL); -- -- err = argz_create (envp, &startup_envz, &startup_envz_len); -- assert_perror (err); -- -- /* At this point we can use assert to check for errors. */ -- err = mach_port_allocate (mach_task_self (), -- MACH_PORT_RIGHT_RECEIVE, &startup); -- assert_perror (err); -- err = mach_port_insert_right (mach_task_self (), startup, startup, -- MACH_MSG_TYPE_MAKE_SEND); -- assert_perror (err); -- -- /* Crash if the boot filesystem task dies. */ -- request_dead_name (fstask); -- -- /* Set up the set of ports we will pass to the programs we exec. */ -- for (i = 0; i < INIT_PORT_MAX; i++) -- switch (i) -- { -- case INIT_PORT_CRDIR: -- default_ports[i] = getcrdir (); -- break; -- case INIT_PORT_CWDIR: -- default_ports[i] = getcwdir (); -- break; -- default: -- default_ports[i] = MACH_PORT_NULL; -- break; -- } -- -- default_dtable[0] = getdport (0); -- default_dtable[1] = getdport (1); -- default_dtable[2] = getdport (2); -- -- /* All programs we start should ignore job control stop signals. -- That way Posix.1 B.2.2.2 is satisfied where it says that programs -- not run under job control shells are protected. */ -- default_ints[INIT_SIGIGN] = (sigmask (SIGTSTP) -- | sigmask (SIGTTIN) -- | sigmask (SIGTTOU)); -- -- default_ports[INIT_PORT_BOOTSTRAP] = startup; -- run ("/hurd/proc", default_ports, &proctask); -- printf (" proc"); -- fflush (stdout); -- run ("/hurd/auth", default_ports, &authtask); -- printf (" auth"); -- fflush (stdout); -- default_ports[INIT_PORT_BOOTSTRAP] = MACH_PORT_NULL; -- -- /* Wait for messages. When both auth and proc have started, we -- run launch_system which does the rest of the boot. */ -- while (1) -- { -- err = mach_msg_server (demuxer, 0, startup); -- assert_perror (err); -- } --} -- --void --launch_core_servers (void) --{ -- mach_port_t old; -- mach_port_t authproc, fsproc, procproc; -- error_t err; -- -- /* Reply to the proc and auth servers. */ -- startup_procinit_reply (procreply, procreplytype, 0, -- mach_task_self (), authserver, -- host_priv, MACH_MSG_TYPE_COPY_SEND, -- device_master, MACH_MSG_TYPE_COPY_SEND); -- if (!fakeboot) -- { -- mach_port_deallocate (mach_task_self (), device_master); -- device_master = 0; -- } -- -- /* Mark us as important. */ -- proc_mark_important (procserver); -- proc_mark_exec (procserver); -- -- /* Declare that the filesystem and auth are our children. */ -- proc_child (procserver, fstask); -- proc_child (procserver, authtask); -- -- proc_task2proc (procserver, authtask, &authproc); -- proc_mark_important (authproc); -- proc_mark_exec (authproc); -- startup_authinit_reply (authreply, authreplytype, 0, authproc, -- MACH_MSG_TYPE_COPY_SEND); -- mach_port_deallocate (mach_task_self (), authproc); -- -- /* Give the library our auth and proc server ports. */ -- _hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], authserver); -- _hurd_port_set (&_hurd_ports[INIT_PORT_PROC], procserver); -- -- /* Do NOT run _hurd_proc_init! That will start signals, which we do not -- want. We listen to our own message port. Tell the proc server where -- our args and environment are. */ -- proc_set_arg_locations (procserver, -- (vm_address_t) global_argv, (vm_address_t) environ); -- -- default_ports[INIT_PORT_AUTH] = authserver; -- -- /* Declare that the proc server is our child. */ -- proc_child (procserver, proctask); -- err = proc_task2proc (procserver, proctask, &procproc); -- if (!err) -- { -- proc_mark_important (procproc); -- proc_mark_exec (procproc); -- mach_port_deallocate (mach_task_self (), procproc); -- } -- -- proc_register_version (procserver, host_priv, "init", "", HURD_VERSION); -- -- /* Get the bootstrap filesystem's proc server port. -- We must do this before calling proc_setmsgport below. */ -- proc_task2proc (procserver, fstask, &fsproc); -- proc_mark_important (fsproc); -- proc_mark_exec (fsproc); -- --#if 0 -- printf ("Init has completed.\n"); -- fflush (stdout); --#endif -- printf (".\n"); -- fflush (stdout); -- -- /* Tell the proc server our msgport. Be sure to do this after we are all -- done making requests of proc. Once we have done this RPC, proc -- assumes it can send us requests, so we cannot block on proc again -- before accepting more RPC requests! However, we must do this before -- calling fsys_init, because fsys_init blocks on exec_init, and -- exec_init will block waiting on our message port. */ -- proc_setmsgport (procserver, startup, &old); -- if (old != MACH_PORT_NULL) -- mach_port_deallocate (mach_task_self (), old); -- -- /* Give the bootstrap FS its proc and auth ports. */ -- err = fsys_init (bootport, fsproc, MACH_MSG_TYPE_COPY_SEND, authserver); -- mach_port_deallocate (mach_task_self (), fsproc); -- if (err) -- error (0, err, "fsys_init"); /* Not necessarily fatal. */ --} -- --/* Set up the initial value of the standard exec data. */ --void --init_stdarrays () --{ -- auth_t nullauth; -- mach_port_t pt; -- mach_port_t ref; -- mach_port_t *std_port_array; -- int *std_int_array; -- int i; -- -- std_port_array = alloca (sizeof (mach_port_t) * INIT_PORT_MAX); -- std_int_array = alloca (sizeof (int) * INIT_INT_MAX); -- -- bzero (std_port_array, sizeof (mach_port_t) * INIT_PORT_MAX); -- bzero (std_int_array, sizeof (int) * INIT_INT_MAX); -- -- __USEPORT (AUTH, auth_makeauth (port, 0, MACH_MSG_TYPE_COPY_SEND, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, &nullauth)); -- -- /* MAKE_SEND is safe in these transactions because we destroy REF -- ourselves each time. */ -- pt = getcwdir (); -- ref = mach_reply_port (); -- io_reauthenticate (pt, ref, MACH_MSG_TYPE_MAKE_SEND); -- auth_user_authenticate (nullauth, ref, MACH_MSG_TYPE_MAKE_SEND, -- &std_port_array[INIT_PORT_CWDIR]); -- mach_port_destroy (mach_task_self (), ref); -- mach_port_deallocate (mach_task_self (), pt); -- -- pt = getcrdir (); -- ref = mach_reply_port (); -- io_reauthenticate (pt, ref, MACH_MSG_TYPE_MAKE_SEND); -- auth_user_authenticate (nullauth, ref, MACH_MSG_TYPE_MAKE_SEND, -- &std_port_array[INIT_PORT_CRDIR]); -- mach_port_destroy (mach_task_self (), ref); -- mach_port_deallocate (mach_task_self (), pt); -- -- std_port_array[INIT_PORT_AUTH] = nullauth; -- -- std_int_array[INIT_UMASK] = CMASK; -- -- __USEPORT (PROC, proc_setexecdata (port, std_port_array, -- MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, -- std_int_array, INIT_INT_MAX)); -- for (i = 0; i < INIT_PORT_MAX; i++) -- mach_port_deallocate (mach_task_self (), std_port_array[i]); --} -- --/* Frobnicate the kernel task and the proc server's idea of it (PID 2), -- so the kernel command line can be read as for a normal Hurd process. */ -- --void --frob_kernel_process (void) --{ -- error_t err; -- int argc, i; -- char *argz, *entry; -- size_t argzlen; -- size_t windowsz; -- vm_address_t mine, his; -- task_t task; -- process_t proc, kbs; -- -- err = proc_pid2task (procserver, HURD_PID_KERNEL, &task); -- if (err) -- { -- error (0, err, "cannot get kernel task port"); -- return; -- } -- err = proc_task2proc (procserver, task, &proc); -- if (err) -- { -- error (0, err, "cannot get kernel task's proc server port"); -- mach_port_deallocate (mach_task_self (), task); -- return; -- } -- -- /* Mark the kernel task as an essential task so that we or the proc server -- never want to task_terminate it. */ -- proc_mark_important (proc); -- -- err = record_essential_task ("kernel", task); -- assert_perror (err); -- -- err = task_get_bootstrap_port (task, &kbs); -- assert_perror (err); -- if (kbs == MACH_PORT_NULL) -- { -- /* The kernel task has no bootstrap port set, so we are presumably -- the first Hurd to boot. Install the kernel task's proc port from -- this Hurd's proc server as the task bootstrap port. Additional -- Hurds will see this. */ -- -- err = task_set_bootstrap_port (task, proc); -- if (err) -- error (0, err, "cannot set kernel task's bootstrap port"); -- -- if (fakeboot) -- error (0, 0, "warning: --fake-boot specified but I see no other Hurd"); -- } -- else -- { -- /* The kernel task has a bootstrap port set. Perhaps it is its proc -- server port from another Hurd. If so, propagate the kernel -- argument locations from that Hurd rather than diddling with the -- kernel task ourselves. */ -- -- vm_address_t kargv, kenvp; -- err = proc_get_arg_locations (kbs, &kargv, &kenvp); -- mach_port_deallocate (mach_task_self (), kbs); -- if (err) -- error (0, err, "kernel task bootstrap port (ignoring)"); -- else -- { -- err = proc_set_arg_locations (proc, kargv, kenvp); -- if (err) -- error (0, err, "cannot propagate original kernel command line"); -- else -- { -- mach_port_deallocate (mach_task_self (), proc); -- mach_port_deallocate (mach_task_self (), task); -- if (! fakeboot) -- error (0, 0, "warning: " -- "I see another Hurd, but --fake-boot was not given"); -- return; -- } -- } -- } -- -- /* Our arguments make up the multiboot command line used to boot the -- kernel. We'll write into the kernel task a page containing a -- canonical argv array and argz of those words. */ -- -- err = argz_create (&global_argv[1], &argz, &argzlen); -- assert_perror (err); -- argc = argz_count (argz, argzlen); -- -- windowsz = round_page (((argc + 1) * sizeof (char *)) + argzlen); -- -- mine = (vm_address_t) mmap (0, windowsz, PROT_READ|PROT_WRITE, -- MAP_ANON, 0, 0); -- assert (mine != -1); -- err = vm_allocate (task, &his, windowsz, 1); -- if (err) -- { -- error (0, err, "cannot allocate %Zu bytes in kernel task", windowsz); -- free (argz); -- mach_port_deallocate (mach_task_self (), proc); -- mach_port_deallocate (mach_task_self (), task); -- munmap ((caddr_t) mine, windowsz); -- return; -- } -- -- for (i = 0, entry = argz; entry != NULL; -- ++i, entry = argz_next (argz, argzlen, entry)) -- ((char **) mine)[i] = ((char *) &((char **) his)[argc + 1] -- + (entry - argz)); -- ((char **) mine)[argc] = NULL; -- memcpy (&((char **) mine)[argc + 1], argz, argzlen); -- -- free (argz); -- -- /* We have the data all set up in our copy, now just write it over. */ -- err = vm_write (task, his, mine, windowsz); -- mach_port_deallocate (mach_task_self (), task); -- munmap ((caddr_t) mine, windowsz); -- if (err) -- { -- error (0, err, "cannot write command line into kernel task"); -- return; -- } -- -- /* The argument vector is set up in the kernel task at address HIS. -- Finally, we can inform the proc server where to find it. */ -- err = proc_set_arg_locations (proc, his, his + (argc * sizeof (char *))); -- mach_port_deallocate (mach_task_self (), proc); -- if (err) -- error (0, err, "proc_set_arg_locations for kernel task"); --} -- --/** Running userland. **/ -- --/* In the "split-init" setup, we just run a single program (usually -- /libexec/runsystem) that is not expected to ever exit (or stop). -- If it does exit (or can't be started), we go to an emergency single-user -- shell as a fallback. */ -- -- --static pid_t child_pid; /* PID of the child we run */ --static task_t child_task; /* and its (original) task port */ -- --error_t send_signal (mach_port_t msgport, int signal, mach_port_t refport, -- mach_msg_timeout_t); -- --static void launch_something (const char *why); -- -- --/* SIGNO has arrived and has been validated. Do whatever work it -- implies. */ --void --process_signal (int signo) --{ -- if (signo == SIGCHLD) -- { -- /* A child died. Find its status. */ -- int status; -- pid_t pid; -- -- while (1) -- { -- pid = waitpid (WAIT_ANY, &status, WNOHANG | WUNTRACED); -- if (pid <= 0) -- break; /* No more children. */ -- -- /* Since we are init, orphaned processes get reparented to us and -- alas, all our adopted children eventually die. Woe is us. We -- just need to reap the zombies to relieve the proc server of -- its burden, and then we can forget about the little varmints. */ -- -- if (pid == child_pid) -- { -- /* The big magilla bit the dust. */ -- -- char *desc = 0; -- -- mach_port_deallocate (mach_task_self (), child_task); -- child_task = MACH_PORT_NULL; -- child_pid = -1; -- -- if (WIFSIGNALED (status)) -- asprintf (&desc, "terminated abnormally (%s)", -- strsignal (WTERMSIG (status))); -- else if (WIFSTOPPED (status)) -- asprintf (&desc, "stopped abnormally (%s)", -- strsignal (WTERMSIG (status))); -- else if (WEXITSTATUS (status) == 0) -- desc = strdup ("finished"); -- else -- asprintf (&desc, "exited with status %d", -- WEXITSTATUS (status)); -- -- { -- char buf[40]; -- snprintf (buf, sizeof buf, "%d", status); -- setenv ("STATUS", buf, 1); -- } -- -- launch_something (desc); -- free (desc); -- } -- } -- } -- else -- { -- /* Pass the signal on to the child. */ -- task_t task; -- error_t err; -- -- err = proc_pid2task (procserver, child_pid, &task); -- if (err) -- { -- error (0, err, "proc_pid2task on %d", child_pid); -- task = child_task; -- } -- else -- { -- mach_port_deallocate (mach_task_self (), child_task); -- child_task = task; -- } -- -- if (signo == SIGKILL) -- { -- err = task_terminate (task); -- if (err != MACH_SEND_INVALID_DEST) -- error (0, err, "task_terminate"); -- } -- else -- { -- mach_port_t msgport; -- err = proc_getmsgport (procserver, child_pid, &msgport); -- if (err) -- error (0, err, "proc_getmsgport"); -- else -- { -- err = send_signal (msgport, signo, task, -- 500); /* Block only half a second. */ -- mach_port_deallocate (mach_task_self (), msgport); -- if (err) -- { -- error (0, err, "cannot send %s to child %d", -- strsignal (signo), child_pid); -- err = task_terminate (task); -- if (err != MACH_SEND_INVALID_DEST) -- error (0, err, "task_terminate"); -- } -- } -- } -- } --} -- --/* Start the child program PROG. It is run via /libexec/console-run -- with the given additional arguments. */ --static int --start_child (const char *prog, char **progargs) --{ -- file_t file; -- error_t err; -- char *args; -- size_t arglen; -- -- if (progargs == 0) -- { -- const char *argv[] = { "/libexec/console-run", prog, 0 }; -- err = argz_create ((char **) argv, &args, &arglen); -- } -- else -- { -- int argc = 0; -- while (progargs[argc] != 0) -- ++argc; -- { -- const char *argv[2 + argc + 1]; -- argv[0] = "/libexec/console-run"; -- argv[1] = prog; -- argv[2 + argc] = 0; -- while (argc-- > 0) -- argv[2 + argc] = progargs[argc]; -- err = argz_create ((char **) argv, &args, &arglen); -- } -- } -- assert_perror (err); -- -- file = file_name_lookup (args, O_EXEC, 0); -- if (file == MACH_PORT_NULL) -- { -- error (0, errno, "%s", args); -- free (args); -- return -1; -- } -- -- task_create (mach_task_self (), --#ifdef KERN_INVALID_LEDGER -- NULL, 0, /* OSF Mach */ --#endif -- 0, &child_task); -- proc_set_init_task (procserver, child_task); -- proc_task2pid (procserver, child_task, &child_pid); -- proc_task2proc (procserver, child_task, &default_ports[INIT_PORT_PROC]); -- -- if (bootstrap_args & RB_KDB) -- { -- printf ("Pausing for %s\n", args); -- getchar (); -- } -- -- err = file_exec (file, child_task, 0, -- args, arglen, -- startup_envz, startup_envz_len, -- NULL, MACH_MSG_TYPE_COPY_SEND, 0, /* No fds. */ -- default_ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, -- default_ints, INIT_INT_MAX, -- NULL, 0, NULL, 0); -- proc_mark_important (default_ports[INIT_PORT_PROC]); -- mach_port_deallocate (mach_task_self (), default_ports[INIT_PORT_PROC]); -- mach_port_deallocate (mach_task_self (), file); -- if (err) -- { -- error (0, err, "Cannot execute %s", args); -- free (args); -- return -1; -- } -- free (args); -- return 0; --} -- --static void --launch_something (const char *why) --{ -- file_t something; -- static unsigned int try; -- static const char *const tries[] = -- { -- "/libexec/runsystem", -- _PATH_BSHELL, -- "/bin/shd", /* XXX */ -- }; -- -- if (why) -- error (0, 0, "%s %s", tries[try - 1], why); -- -- something = file_name_lookup (tries[try], O_EXEC, 0); -- if (something != MACH_PORT_NULL) -- { -- mach_port_deallocate (mach_task_self (), something); -- if (try == 0 && start_child (tries[try++], &global_argv[1]) == 0) -- return; -- } -- else -- try++; -- -- while (try < sizeof tries / sizeof tries[0]) -- { -- something = file_name_lookup (tries[try], O_EXEC, 0); -- if (something != MACH_PORT_NULL) -- { -- mach_port_deallocate (mach_task_self (), something); -- if (start_child (tries[try++], NULL) == 0) -- return; -- } -- } -- -- crash_system (); --} -- --void --launch_system (void) --{ -- launch_something (0); --} -- --/** RPC servers **/ -- --kern_return_t --S_startup_procinit (startup_t server, -- mach_port_t reply, -- mach_msg_type_name_t reply_porttype, -- process_t proc, -- mach_port_t *startuptask, -- auth_t *auth, -- mach_port_t *priv, -- mach_msg_type_name_t *hostprivtype, -- mach_port_t *dev, -- mach_msg_type_name_t *devtype) --{ -- if (procserver) -- /* Only one proc server. */ -- return EPERM; -- -- procserver = proc; -- -- procreply = reply; -- procreplytype = reply_porttype; -- -- /* Save the reply port until we get startup_authinit. */ -- if (authserver) -- launch_core_servers (); -- -- return MIG_NO_REPLY; --} -- --/* Called by the auth server when it starts up. */ -- --kern_return_t --S_startup_authinit (startup_t server, -- mach_port_t reply, -- mach_msg_type_name_t reply_porttype, -- mach_port_t auth, -- mach_port_t *proc, -- mach_msg_type_name_t *proctype) --{ -- if (authserver) -- /* Only one auth server. */ -- return EPERM; -- -- authserver = auth; -- -- /* Save the reply port until we get startup_procinit. */ -- authreply = reply; -- authreplytype = reply_porttype; -- -- if (procserver) -- launch_core_servers (); -- -- return MIG_NO_REPLY; --} -- -- --kern_return_t --S_startup_essential_task (mach_port_t server, -- mach_port_t reply, -- mach_msg_type_name_t replytype, -- task_t task, -- mach_port_t excpt, -- char *name, -- mach_port_t credential) --{ -- static int authinit, procinit, execinit; -- int fail; -- -- /* Always deallocate the extra reference this message carries. */ -- if (MACH_PORT_VALID (credential)) -- mach_port_deallocate (mach_task_self (), credential); -- -- if (credential != host_priv) -- return EPERM; -- -- fail = record_essential_task (name, task); -- if (fail) -- return fail; -- -- if (!booted) -- { -- if (!strcmp (name, "auth")) -- authinit = 1; -- else if (!strcmp (name, "exec")) -- { -- execinit = 1; -- mach_port_t execproc; -- proc_task2proc (procserver, task, &execproc); -- proc_mark_important (execproc); -- } -- else if (!strcmp (name, "proc")) -- procinit = 1; -- -- if (authinit && execinit && procinit) -- { -- /* Reply to this RPC, after that everything -- is ready for real startup to begin. */ -- startup_essential_task_reply (reply, replytype, 0); -- -- init_stdarrays (); -- frob_kernel_process (); -- -- launch_system (); -- -- booted = 1; -- -- return MIG_NO_REPLY; -- } -- } -- -- return 0; --} -- --kern_return_t --S_startup_request_notification (mach_port_t server, -- mach_port_t notify, -- char *name) --{ -- struct ntfy_task *nt; -- -- request_dead_name (notify); -- -- /* Note that the ntfy_tasks list is kept in inverse order of the -- calls; this is important. We need later notification requests -- to get executed first. */ -- nt = malloc (sizeof (struct ntfy_task)); -- nt->notify_port = notify; -- nt->next = ntfy_tasks; -- ntfy_tasks = nt; -- nt->name = malloc (strlen (name) + 1); -- strcpy (nt->name, name); -- return 0; --} -- --kern_return_t --do_mach_notify_dead_name (mach_port_t notify, -- mach_port_t name) --{ -- struct ntfy_task *nt, *pnt; -- struct ess_task *et; -- -- assert (notify == startup); -- -- /* Deallocate the extra reference the notification carries. */ -- mach_port_deallocate (mach_task_self (), name); -- -- for (et = ess_tasks; et != NULL; et = et->next) -- if (et->task_port == name) -- /* An essential task has died. */ -- { -- error (0, 0, "Crashing system; essential task %s died", et->name); -- crash_system (); -- } -- -- for (nt = ntfy_tasks, pnt = NULL; nt != NULL; pnt = nt, nt = nt->next) -- if (nt->notify_port == name) -- { -- /* Someone who wanted to be notified is gone. */ -- mach_port_deallocate (mach_task_self (), name); -- if (pnt != NULL) -- pnt->next = nt->next; -- else -- ntfy_tasks = nt->next; -- free (nt); -- -- return 0; -- } -- -- if (! booted) -- { -- /* The system has not come up yet, so essential tasks are not yet -- registered. But the essential servers involved in the bootstrap -- handshake might crash before completing it, so we have requested -- dead-name notification on those tasks. */ -- static const struct { task_t *taskp; const char *name; } boots[] = -- { -- {&fstask, "bootstrap filesystem"}, -- {&authtask, "auth"}, -- {&proctask, "proc"}, -- }; -- size_t i; -- for (i = 0; i < sizeof boots / sizeof boots[0]; ++i) -- if (name == *boots[i].taskp) -- { -- error (0, 0, "Crashing system; %s server died during bootstrap", -- boots[i].name); -- crash_mach (); -- } -- error (0, 0, "BUG! Unexpected dead-name notification (name %#zx)", -- name); -- crash_mach (); -- } -- -- return 0; --} -- --kern_return_t --S_startup_reboot (mach_port_t server, -- mach_port_t refpt, -- int code) --{ -- if (refpt != host_priv) -- return EPERM; -- -- reboot_system (code); -- for (;;); --} -- --/* Stubs for unused notification RPCs. */ -- --kern_return_t --do_mach_notify_port_destroyed (mach_port_t notify, -- mach_port_t rights) --{ -- return EOPNOTSUPP; --} -- --kern_return_t --do_mach_notify_send_once (mach_port_t notify) --{ -- return EOPNOTSUPP; --} -- --kern_return_t --do_mach_notify_no_senders (mach_port_t port, mach_port_mscount_t mscount) --{ -- return EOPNOTSUPP; --} -- --kern_return_t --do_mach_notify_port_deleted (mach_port_t notify, -- mach_port_t name) --{ -- return EOPNOTSUPP; --} -- --kern_return_t --do_mach_notify_msg_accepted (mach_port_t notify, -- mach_port_t name) --{ -- return EOPNOTSUPP; --} -- --/* msg server */ -- --kern_return_t --S_msg_sig_post_untraced (mach_port_t msgport, -- mach_port_t reply, mach_msg_type_name_t reply_type, -- int signo, natural_t sigcode, mach_port_t refport) --{ -- if (refport != mach_task_self ()) -- return EPERM; -- mach_port_deallocate (mach_task_self (), refport); -- -- /* Reply immediately */ -- msg_sig_post_untraced_reply (reply, reply_type, 0); -- -- process_signal (signo); -- return MIG_NO_REPLY; --} -- --kern_return_t --S_msg_sig_post (mach_port_t msgport, -- mach_port_t reply, mach_msg_type_name_t reply_type, -- int signo, natural_t sigcode, mach_port_t refport) --{ -- if (refport != mach_task_self ()) -- return EPERM; -- mach_port_deallocate (mach_task_self (), refport); -- -- /* Reply immediately */ -- msg_sig_post_reply (reply, reply_type, 0); -- -- process_signal (signo); -- return MIG_NO_REPLY; --} -- -- --/* For the rest of the msg functions, just call the C library's -- internal server stubs usually run in the signal thread. */ -- --kern_return_t --S_msg_proc_newids (mach_port_t process, -- mach_port_t task, -- pid_t ppid, -- pid_t pgrp, -- int orphaned) --{ return _S_msg_proc_newids (process, task, ppid, pgrp, orphaned); } -- -- --kern_return_t --S_msg_add_auth (mach_port_t process, -- auth_t auth) --{ return _S_msg_add_auth (process, auth); } -- -- --kern_return_t --S_msg_del_auth (mach_port_t process, -- mach_port_t task, -- intarray_t uids, -- mach_msg_type_number_t uidsCnt, -- intarray_t gids, -- mach_msg_type_number_t gidsCnt) --{ return _S_msg_del_auth (process, task, uids, uidsCnt, gids, gidsCnt); } -- -- --kern_return_t --S_msg_get_init_port (mach_port_t process, -- mach_port_t refport, -- int which, -- mach_port_t *port, -- mach_msg_type_name_t *portPoly) --{ return _S_msg_get_init_port (process, refport, which, port, portPoly); } -- -- --kern_return_t --S_msg_set_init_port (mach_port_t process, -- mach_port_t refport, -- int which, -- mach_port_t port) --{ return _S_msg_set_init_port (process, refport, which, port); } -- -- --kern_return_t --S_msg_get_init_ports (mach_port_t process, -- mach_port_t refport, -- portarray_t *ports, -- mach_msg_type_name_t *portsPoly, -- mach_msg_type_number_t *portsCnt) --{ return _S_msg_get_init_ports (process, refport, ports, portsPoly, portsCnt); } -- -- --kern_return_t --S_msg_set_init_ports (mach_port_t process, -- mach_port_t refport, -- portarray_t ports, -- mach_msg_type_number_t portsCnt) --{ return _S_msg_set_init_ports (process, refport, ports, portsCnt); } -- -- --kern_return_t --S_msg_get_init_int (mach_port_t process, -- mach_port_t refport, -- int which, -- int *value) --{ return _S_msg_get_init_int (process, refport, which, value); } -- -- --kern_return_t --S_msg_set_init_int (mach_port_t process, -- mach_port_t refport, -- int which, -- int value) --{ return _S_msg_set_init_int (process, refport, which, value); } -- -- --kern_return_t --S_msg_get_init_ints (mach_port_t process, -- mach_port_t refport, -- intarray_t *values, -- mach_msg_type_number_t *valuesCnt) --{ return _S_msg_get_init_ints (process, refport, values, valuesCnt); } -- -- --kern_return_t --S_msg_set_init_ints (mach_port_t process, -- mach_port_t refport, -- intarray_t values, -- mach_msg_type_number_t valuesCnt) --{ return _S_msg_set_init_ints (process, refport, values, valuesCnt); } -- -- --kern_return_t --S_msg_get_dtable (mach_port_t process, -- mach_port_t refport, -- portarray_t *dtable, -- mach_msg_type_name_t *dtablePoly, -- mach_msg_type_number_t *dtableCnt) --{ return _S_msg_get_dtable (process, refport, dtable, dtablePoly, dtableCnt); } -- -- --kern_return_t --S_msg_set_dtable (mach_port_t process, -- mach_port_t refport, -- portarray_t dtable, -- mach_msg_type_number_t dtableCnt) --{ return _S_msg_set_dtable (process, refport, dtable, dtableCnt); } -- -- --kern_return_t --S_msg_get_fd (mach_port_t process, -- mach_port_t refport, -- int fd, -- mach_port_t *port, -- mach_msg_type_name_t *portPoly) --{ return _S_msg_get_fd (process, refport, fd, port, portPoly); } -- -- --kern_return_t --S_msg_set_fd (mach_port_t process, -- mach_port_t refport, -- int fd, -- mach_port_t port) --{ return _S_msg_set_fd (process, refport, fd, port); } -- -- --kern_return_t --S_msg_get_environment (mach_port_t process, -- data_t *value, -- mach_msg_type_number_t *valueCnt) --{ return _S_msg_get_environment (process, value, valueCnt); } -- -- --kern_return_t --S_msg_set_environment (mach_port_t process, -- mach_port_t refport, -- data_t value, -- mach_msg_type_number_t valueCnt) --{ return _S_msg_set_environment (process, refport, value, valueCnt); } -- -- --kern_return_t --S_msg_get_env_variable (mach_port_t process, -- string_t variable, -- data_t *value, -- mach_msg_type_number_t *valueCnt) --{ return _S_msg_get_env_variable (process, variable, value, valueCnt); } -- -- --kern_return_t --S_msg_set_env_variable (mach_port_t process, -- mach_port_t refport, -- string_t variable, -- string_t value, -- boolean_t replace) --{ return _S_msg_set_env_variable (process, refport, variable, value, replace); } -- --error_t --S_msg_describe_ports (mach_port_t process, -- mach_port_t refport, -- mach_port_array_t names, -- mach_msg_type_number_t namesCnt, -- data_t *descriptions, -- mach_msg_type_number_t *descriptionsCnt) --{ -- return _S_msg_describe_ports (process, refport, names, namesCnt, -- descriptions, descriptionsCnt); --} -- --error_t --S_msg_report_wait (mach_port_t process, thread_t thread, -- string_t desc, mach_msg_id_t *rpc) --{ -- *desc = 0; -- *rpc = 0; -- return 0; --} -diff --git a/init/stubs.c b/init/stubs.c -deleted file mode 100644 -index 5292ab6..0000000 ---- a/init/stubs.c -+++ /dev/null -@@ -1,139 +0,0 @@ --/* By-hand stubs for some RPC calls -- Copyright (C) 1994,96,99,2000 Free Software Foundation, Inc. -- -- This program 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. -- -- This program 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 this program; if not, write to the Free Software -- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -- --#include <stdlib.h> --#include <hurd/hurd_types.h> --#include <mach.h> --#include <string.h> --#include <assert.h> -- --/* From hurd/msg.defs: */ --#define RPCID_SIG_POST 23000 -- -- --/* Send signal SIGNO to MSGPORT with REFPORT as reference. Don't -- block in any fashion. */ --error_t --send_signal (mach_port_t msgport, -- int signal, -- mach_port_t refport, -- mach_msg_timeout_t timeout) --{ -- error_t err; -- -- /* This message buffer might be modified by mach_msg in some error cases, -- so we cannot safely reuse a static buffer. */ -- struct -- { -- mach_msg_header_t head; -- mach_msg_type_t signaltype; -- int signal; -- mach_msg_type_t sigcode_type; -- natural_t sigcode; -- mach_msg_type_t refporttype; -- mach_port_t refport; -- } -- message = -- { -- { -- /* Message header: */ -- (MACH_MSGH_BITS_COMPLEX -- | MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, -- MACH_MSG_TYPE_MAKE_SEND_ONCE)), /* msgh_bits */ -- sizeof message, /* msgh_size */ -- msgport, /* msgh_remote_port */ -- MACH_PORT_NULL, /* msgh_local_port */ -- 0, /* msgh_seqno */ -- RPCID_SIG_POST, /* msgh_id */ -- }, -- { -- /* Type descriptor for signo */ -- MACH_MSG_TYPE_INTEGER_32, /* msgt_name */ -- 32, /* msgt_size */ -- 1, /* msgt_number */ -- 1, /* msgt_inline */ -- 0, /* msgt_longform */ -- 0, /* msgt_deallocate */ -- 0, /* msgt_unused */ -- }, -- /* Signal number */ -- signal, -- /* Type descriptor for sigcode */ -- { -- MACH_MSG_TYPE_INTEGER_32, /* msgt_name */ -- 32, /* msgt_size */ -- 1, /* msgt_number */ -- 1, /* msgt_inline */ -- 0, /* msgt_longform */ -- 0, /* msgt_deallocate */ -- 0, /* msgt_unused */ -- }, -- /* Sigcode */ -- 0, -- { -- /* Type descriptor for refport */ -- MACH_MSG_TYPE_COPY_SEND, /* msgt_name */ -- 32, /* msgt_size */ -- 1, /* msgt_number */ -- 1, /* msgt_inline */ -- 0, /* msgt_longform */ -- 0, /* msgt_deallocate */ -- 0, /* msgt_unused */ -- }, -- /* Reference port */ -- refport -- }; -- -- err = mach_msg (&message.head, -- MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof message, 0, -- MACH_PORT_NULL, timeout, MACH_PORT_NULL); -- -- switch (err) -- { -- case MACH_SEND_TIMED_OUT: -- /* The send could not complete in time. In this error case, the -- kernel has modified the message buffer in a pseudo-receive -- operation. That means our COPY_SEND refs might now be MOVE_SEND -- refs, in which case each has gained user ref accordingly. To -- avoid leaking those refs, we must clean up the buffer. We don't -- use mach_msg_destroy because it assumes the local/remote ports in -- the header have been reversed as from a real receive, while a -- pseudo-receive leaves them as they were. */ -- if (MACH_MSGH_BITS_REMOTE (message.head.msgh_bits) -- == MACH_MSG_TYPE_MOVE_SEND) -- mach_port_deallocate (mach_task_self (), -- message.head.msgh_remote_port); -- if (message.refporttype.msgt_name == MACH_MSG_TYPE_MOVE_SEND) -- mach_port_deallocate (mach_task_self (), message.refport); -- break; -- -- /* These are the other codes that mean a pseudo-receive modified -- the message buffer and we might need to clean up the send rights. -- None of them should be possible in our usage. */ -- case MACH_SEND_INTERRUPTED: -- case MACH_SEND_INVALID_NOTIFY: -- case MACH_SEND_NO_NOTIFY: -- case MACH_SEND_NOTIFY_IN_PROGRESS: -- assert_perror (err); -- break; -- -- default: /* Other errors are safe to ignore. */ -- break; -- } -- -- return err; --} -diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c -index a590975..42e991e 100644 ---- a/libdiskfs/boot-start.c -+++ b/libdiskfs/boot-start.c -@@ -46,7 +46,7 @@ static task_t parent_task = MACH_PORT_NULL; - static pthread_mutex_t execstartlock; - static pthread_cond_t execstarted; - --const char *diskfs_boot_init_program = _HURD_INIT; -+const char *diskfs_boot_init_program = _HURD_STARTUP; - - static void start_execserver (); - -diff --git a/libdiskfs/opts-std-startup.c b/libdiskfs/opts-std-startup.c -index 6fe2875..ed25a18 100644 ---- a/libdiskfs/opts-std-startup.c -+++ b/libdiskfs/opts-std-startup.c -@@ -59,7 +59,7 @@ startup_options[] = - "Required for bootstrap filesystem, the multiboot kernel command line"}, - {"bootflags", 0, 0, OPTION_ALIAS|OPTION_HIDDEN}, - {"boot-init-program", OPT_BOOT_INIT_PROGRAM, "FILE", 0, -- "For bootstrap filesystem, init program to run (default " _HURD_INIT ")"}, -+ "For bootstrap filesystem, init program to run (default " _HURD_STARTUP ")"}, - {"boot-debug-pause", OPT_BOOT_PAUSE, 0, 0, - "Pause for keystroke before starting bootstrap programs"}, - {"boot-command", OPT_BOOT_COMMAND, 0, 0, -diff --git a/startup/Makefile b/startup/Makefile -new file mode 100644 -index 0000000..2d6b892 ---- /dev/null -+++ b/startup/Makefile -@@ -0,0 +1,31 @@ -+# -+# Copyright (C) 1994,95,96,99,2001 Free Software Foundation, Inc. -+# -+# This program 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. -+# -+# This program 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 this program; if not, write to the Free Software -+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ -+dir := startup -+makemode := server -+ -+SRCS = startup.c stubs.c -+OBJS = $(SRCS:.c=.o) \ -+ startupServer.o notifyServer.o startup_replyUser.o msgServer.o \ -+ startup_notifyUser.o -+target = startup -+HURDLIBS = shouldbeinlibc -+ -+include ../Makeconf -+ -+mung_msg_S.h: msg_S.h -+ sed 's/msg_server/mung_msg_server/' < $< > $@ -diff --git a/startup/startup.c b/startup/startup.c -new file mode 100644 -index 0000000..29269a6 ---- /dev/null -+++ b/startup/startup.c -@@ -0,0 +1,1593 @@ -+/* Start and maintain hurd core servers and system run state -+ -+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -+ 2005, 2008, 2013 Free Software Foundation, Inc. -+ 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; see the file COPYING. If not, write to -+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -+ -+/* Written by Michael I. Bushnell and Roland McGrath. */ -+ -+/* This is probably more include files than I've ever seen before for -+ one file. */ -+#include <hurd.h> -+#include <hurd/fs.h> -+#include <hurd/fsys.h> -+#include <device/device.h> -+#include <stdio.h> -+#include <assert.h> -+#include <hurd/paths.h> -+#include <sys/reboot.h> -+#include <sys/file.h> -+#include <unistd.h> -+#include <string.h> -+#include <mach/notify.h> -+#include <stdlib.h> -+#include <hurd/msg.h> -+#include <hurd/term.h> -+#include <hurd/fshelp.h> -+#include <paths.h> -+#include <sys/mman.h> -+#include <hurd/msg_server.h> -+#include <wire.h> -+#include <sys/wait.h> -+#include <error.h> -+#include <hurd/msg_reply.h> -+#include <argz.h> -+#include <maptime.h> -+#include <version.h> -+#include <argp.h> -+#include <pids.h> -+ -+#include "startup_notify_U.h" -+#include "startup_reply_U.h" -+#include "startup_S.h" -+#include "notify_S.h" -+#include "mung_msg_S.h" -+ -+/* host_reboot flags for when we crash. */ -+static int crash_flags = RB_AUTOBOOT; -+ -+#define BOOT(flags) ((flags & RB_HALT) ? "halt" : "reboot") -+ -+ -+const char *argp_program_version = STANDARD_HURD_VERSION (startup); -+ -+static struct argp_option -+options[] = -+{ -+ {"single-user", 's', 0, 0, "Startup system in single-user mode"}, -+ {"query", 'q', 0, 0, "Ask for the names of servers to start"}, -+ {"init-name", 'n', 0, 0 }, -+ {"crash-debug", 'H', 0, 0, "On system crash, go to kernel debugger"}, -+ {"debug", 'd', 0, 0 }, -+ {"fake-boot", 'f', 0, 0, "This hurd hasn't been booted on the raw machine"}, -+ {0, 'x', 0, OPTION_HIDDEN}, -+ {0} -+}; -+ -+static char doc[] = "Start and maintain hurd core servers and system run state"; -+ -+static int booted; /* Set when the core servers are up. */ -+ -+/* This structure keeps track of each notified task. */ -+struct ntfy_task -+ { -+ mach_port_t notify_port; -+ struct ntfy_task *next; -+ char *name; -+ }; -+ -+/* This structure keeps track of each registered essential task. */ -+struct ess_task -+ { -+ struct ess_task *next; -+ task_t task_port; -+ char *name; -+ }; -+ -+/* These are linked lists of all of the registered items. */ -+static struct ess_task *ess_tasks; -+static struct ntfy_task *ntfy_tasks; -+ -+ -+/* Our receive right */ -+static mach_port_t startup; -+ -+/* Ports to the kernel */ -+static mach_port_t host_priv, device_master; -+ -+/* Args to bootstrap, expressed as flags */ -+static int bootstrap_args = 0; -+ -+/* Stored information for returning proc and auth startup messages. */ -+static mach_port_t procreply, authreply; -+static mach_msg_type_name_t procreplytype, authreplytype; -+ -+/* Our ports to auth and proc. */ -+static mach_port_t authserver; -+static mach_port_t procserver; -+ -+/* Our bootstrap port, on which we call fsys_getpriv and fsys_init. */ -+static mach_port_t bootport; -+ -+/* Set iff we are a `fake' bootstrap. */ -+static int fakeboot; -+ -+/* The tasks of auth and proc and the bootstrap filesystem. */ -+static task_t authtask, proctask, fstask; -+ -+static mach_port_t default_ports[INIT_PORT_MAX]; -+static mach_port_t default_dtable[3]; -+static int default_ints[INIT_INT_MAX]; -+ -+static char **global_argv; -+static char *startup_envz; -+static size_t startup_envz_len; -+ -+void launch_system (void); -+void process_signal (int signo); -+ -+/** Utility functions **/ -+ -+/* Read a string from stdin into BUF. */ -+static int -+getstring (char *buf, size_t bufsize) -+{ -+ if (fgets (buf, bufsize, stdin) != NULL && buf[0] != '\0') -+ { -+ size_t len = strlen (buf); -+ if (buf[len - 1] == '\n' || buf[len - 1] == '\r') -+ buf[len - 1] = '\0'; -+ return 1; -+ } -+ return 0; -+} -+ -+ -+/** System shutdown **/ -+ -+/* Reboot the microkernel. */ -+void -+reboot_mach (int flags) -+{ -+ if (fakeboot) -+ { -+ printf ("%s: Would %s Mach with flags %#x\n", -+ program_invocation_short_name, BOOT (flags), flags); -+ fflush (stdout); -+ exit (1); -+ } -+ else -+ { -+ error_t err; -+ printf ("%s: %sing Mach (flags %#x)...\n", -+ program_invocation_short_name, BOOT (flags), flags); -+ fflush (stdout); -+ sleep (5); -+ while ((err = host_reboot (host_priv, flags))) -+ error (0, err, "reboot"); -+ for (;;); -+ } -+} -+ -+/* Reboot the microkernel, specifying that this is a crash. */ -+void -+crash_mach (void) -+{ -+ reboot_mach (crash_flags); -+} -+ -+/* Notify all tasks that have requested shutdown notifications */ -+void -+notify_shutdown (const char *msg) -+{ -+ struct ntfy_task *n; -+ -+ for (n = ntfy_tasks; n != NULL; n = n->next) -+ { -+ error_t err; -+ printf ("%s: notifying %s of %s...", -+ program_invocation_short_name, n->name, msg); -+ fflush (stdout); -+ err = startup_dosync (n->notify_port, 60000); /* 1 minute to reply */ -+ if (err == MACH_SEND_INVALID_DEST) -+ puts ("(no longer present)"); -+ else if (err) -+ puts (strerror (err)); -+ else -+ puts ("done"); -+ fflush (stdout); -+ } -+} -+ -+/* Reboot the Hurd. */ -+void -+reboot_system (int flags) -+{ -+ notify_shutdown ("shutdown"); -+ -+ if (fakeboot) -+ { -+ pid_t *pp; -+ size_t npids = 0; -+ error_t err; -+ int ind; -+ -+ err = proc_getallpids (procserver, &pp, &npids); -+ if (err == MACH_SEND_INVALID_DEST) -+ { -+ procbad: -+ /* The procserver must have died. Give up. */ -+ error (0, 0, "Can't simulate crash; proc has died"); -+ reboot_mach (flags); -+ } -+ for (ind = 0; ind < npids; ind++) -+ { -+ task_t task; -+ -+ err = proc_pid2task (procserver, pp[ind], &task); -+ if (err == MACH_SEND_INVALID_DEST) -+ goto procbad; -+ else if (err) -+ { -+ error (0, err, "Getting task for pid %d", pp[ind]); -+ continue; -+ } -+ -+ /* Postpone self so we can finish; postpone proc -+ so that we can finish. */ -+ if (task != mach_task_self () && task != proctask) -+ { -+ struct procinfo *pi = 0; -+ size_t pisize = 0; -+ char *noise; -+ size_t noise_len = 0; -+ int flags; -+ err = proc_getprocinfo (procserver, pp[ind], &flags, -+ (int **)&pi, &pisize, -+ &noise, &noise_len); -+ if (err == MACH_SEND_INVALID_DEST) -+ goto procbad; -+ if (err) -+ { -+ error (0, err, "Getting procinfo for pid %d", pp[ind]); -+ continue; -+ } -+ if (!(pi->state & PI_NOPARENT)) -+ { -+ printf ("%s: Killing pid %d\n", -+ program_invocation_short_name, pp[ind]); -+ fflush (stdout); -+ task_terminate (task); -+ } -+ if (noise_len > 0) -+ munmap (noise, noise_len); -+ } -+ } -+ printf ("%s: Killing proc server\n", program_invocation_short_name); -+ fflush (stdout); -+ task_terminate (proctask); -+ printf ("%s: Exiting", program_invocation_short_name); -+ fflush (stdout); -+ } -+ reboot_mach (flags); -+} -+ -+/* Reboot the Hurd, specifying that this is a crash. */ -+void -+crash_system (void) -+{ -+ reboot_system (crash_flags); -+} -+ -+ -+ -+/* Request a dead-name notification sent to our port. */ -+static void -+request_dead_name (mach_port_t name) -+{ -+ mach_port_t prev; -+ mach_port_request_notification (mach_task_self (), name, -+ MACH_NOTIFY_DEAD_NAME, 1, startup, -+ MACH_MSG_TYPE_MAKE_SEND_ONCE, &prev); -+ if (prev != MACH_PORT_NULL) -+ mach_port_deallocate (mach_task_self (), prev); -+} -+ -+/* Record an essential task in the list. */ -+static error_t -+record_essential_task (const char *name, task_t task) -+{ -+ struct ess_task *et; -+ /* Record this task as essential. */ -+ et = malloc (sizeof (struct ess_task)); -+ if (et == NULL) -+ return ENOMEM; -+ et->task_port = task; -+ et->name = strdup (name); -+ if (et->name == NULL) -+ { -+ free (et); -+ return ENOMEM; -+ } -+ et->next = ess_tasks; -+ ess_tasks = et; -+ -+ /* Dead-name notification on the task port will tell us when it dies. */ -+ request_dead_name (task); -+ -+#if 0 -+ /* Taking over the exception port will give us a better chance -+ if the task tries to get wedged on a fault. */ -+ task_set_special_port (task, TASK_EXCEPTION_PORT, startup); -+#endif -+ -+ return 0; -+} -+ -+ -+/** Starting programs **/ -+ -+/* Run SERVER, giving it INIT_PORT_MAX initial ports from PORTS. -+ Set TASK to be the task port of the new image. */ -+void -+run (const char *server, mach_port_t *ports, task_t *task) -+{ -+ char buf[BUFSIZ]; -+ const char *prog = server; -+ -+ if (bootstrap_args & RB_INITNAME) -+ { -+ printf ("Server file name (default %s): ", server); -+ if (getstring (buf, sizeof (buf))) -+ prog = buf; -+ } -+ -+ while (1) -+ { -+ file_t file; -+ error_t err; -+ -+ file = file_name_lookup (prog, O_EXEC, 0); -+ if (file == MACH_PORT_NULL) -+ error (0, errno, "%s", prog); -+ else -+ { -+ task_create (mach_task_self (), -+#ifdef KERN_INVALID_LEDGER -+ NULL, 0, /* OSF Mach */ -+#endif -+ 0, task); -+ if (bootstrap_args & RB_KDB) -+ { -+ printf ("Pausing for %s\n", prog); -+ getchar (); -+ } -+ err = file_exec (file, *task, 0, -+ (char *)prog, strlen (prog) + 1, /* Args. */ -+ startup_envz, startup_envz_len, -+ default_dtable, MACH_MSG_TYPE_COPY_SEND, 3, -+ ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, -+ default_ints, INIT_INT_MAX, -+ NULL, 0, NULL, 0); -+ if (!err) -+ break; -+ -+ error (0, err, "%s", prog); -+ } -+ -+ printf ("File name for server %s (or nothing to reboot): ", server); -+ if (getstring (buf, sizeof (buf))) -+ prog = buf; -+ else -+ crash_system (); -+ } -+ -+#if 0 -+ printf ("started %s\n", prog); -+ fflush (stdout); -+#endif -+ -+ /* Dead-name notification on the task port will tell us when it dies, -+ so we can crash if we don't make it to a fully bootstrapped Hurd. */ -+ request_dead_name (*task); -+} -+ -+/* Run FILENAME as root with ARGS as its argv (length ARGLEN). Return -+ the task that we started. If CTTY is set, then make that the -+ controlling terminal of the new process and put it in its own login -+ collection. If SETSID is set, put it in a new session. Return -+ 0 if the task was not created successfully. */ -+pid_t -+run_for_real (char *filename, char *args, int arglen, mach_port_t ctty, -+ int setsid) -+{ -+ file_t file; -+ error_t err; -+ task_t task; -+ char *progname; -+ int pid; -+ -+#if 0 -+ char buf[512]; -+ do -+ { -+ printf ("File name [%s]: ", filename); -+ if (getstring (buf, sizeof (buf)) && *buf) -+ filename = buf; -+ file = file_name_lookup (filename, O_EXEC, 0); -+ if (file == MACH_PORT_NULL) -+ error (0, errno, "%s", filename); -+ } -+ while (file == MACH_PORT_NULL); -+#else -+ file = file_name_lookup (filename, O_EXEC, 0); -+ if (file == MACH_PORT_NULL) -+ { -+ error (0, errno, "%s", filename); -+ return 0; -+ } -+#endif -+ -+ task_create (mach_task_self (), -+#ifdef KERN_INVALID_LEDGER -+ NULL, 0, /* OSF Mach */ -+#endif -+ 0, &task); -+ proc_child (procserver, task); -+ proc_task2pid (procserver, task, &pid); -+ proc_task2proc (procserver, task, &default_ports[INIT_PORT_PROC]); -+ proc_mark_exec (default_ports[INIT_PORT_PROC]); -+ if (setsid) -+ proc_setsid (default_ports[INIT_PORT_PROC]); -+ if (ctty != MACH_PORT_NULL) -+ { -+ term_getctty (ctty, &default_ports[INIT_PORT_CTTYID]); -+ io_mod_owner (ctty, -pid); -+ proc_make_login_coll (default_ports[INIT_PORT_PROC]); -+ } -+ if (bootstrap_args & RB_KDB) -+ { -+ printf ("Pausing for %s\n", filename); -+ getchar (); -+ } -+ progname = strrchr (filename, '/'); -+ if (progname) -+ ++progname; -+ else -+ progname = filename; -+ err = file_exec (file, task, 0, -+ args, arglen, -+ startup_envz, startup_envz_len, -+ default_dtable, MACH_MSG_TYPE_COPY_SEND, 3, -+ default_ports, MACH_MSG_TYPE_COPY_SEND, -+ INIT_PORT_MAX, -+ default_ints, INIT_INT_MAX, -+ NULL, 0, NULL, 0); -+ mach_port_deallocate (mach_task_self (), default_ports[INIT_PORT_PROC]); -+ mach_port_deallocate (mach_task_self (), task); -+ if (ctty != MACH_PORT_NULL) -+ { -+ mach_port_deallocate (mach_task_self (), -+ default_ports[INIT_PORT_CTTYID]); -+ default_ports[INIT_PORT_CTTYID] = MACH_PORT_NULL; -+ } -+ mach_port_deallocate (mach_task_self (), file); -+ if (err) -+ { -+ error (0, err, "Cannot execute %s", filename); -+ return 0; -+ } -+ return pid; -+} -+ -+ -+/** Main program and setup **/ -+ -+static int -+demuxer (mach_msg_header_t *inp, -+ mach_msg_header_t *outp) -+{ -+ extern int notify_server (), startup_server (), msg_server (); -+ -+ return (notify_server (inp, outp) || -+ msg_server (inp, outp) || -+ startup_server (inp, outp)); -+} -+ -+static int -+parse_opt (int key, char *arg, struct argp_state *state) -+{ -+ switch (key) -+ { -+ case 'q': bootstrap_args |= RB_ASKNAME; break; -+ case 's': bootstrap_args |= RB_SINGLE; break; -+ case 'd': bootstrap_args |= RB_KDB; break; -+ case 'n': bootstrap_args |= RB_INITNAME; break; -+ case 'f': fakeboot = 1; break; -+ case 'H': crash_flags = RB_DEBUGGER; break; -+ case 'x': /* NOP */ break; -+ default: return ARGP_ERR_UNKNOWN; -+ } -+ return 0; -+} -+ -+int -+main (int argc, char **argv, char **envp) -+{ -+ volatile int err; -+ int i; -+ int flags; -+ mach_port_t consdev; -+ struct argp argp = { options, parse_opt, 0, doc }; -+ -+ /* Parse the arguments. We don't want the vector reordered, we -+ should pass on to our child the exact arguments we got and just -+ ignore any arguments that aren't flags for us. ARGP_NO_ERRS -+ suppresses --help and --version, so we only use that option if we -+ are booting. */ -+ flags = ARGP_IN_ORDER; -+ if (getpid () == 0) -+ flags |= ARGP_NO_ERRS; -+ argp_parse (&argp, argc, argv, flags, 0, 0); -+ -+ if (getpid () > 0) -+ error (2, 0, "can only be run by bootstrap filesystem"); -+ -+ global_argv = argv; -+ -+ /* Fetch a port to the bootstrap filesystem, the host priv and -+ master device ports, and the console. */ -+ if (task_get_bootstrap_port (mach_task_self (), &bootport) -+ || fsys_getpriv (bootport, &host_priv, &device_master, &fstask) -+ || device_open (device_master, D_WRITE, "console", &consdev)) -+ crash_mach (); -+ -+ wire_task_self (); -+ -+ /* Clear our bootstrap port so our children don't inherit it. */ -+ task_set_bootstrap_port (mach_task_self (), MACH_PORT_NULL); -+ -+ stderr = stdout = mach_open_devstream (consdev, "w"); -+ stdin = mach_open_devstream (consdev, "r"); -+ if (stdout == NULL || stdin == NULL) -+ crash_mach (); -+ setbuf (stdout, NULL); -+ -+ err = argz_create (envp, &startup_envz, &startup_envz_len); -+ assert_perror (err); -+ -+ /* At this point we can use assert to check for errors. */ -+ err = mach_port_allocate (mach_task_self (), -+ MACH_PORT_RIGHT_RECEIVE, &startup); -+ assert_perror (err); -+ err = mach_port_insert_right (mach_task_self (), startup, startup, -+ MACH_MSG_TYPE_MAKE_SEND); -+ assert_perror (err); -+ -+ /* Crash if the boot filesystem task dies. */ -+ request_dead_name (fstask); -+ -+ /* Set up the set of ports we will pass to the programs we exec. */ -+ for (i = 0; i < INIT_PORT_MAX; i++) -+ switch (i) -+ { -+ case INIT_PORT_CRDIR: -+ default_ports[i] = getcrdir (); -+ break; -+ case INIT_PORT_CWDIR: -+ default_ports[i] = getcwdir (); -+ break; -+ default: -+ default_ports[i] = MACH_PORT_NULL; -+ break; -+ } -+ -+ default_dtable[0] = getdport (0); -+ default_dtable[1] = getdport (1); -+ default_dtable[2] = getdport (2); -+ -+ /* All programs we start should ignore job control stop signals. -+ That way Posix.1 B.2.2.2 is satisfied where it says that programs -+ not run under job control shells are protected. */ -+ default_ints[INIT_SIGIGN] = (sigmask (SIGTSTP) -+ | sigmask (SIGTTIN) -+ | sigmask (SIGTTOU)); -+ -+ default_ports[INIT_PORT_BOOTSTRAP] = startup; -+ run ("/hurd/proc", default_ports, &proctask); -+ printf (" proc"); -+ fflush (stdout); -+ run ("/hurd/auth", default_ports, &authtask); -+ printf (" auth"); -+ fflush (stdout); -+ default_ports[INIT_PORT_BOOTSTRAP] = MACH_PORT_NULL; -+ -+ /* Wait for messages. When both auth and proc have started, we -+ run launch_system which does the rest of the boot. */ -+ while (1) -+ { -+ err = mach_msg_server (demuxer, 0, startup); -+ assert_perror (err); -+ } -+} -+ -+void -+launch_core_servers (void) -+{ -+ mach_port_t old; -+ mach_port_t authproc, fsproc, procproc; -+ error_t err; -+ -+ /* Reply to the proc and auth servers. */ -+ startup_procinit_reply (procreply, procreplytype, 0, -+ mach_task_self (), authserver, -+ host_priv, MACH_MSG_TYPE_COPY_SEND, -+ device_master, MACH_MSG_TYPE_COPY_SEND); -+ if (!fakeboot) -+ { -+ mach_port_deallocate (mach_task_self (), device_master); -+ device_master = 0; -+ } -+ -+ /* Mark us as important. */ -+ proc_mark_important (procserver); -+ proc_mark_exec (procserver); -+ -+ /* Declare that the filesystem and auth are our children. */ -+ proc_child (procserver, fstask); -+ proc_child (procserver, authtask); -+ -+ proc_task2proc (procserver, authtask, &authproc); -+ proc_mark_important (authproc); -+ proc_mark_exec (authproc); -+ startup_authinit_reply (authreply, authreplytype, 0, authproc, -+ MACH_MSG_TYPE_COPY_SEND); -+ mach_port_deallocate (mach_task_self (), authproc); -+ -+ /* Give the library our auth and proc server ports. */ -+ _hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], authserver); -+ _hurd_port_set (&_hurd_ports[INIT_PORT_PROC], procserver); -+ -+ /* Do NOT run _hurd_proc_init! That will start signals, which we do not -+ want. We listen to our own message port. Tell the proc server where -+ our args and environment are. */ -+ proc_set_arg_locations (procserver, -+ (vm_address_t) global_argv, (vm_address_t) environ); -+ -+ default_ports[INIT_PORT_AUTH] = authserver; -+ -+ /* Declare that the proc server is our child. */ -+ proc_child (procserver, proctask); -+ err = proc_task2proc (procserver, proctask, &procproc); -+ if (!err) -+ { -+ proc_mark_important (procproc); -+ proc_mark_exec (procproc); -+ mach_port_deallocate (mach_task_self (), procproc); -+ } -+ -+ proc_register_version (procserver, host_priv, "init", "", HURD_VERSION); -+ -+ /* Get the bootstrap filesystem's proc server port. -+ We must do this before calling proc_setmsgport below. */ -+ proc_task2proc (procserver, fstask, &fsproc); -+ proc_mark_important (fsproc); -+ proc_mark_exec (fsproc); -+ -+#if 0 -+ printf ("Init has completed.\n"); -+ fflush (stdout); -+#endif -+ printf (".\n"); -+ fflush (stdout); -+ -+ /* Tell the proc server our msgport. Be sure to do this after we are all -+ done making requests of proc. Once we have done this RPC, proc -+ assumes it can send us requests, so we cannot block on proc again -+ before accepting more RPC requests! However, we must do this before -+ calling fsys_init, because fsys_init blocks on exec_init, and -+ exec_init will block waiting on our message port. */ -+ proc_setmsgport (procserver, startup, &old); -+ if (old != MACH_PORT_NULL) -+ mach_port_deallocate (mach_task_self (), old); -+ -+ /* Give the bootstrap FS its proc and auth ports. */ -+ err = fsys_init (bootport, fsproc, MACH_MSG_TYPE_COPY_SEND, authserver); -+ mach_port_deallocate (mach_task_self (), fsproc); -+ if (err) -+ error (0, err, "fsys_init"); /* Not necessarily fatal. */ -+} -+ -+/* Set up the initial value of the standard exec data. */ -+void -+init_stdarrays () -+{ -+ auth_t nullauth; -+ mach_port_t pt; -+ mach_port_t ref; -+ mach_port_t *std_port_array; -+ int *std_int_array; -+ int i; -+ -+ std_port_array = alloca (sizeof (mach_port_t) * INIT_PORT_MAX); -+ std_int_array = alloca (sizeof (int) * INIT_INT_MAX); -+ -+ bzero (std_port_array, sizeof (mach_port_t) * INIT_PORT_MAX); -+ bzero (std_int_array, sizeof (int) * INIT_INT_MAX); -+ -+ __USEPORT (AUTH, auth_makeauth (port, 0, MACH_MSG_TYPE_COPY_SEND, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, &nullauth)); -+ -+ /* MAKE_SEND is safe in these transactions because we destroy REF -+ ourselves each time. */ -+ pt = getcwdir (); -+ ref = mach_reply_port (); -+ io_reauthenticate (pt, ref, MACH_MSG_TYPE_MAKE_SEND); -+ auth_user_authenticate (nullauth, ref, MACH_MSG_TYPE_MAKE_SEND, -+ &std_port_array[INIT_PORT_CWDIR]); -+ mach_port_destroy (mach_task_self (), ref); -+ mach_port_deallocate (mach_task_self (), pt); -+ -+ pt = getcrdir (); -+ ref = mach_reply_port (); -+ io_reauthenticate (pt, ref, MACH_MSG_TYPE_MAKE_SEND); -+ auth_user_authenticate (nullauth, ref, MACH_MSG_TYPE_MAKE_SEND, -+ &std_port_array[INIT_PORT_CRDIR]); -+ mach_port_destroy (mach_task_self (), ref); -+ mach_port_deallocate (mach_task_self (), pt); -+ -+ std_port_array[INIT_PORT_AUTH] = nullauth; -+ -+ std_int_array[INIT_UMASK] = CMASK; -+ -+ __USEPORT (PROC, proc_setexecdata (port, std_port_array, -+ MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, -+ std_int_array, INIT_INT_MAX)); -+ for (i = 0; i < INIT_PORT_MAX; i++) -+ mach_port_deallocate (mach_task_self (), std_port_array[i]); -+} -+ -+/* Frobnicate the kernel task and the proc server's idea of it (PID 2), -+ so the kernel command line can be read as for a normal Hurd process. */ -+ -+void -+frob_kernel_process (void) -+{ -+ error_t err; -+ int argc, i; -+ char *argz, *entry; -+ size_t argzlen; -+ size_t windowsz; -+ vm_address_t mine, his; -+ task_t task; -+ process_t proc, kbs; -+ -+ err = proc_pid2task (procserver, HURD_PID_KERNEL, &task); -+ if (err) -+ { -+ error (0, err, "cannot get kernel task port"); -+ return; -+ } -+ err = proc_task2proc (procserver, task, &proc); -+ if (err) -+ { -+ error (0, err, "cannot get kernel task's proc server port"); -+ mach_port_deallocate (mach_task_self (), task); -+ return; -+ } -+ -+ /* Mark the kernel task as an essential task so that we or the proc server -+ never want to task_terminate it. */ -+ proc_mark_important (proc); -+ -+ err = record_essential_task ("kernel", task); -+ assert_perror (err); -+ -+ err = task_get_bootstrap_port (task, &kbs); -+ assert_perror (err); -+ if (kbs == MACH_PORT_NULL) -+ { -+ /* The kernel task has no bootstrap port set, so we are presumably -+ the first Hurd to boot. Install the kernel task's proc port from -+ this Hurd's proc server as the task bootstrap port. Additional -+ Hurds will see this. */ -+ -+ err = task_set_bootstrap_port (task, proc); -+ if (err) -+ error (0, err, "cannot set kernel task's bootstrap port"); -+ -+ if (fakeboot) -+ error (0, 0, "warning: --fake-boot specified but I see no other Hurd"); -+ } -+ else -+ { -+ /* The kernel task has a bootstrap port set. Perhaps it is its proc -+ server port from another Hurd. If so, propagate the kernel -+ argument locations from that Hurd rather than diddling with the -+ kernel task ourselves. */ -+ -+ vm_address_t kargv, kenvp; -+ err = proc_get_arg_locations (kbs, &kargv, &kenvp); -+ mach_port_deallocate (mach_task_self (), kbs); -+ if (err) -+ error (0, err, "kernel task bootstrap port (ignoring)"); -+ else -+ { -+ err = proc_set_arg_locations (proc, kargv, kenvp); -+ if (err) -+ error (0, err, "cannot propagate original kernel command line"); -+ else -+ { -+ mach_port_deallocate (mach_task_self (), proc); -+ mach_port_deallocate (mach_task_self (), task); -+ if (! fakeboot) -+ error (0, 0, "warning: " -+ "I see another Hurd, but --fake-boot was not given"); -+ return; -+ } -+ } -+ } -+ -+ /* Our arguments make up the multiboot command line used to boot the -+ kernel. We'll write into the kernel task a page containing a -+ canonical argv array and argz of those words. */ -+ -+ err = argz_create (&global_argv[1], &argz, &argzlen); -+ assert_perror (err); -+ argc = argz_count (argz, argzlen); -+ -+ windowsz = round_page (((argc + 1) * sizeof (char *)) + argzlen); -+ -+ mine = (vm_address_t) mmap (0, windowsz, PROT_READ|PROT_WRITE, -+ MAP_ANON, 0, 0); -+ assert (mine != -1); -+ err = vm_allocate (task, &his, windowsz, 1); -+ if (err) -+ { -+ error (0, err, "cannot allocate %Zu bytes in kernel task", windowsz); -+ free (argz); -+ mach_port_deallocate (mach_task_self (), proc); -+ mach_port_deallocate (mach_task_self (), task); -+ munmap ((caddr_t) mine, windowsz); -+ return; -+ } -+ -+ for (i = 0, entry = argz; entry != NULL; -+ ++i, entry = argz_next (argz, argzlen, entry)) -+ ((char **) mine)[i] = ((char *) &((char **) his)[argc + 1] -+ + (entry - argz)); -+ ((char **) mine)[argc] = NULL; -+ memcpy (&((char **) mine)[argc + 1], argz, argzlen); -+ -+ free (argz); -+ -+ /* We have the data all set up in our copy, now just write it over. */ -+ err = vm_write (task, his, mine, windowsz); -+ mach_port_deallocate (mach_task_self (), task); -+ munmap ((caddr_t) mine, windowsz); -+ if (err) -+ { -+ error (0, err, "cannot write command line into kernel task"); -+ return; -+ } -+ -+ /* The argument vector is set up in the kernel task at address HIS. -+ Finally, we can inform the proc server where to find it. */ -+ err = proc_set_arg_locations (proc, his, his + (argc * sizeof (char *))); -+ mach_port_deallocate (mach_task_self (), proc); -+ if (err) -+ error (0, err, "proc_set_arg_locations for kernel task"); -+} -+ -+/** Running userland. **/ -+ -+/* In the "split-init" setup, we just run a single program (usually -+ /libexec/runsystem) that is not expected to ever exit (or stop). -+ If it does exit (or can't be started), we go to an emergency single-user -+ shell as a fallback. */ -+ -+ -+static pid_t child_pid; /* PID of the child we run */ -+static task_t child_task; /* and its (original) task port */ -+ -+error_t send_signal (mach_port_t msgport, int signal, mach_port_t refport, -+ mach_msg_timeout_t); -+ -+static void launch_something (const char *why); -+ -+ -+/* SIGNO has arrived and has been validated. Do whatever work it -+ implies. */ -+void -+process_signal (int signo) -+{ -+ if (signo == SIGCHLD) -+ { -+ /* A child died. Find its status. */ -+ int status; -+ pid_t pid; -+ -+ while (1) -+ { -+ pid = waitpid (WAIT_ANY, &status, WNOHANG | WUNTRACED); -+ if (pid <= 0) -+ break; /* No more children. */ -+ -+ /* Since we are init, orphaned processes get reparented to us and -+ alas, all our adopted children eventually die. Woe is us. We -+ just need to reap the zombies to relieve the proc server of -+ its burden, and then we can forget about the little varmints. */ -+ -+ if (pid == child_pid) -+ { -+ /* The big magilla bit the dust. */ -+ -+ char *desc = 0; -+ -+ mach_port_deallocate (mach_task_self (), child_task); -+ child_task = MACH_PORT_NULL; -+ child_pid = -1; -+ -+ if (WIFSIGNALED (status)) -+ asprintf (&desc, "terminated abnormally (%s)", -+ strsignal (WTERMSIG (status))); -+ else if (WIFSTOPPED (status)) -+ asprintf (&desc, "stopped abnormally (%s)", -+ strsignal (WTERMSIG (status))); -+ else if (WEXITSTATUS (status) == 0) -+ desc = strdup ("finished"); -+ else -+ asprintf (&desc, "exited with status %d", -+ WEXITSTATUS (status)); -+ -+ { -+ char buf[40]; -+ snprintf (buf, sizeof buf, "%d", status); -+ setenv ("STATUS", buf, 1); -+ } -+ -+ launch_something (desc); -+ free (desc); -+ } -+ } -+ } -+ else -+ { -+ /* Pass the signal on to the child. */ -+ task_t task; -+ error_t err; -+ -+ err = proc_pid2task (procserver, child_pid, &task); -+ if (err) -+ { -+ error (0, err, "proc_pid2task on %d", child_pid); -+ task = child_task; -+ } -+ else -+ { -+ mach_port_deallocate (mach_task_self (), child_task); -+ child_task = task; -+ } -+ -+ if (signo == SIGKILL) -+ { -+ err = task_terminate (task); -+ if (err != MACH_SEND_INVALID_DEST) -+ error (0, err, "task_terminate"); -+ } -+ else -+ { -+ mach_port_t msgport; -+ err = proc_getmsgport (procserver, child_pid, &msgport); -+ if (err) -+ error (0, err, "proc_getmsgport"); -+ else -+ { -+ err = send_signal (msgport, signo, task, -+ 500); /* Block only half a second. */ -+ mach_port_deallocate (mach_task_self (), msgport); -+ if (err) -+ { -+ error (0, err, "cannot send %s to child %d", -+ strsignal (signo), child_pid); -+ err = task_terminate (task); -+ if (err != MACH_SEND_INVALID_DEST) -+ error (0, err, "task_terminate"); -+ } -+ } -+ } -+ } -+} -+ -+/* Start the child program PROG. It is run via /libexec/console-run -+ with the given additional arguments. */ -+static int -+start_child (const char *prog, char **progargs) -+{ -+ file_t file; -+ error_t err; -+ char *args; -+ size_t arglen; -+ -+ if (progargs == 0) -+ { -+ const char *argv[] = { "/libexec/console-run", prog, 0 }; -+ err = argz_create ((char **) argv, &args, &arglen); -+ } -+ else -+ { -+ int argc = 0; -+ while (progargs[argc] != 0) -+ ++argc; -+ { -+ const char *argv[2 + argc + 1]; -+ argv[0] = "/libexec/console-run"; -+ argv[1] = prog; -+ argv[2 + argc] = 0; -+ while (argc-- > 0) -+ argv[2 + argc] = progargs[argc]; -+ err = argz_create ((char **) argv, &args, &arglen); -+ } -+ } -+ assert_perror (err); -+ -+ file = file_name_lookup (args, O_EXEC, 0); -+ if (file == MACH_PORT_NULL) -+ { -+ error (0, errno, "%s", args); -+ free (args); -+ return -1; -+ } -+ -+ task_create (mach_task_self (), -+#ifdef KERN_INVALID_LEDGER -+ NULL, 0, /* OSF Mach */ -+#endif -+ 0, &child_task); -+ proc_set_init_task (procserver, child_task); -+ proc_task2pid (procserver, child_task, &child_pid); -+ proc_task2proc (procserver, child_task, &default_ports[INIT_PORT_PROC]); -+ -+ if (bootstrap_args & RB_KDB) -+ { -+ printf ("Pausing for %s\n", args); -+ getchar (); -+ } -+ -+ err = file_exec (file, child_task, 0, -+ args, arglen, -+ startup_envz, startup_envz_len, -+ NULL, MACH_MSG_TYPE_COPY_SEND, 0, /* No fds. */ -+ default_ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, -+ default_ints, INIT_INT_MAX, -+ NULL, 0, NULL, 0); -+ proc_mark_important (default_ports[INIT_PORT_PROC]); -+ mach_port_deallocate (mach_task_self (), default_ports[INIT_PORT_PROC]); -+ mach_port_deallocate (mach_task_self (), file); -+ if (err) -+ { -+ error (0, err, "Cannot execute %s", args); -+ free (args); -+ return -1; -+ } -+ free (args); -+ return 0; -+} -+ -+static void -+launch_something (const char *why) -+{ -+ file_t something; -+ static unsigned int try; -+ static const char *const tries[] = -+ { -+ "/libexec/runsystem", -+ _PATH_BSHELL, -+ "/bin/shd", /* XXX */ -+ }; -+ -+ if (why) -+ error (0, 0, "%s %s", tries[try - 1], why); -+ -+ something = file_name_lookup (tries[try], O_EXEC, 0); -+ if (something != MACH_PORT_NULL) -+ { -+ mach_port_deallocate (mach_task_self (), something); -+ if (try == 0 && start_child (tries[try++], &global_argv[1]) == 0) -+ return; -+ } -+ else -+ try++; -+ -+ while (try < sizeof tries / sizeof tries[0]) -+ { -+ something = file_name_lookup (tries[try], O_EXEC, 0); -+ if (something != MACH_PORT_NULL) -+ { -+ mach_port_deallocate (mach_task_self (), something); -+ if (start_child (tries[try++], NULL) == 0) -+ return; -+ } -+ } -+ -+ crash_system (); -+} -+ -+void -+launch_system (void) -+{ -+ launch_something (0); -+} -+ -+/** RPC servers **/ -+ -+kern_return_t -+S_startup_procinit (startup_t server, -+ mach_port_t reply, -+ mach_msg_type_name_t reply_porttype, -+ process_t proc, -+ mach_port_t *startuptask, -+ auth_t *auth, -+ mach_port_t *priv, -+ mach_msg_type_name_t *hostprivtype, -+ mach_port_t *dev, -+ mach_msg_type_name_t *devtype) -+{ -+ if (procserver) -+ /* Only one proc server. */ -+ return EPERM; -+ -+ procserver = proc; -+ -+ procreply = reply; -+ procreplytype = reply_porttype; -+ -+ /* Save the reply port until we get startup_authinit. */ -+ if (authserver) -+ launch_core_servers (); -+ -+ return MIG_NO_REPLY; -+} -+ -+/* Called by the auth server when it starts up. */ -+ -+kern_return_t -+S_startup_authinit (startup_t server, -+ mach_port_t reply, -+ mach_msg_type_name_t reply_porttype, -+ mach_port_t auth, -+ mach_port_t *proc, -+ mach_msg_type_name_t *proctype) -+{ -+ if (authserver) -+ /* Only one auth server. */ -+ return EPERM; -+ -+ authserver = auth; -+ -+ /* Save the reply port until we get startup_procinit. */ -+ authreply = reply; -+ authreplytype = reply_porttype; -+ -+ if (procserver) -+ launch_core_servers (); -+ -+ return MIG_NO_REPLY; -+} -+ -+ -+kern_return_t -+S_startup_essential_task (mach_port_t server, -+ mach_port_t reply, -+ mach_msg_type_name_t replytype, -+ task_t task, -+ mach_port_t excpt, -+ char *name, -+ mach_port_t credential) -+{ -+ static int authinit, procinit, execinit; -+ int fail; -+ -+ /* Always deallocate the extra reference this message carries. */ -+ if (MACH_PORT_VALID (credential)) -+ mach_port_deallocate (mach_task_self (), credential); -+ -+ if (credential != host_priv) -+ return EPERM; -+ -+ fail = record_essential_task (name, task); -+ if (fail) -+ return fail; -+ -+ if (!booted) -+ { -+ if (!strcmp (name, "auth")) -+ authinit = 1; -+ else if (!strcmp (name, "exec")) -+ { -+ execinit = 1; -+ mach_port_t execproc; -+ proc_task2proc (procserver, task, &execproc); -+ proc_mark_important (execproc); -+ } -+ else if (!strcmp (name, "proc")) -+ procinit = 1; -+ -+ if (authinit && execinit && procinit) -+ { -+ /* Reply to this RPC, after that everything -+ is ready for real startup to begin. */ -+ startup_essential_task_reply (reply, replytype, 0); -+ -+ init_stdarrays (); -+ frob_kernel_process (); -+ -+ launch_system (); -+ -+ booted = 1; -+ -+ return MIG_NO_REPLY; -+ } -+ } -+ -+ return 0; -+} -+ -+kern_return_t -+S_startup_request_notification (mach_port_t server, -+ mach_port_t notify, -+ char *name) -+{ -+ struct ntfy_task *nt; -+ -+ request_dead_name (notify); -+ -+ /* Note that the ntfy_tasks list is kept in inverse order of the -+ calls; this is important. We need later notification requests -+ to get executed first. */ -+ nt = malloc (sizeof (struct ntfy_task)); -+ nt->notify_port = notify; -+ nt->next = ntfy_tasks; -+ ntfy_tasks = nt; -+ nt->name = malloc (strlen (name) + 1); -+ strcpy (nt->name, name); -+ return 0; -+} -+ -+kern_return_t -+do_mach_notify_dead_name (mach_port_t notify, -+ mach_port_t name) -+{ -+ struct ntfy_task *nt, *pnt; -+ struct ess_task *et; -+ -+ assert (notify == startup); -+ -+ /* Deallocate the extra reference the notification carries. */ -+ mach_port_deallocate (mach_task_self (), name); -+ -+ for (et = ess_tasks; et != NULL; et = et->next) -+ if (et->task_port == name) -+ /* An essential task has died. */ -+ { -+ error (0, 0, "Crashing system; essential task %s died", et->name); -+ crash_system (); -+ } -+ -+ for (nt = ntfy_tasks, pnt = NULL; nt != NULL; pnt = nt, nt = nt->next) -+ if (nt->notify_port == name) -+ { -+ /* Someone who wanted to be notified is gone. */ -+ mach_port_deallocate (mach_task_self (), name); -+ if (pnt != NULL) -+ pnt->next = nt->next; -+ else -+ ntfy_tasks = nt->next; -+ free (nt); -+ -+ return 0; -+ } -+ -+ if (! booted) -+ { -+ /* The system has not come up yet, so essential tasks are not yet -+ registered. But the essential servers involved in the bootstrap -+ handshake might crash before completing it, so we have requested -+ dead-name notification on those tasks. */ -+ static const struct { task_t *taskp; const char *name; } boots[] = -+ { -+ {&fstask, "bootstrap filesystem"}, -+ {&authtask, "auth"}, -+ {&proctask, "proc"}, -+ }; -+ size_t i; -+ for (i = 0; i < sizeof boots / sizeof boots[0]; ++i) -+ if (name == *boots[i].taskp) -+ { -+ error (0, 0, "Crashing system; %s server died during bootstrap", -+ boots[i].name); -+ crash_mach (); -+ } -+ error (0, 0, "BUG! Unexpected dead-name notification (name %#zx)", -+ name); -+ crash_mach (); -+ } -+ -+ return 0; -+} -+ -+kern_return_t -+S_startup_reboot (mach_port_t server, -+ mach_port_t refpt, -+ int code) -+{ -+ if (refpt != host_priv) -+ return EPERM; -+ -+ reboot_system (code); -+ for (;;); -+} -+ -+/* Stubs for unused notification RPCs. */ -+ -+kern_return_t -+do_mach_notify_port_destroyed (mach_port_t notify, -+ mach_port_t rights) -+{ -+ return EOPNOTSUPP; -+} -+ -+kern_return_t -+do_mach_notify_send_once (mach_port_t notify) -+{ -+ return EOPNOTSUPP; -+} -+ -+kern_return_t -+do_mach_notify_no_senders (mach_port_t port, mach_port_mscount_t mscount) -+{ -+ return EOPNOTSUPP; -+} -+ -+kern_return_t -+do_mach_notify_port_deleted (mach_port_t notify, -+ mach_port_t name) -+{ -+ return EOPNOTSUPP; -+} -+ -+kern_return_t -+do_mach_notify_msg_accepted (mach_port_t notify, -+ mach_port_t name) -+{ -+ return EOPNOTSUPP; -+} -+ -+/* msg server */ -+ -+kern_return_t -+S_msg_sig_post_untraced (mach_port_t msgport, -+ mach_port_t reply, mach_msg_type_name_t reply_type, -+ int signo, natural_t sigcode, mach_port_t refport) -+{ -+ if (refport != mach_task_self ()) -+ return EPERM; -+ mach_port_deallocate (mach_task_self (), refport); -+ -+ /* Reply immediately */ -+ msg_sig_post_untraced_reply (reply, reply_type, 0); -+ -+ process_signal (signo); -+ return MIG_NO_REPLY; -+} -+ -+kern_return_t -+S_msg_sig_post (mach_port_t msgport, -+ mach_port_t reply, mach_msg_type_name_t reply_type, -+ int signo, natural_t sigcode, mach_port_t refport) -+{ -+ if (refport != mach_task_self ()) -+ return EPERM; -+ mach_port_deallocate (mach_task_self (), refport); -+ -+ /* Reply immediately */ -+ msg_sig_post_reply (reply, reply_type, 0); -+ -+ process_signal (signo); -+ return MIG_NO_REPLY; -+} -+ -+ -+/* For the rest of the msg functions, just call the C library's -+ internal server stubs usually run in the signal thread. */ -+ -+kern_return_t -+S_msg_proc_newids (mach_port_t process, -+ mach_port_t task, -+ pid_t ppid, -+ pid_t pgrp, -+ int orphaned) -+{ return _S_msg_proc_newids (process, task, ppid, pgrp, orphaned); } -+ -+ -+kern_return_t -+S_msg_add_auth (mach_port_t process, -+ auth_t auth) -+{ return _S_msg_add_auth (process, auth); } -+ -+ -+kern_return_t -+S_msg_del_auth (mach_port_t process, -+ mach_port_t task, -+ intarray_t uids, -+ mach_msg_type_number_t uidsCnt, -+ intarray_t gids, -+ mach_msg_type_number_t gidsCnt) -+{ return _S_msg_del_auth (process, task, uids, uidsCnt, gids, gidsCnt); } -+ -+ -+kern_return_t -+S_msg_get_init_port (mach_port_t process, -+ mach_port_t refport, -+ int which, -+ mach_port_t *port, -+ mach_msg_type_name_t *portPoly) -+{ return _S_msg_get_init_port (process, refport, which, port, portPoly); } -+ -+ -+kern_return_t -+S_msg_set_init_port (mach_port_t process, -+ mach_port_t refport, -+ int which, -+ mach_port_t port) -+{ return _S_msg_set_init_port (process, refport, which, port); } -+ -+ -+kern_return_t -+S_msg_get_init_ports (mach_port_t process, -+ mach_port_t refport, -+ portarray_t *ports, -+ mach_msg_type_name_t *portsPoly, -+ mach_msg_type_number_t *portsCnt) -+{ return _S_msg_get_init_ports (process, refport, ports, portsPoly, portsCnt); } -+ -+ -+kern_return_t -+S_msg_set_init_ports (mach_port_t process, -+ mach_port_t refport, -+ portarray_t ports, -+ mach_msg_type_number_t portsCnt) -+{ return _S_msg_set_init_ports (process, refport, ports, portsCnt); } -+ -+ -+kern_return_t -+S_msg_get_init_int (mach_port_t process, -+ mach_port_t refport, -+ int which, -+ int *value) -+{ return _S_msg_get_init_int (process, refport, which, value); } -+ -+ -+kern_return_t -+S_msg_set_init_int (mach_port_t process, -+ mach_port_t refport, -+ int which, -+ int value) -+{ return _S_msg_set_init_int (process, refport, which, value); } -+ -+ -+kern_return_t -+S_msg_get_init_ints (mach_port_t process, -+ mach_port_t refport, -+ intarray_t *values, -+ mach_msg_type_number_t *valuesCnt) -+{ return _S_msg_get_init_ints (process, refport, values, valuesCnt); } -+ -+ -+kern_return_t -+S_msg_set_init_ints (mach_port_t process, -+ mach_port_t refport, -+ intarray_t values, -+ mach_msg_type_number_t valuesCnt) -+{ return _S_msg_set_init_ints (process, refport, values, valuesCnt); } -+ -+ -+kern_return_t -+S_msg_get_dtable (mach_port_t process, -+ mach_port_t refport, -+ portarray_t *dtable, -+ mach_msg_type_name_t *dtablePoly, -+ mach_msg_type_number_t *dtableCnt) -+{ return _S_msg_get_dtable (process, refport, dtable, dtablePoly, dtableCnt); } -+ -+ -+kern_return_t -+S_msg_set_dtable (mach_port_t process, -+ mach_port_t refport, -+ portarray_t dtable, -+ mach_msg_type_number_t dtableCnt) -+{ return _S_msg_set_dtable (process, refport, dtable, dtableCnt); } -+ -+ -+kern_return_t -+S_msg_get_fd (mach_port_t process, -+ mach_port_t refport, -+ int fd, -+ mach_port_t *port, -+ mach_msg_type_name_t *portPoly) -+{ return _S_msg_get_fd (process, refport, fd, port, portPoly); } -+ -+ -+kern_return_t -+S_msg_set_fd (mach_port_t process, -+ mach_port_t refport, -+ int fd, -+ mach_port_t port) -+{ return _S_msg_set_fd (process, refport, fd, port); } -+ -+ -+kern_return_t -+S_msg_get_environment (mach_port_t process, -+ data_t *value, -+ mach_msg_type_number_t *valueCnt) -+{ return _S_msg_get_environment (process, value, valueCnt); } -+ -+ -+kern_return_t -+S_msg_set_environment (mach_port_t process, -+ mach_port_t refport, -+ data_t value, -+ mach_msg_type_number_t valueCnt) -+{ return _S_msg_set_environment (process, refport, value, valueCnt); } -+ -+ -+kern_return_t -+S_msg_get_env_variable (mach_port_t process, -+ string_t variable, -+ data_t *value, -+ mach_msg_type_number_t *valueCnt) -+{ return _S_msg_get_env_variable (process, variable, value, valueCnt); } -+ -+ -+kern_return_t -+S_msg_set_env_variable (mach_port_t process, -+ mach_port_t refport, -+ string_t variable, -+ string_t value, -+ boolean_t replace) -+{ return _S_msg_set_env_variable (process, refport, variable, value, replace); } -+ -+error_t -+S_msg_describe_ports (mach_port_t process, -+ mach_port_t refport, -+ mach_port_array_t names, -+ mach_msg_type_number_t namesCnt, -+ data_t *descriptions, -+ mach_msg_type_number_t *descriptionsCnt) -+{ -+ return _S_msg_describe_ports (process, refport, names, namesCnt, -+ descriptions, descriptionsCnt); -+} -+ -+error_t -+S_msg_report_wait (mach_port_t process, thread_t thread, -+ string_t desc, mach_msg_id_t *rpc) -+{ -+ *desc = 0; -+ *rpc = 0; -+ return 0; -+} -diff --git a/startup/stubs.c b/startup/stubs.c -new file mode 100644 -index 0000000..5292ab6 ---- /dev/null -+++ b/startup/stubs.c -@@ -0,0 +1,139 @@ -+/* By-hand stubs for some RPC calls -+ Copyright (C) 1994,96,99,2000 Free Software Foundation, Inc. -+ -+ This program 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. -+ -+ This program 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 this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -+ -+#include <stdlib.h> -+#include <hurd/hurd_types.h> -+#include <mach.h> -+#include <string.h> -+#include <assert.h> -+ -+/* From hurd/msg.defs: */ -+#define RPCID_SIG_POST 23000 -+ -+ -+/* Send signal SIGNO to MSGPORT with REFPORT as reference. Don't -+ block in any fashion. */ -+error_t -+send_signal (mach_port_t msgport, -+ int signal, -+ mach_port_t refport, -+ mach_msg_timeout_t timeout) -+{ -+ error_t err; -+ -+ /* This message buffer might be modified by mach_msg in some error cases, -+ so we cannot safely reuse a static buffer. */ -+ struct -+ { -+ mach_msg_header_t head; -+ mach_msg_type_t signaltype; -+ int signal; -+ mach_msg_type_t sigcode_type; -+ natural_t sigcode; -+ mach_msg_type_t refporttype; -+ mach_port_t refport; -+ } -+ message = -+ { -+ { -+ /* Message header: */ -+ (MACH_MSGH_BITS_COMPLEX -+ | MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, -+ MACH_MSG_TYPE_MAKE_SEND_ONCE)), /* msgh_bits */ -+ sizeof message, /* msgh_size */ -+ msgport, /* msgh_remote_port */ -+ MACH_PORT_NULL, /* msgh_local_port */ -+ 0, /* msgh_seqno */ -+ RPCID_SIG_POST, /* msgh_id */ -+ }, -+ { -+ /* Type descriptor for signo */ -+ MACH_MSG_TYPE_INTEGER_32, /* msgt_name */ -+ 32, /* msgt_size */ -+ 1, /* msgt_number */ -+ 1, /* msgt_inline */ -+ 0, /* msgt_longform */ -+ 0, /* msgt_deallocate */ -+ 0, /* msgt_unused */ -+ }, -+ /* Signal number */ -+ signal, -+ /* Type descriptor for sigcode */ -+ { -+ MACH_MSG_TYPE_INTEGER_32, /* msgt_name */ -+ 32, /* msgt_size */ -+ 1, /* msgt_number */ -+ 1, /* msgt_inline */ -+ 0, /* msgt_longform */ -+ 0, /* msgt_deallocate */ -+ 0, /* msgt_unused */ -+ }, -+ /* Sigcode */ -+ 0, -+ { -+ /* Type descriptor for refport */ -+ MACH_MSG_TYPE_COPY_SEND, /* msgt_name */ -+ 32, /* msgt_size */ -+ 1, /* msgt_number */ -+ 1, /* msgt_inline */ -+ 0, /* msgt_longform */ -+ 0, /* msgt_deallocate */ -+ 0, /* msgt_unused */ -+ }, -+ /* Reference port */ -+ refport -+ }; -+ -+ err = mach_msg (&message.head, -+ MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof message, 0, -+ MACH_PORT_NULL, timeout, MACH_PORT_NULL); -+ -+ switch (err) -+ { -+ case MACH_SEND_TIMED_OUT: -+ /* The send could not complete in time. In this error case, the -+ kernel has modified the message buffer in a pseudo-receive -+ operation. That means our COPY_SEND refs might now be MOVE_SEND -+ refs, in which case each has gained user ref accordingly. To -+ avoid leaking those refs, we must clean up the buffer. We don't -+ use mach_msg_destroy because it assumes the local/remote ports in -+ the header have been reversed as from a real receive, while a -+ pseudo-receive leaves them as they were. */ -+ if (MACH_MSGH_BITS_REMOTE (message.head.msgh_bits) -+ == MACH_MSG_TYPE_MOVE_SEND) -+ mach_port_deallocate (mach_task_self (), -+ message.head.msgh_remote_port); -+ if (message.refporttype.msgt_name == MACH_MSG_TYPE_MOVE_SEND) -+ mach_port_deallocate (mach_task_self (), message.refport); -+ break; -+ -+ /* These are the other codes that mean a pseudo-receive modified -+ the message buffer and we might need to clean up the send rights. -+ None of them should be possible in our usage. */ -+ case MACH_SEND_INTERRUPTED: -+ case MACH_SEND_INVALID_NOTIFY: -+ case MACH_SEND_NO_NOTIFY: -+ case MACH_SEND_NOTIFY_IN_PROGRESS: -+ assert_perror (err); -+ break; -+ -+ default: /* Other errors are safe to ignore. */ -+ break; -+ } -+ -+ return err; -+} --- -2.1.0 - diff --git a/debian/patches/startup-0004-init-add-a-minimalist-init-program.patch b/debian/patches/startup-0004-init-add-a-minimalist-init-program.patch deleted file mode 100644 index 7b6af753..00000000 --- a/debian/patches/startup-0004-init-add-a-minimalist-init-program.patch +++ /dev/null @@ -1,572 +0,0 @@ -From 5551fcc6442401d72b4db5ac5f5de471f07eeb0a Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Wed, 18 Sep 2013 15:29:36 +0200 -Subject: [PATCH 4/8] init: add a minimalist init program - -This patch adds a minimalist init program. It is somewhat lacking in -features, but is able to bring up a Hurd system with the runsystem and -rc scripts. In fact, it roughly does what the former /hurd/init did, -modulo all the very early bootstrapping stuff and the startup -protocol. It is started when all the essential servers are up and -running, so it can make use of most of the POSIX goodies, making its -implementation much simpler. - -* Makefile (prog-subdirs): Add init. -* daemons/runsystem.sh: Generalize runsystem so that it can start any -init as specified on the kernel command line. By default, it starts -/hurd/init. -* daemons/runsystem.hurd: This is a verbatim copy of runsystem.sh. It -is started by /hurd/init. -* daemons/rc.sh: Do not start /hurd/mach-defpager as it is already -started in runsystem.sh. -* daemons/Makefile (SRCS): Add runsystem.hurd. -* init/Makefile: New file. -* init/init.c: Likewise. ---- - Makefile | 1 + - daemons/Makefile | 4 +- - daemons/rc.sh | 3 - - daemons/runsystem.hurd | 155 +++++++++++++++++++++++++++++++++++++++++++++++++ - daemons/runsystem.sh | 80 +++++++++---------------- - init/Makefile | 24 ++++++++ - init/init.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++ - 7 files changed, 364 insertions(+), 58 deletions(-) - create mode 100644 daemons/runsystem.hurd - create mode 100644 init/Makefile - create mode 100644 init/init.c - -diff --git a/Makefile b/Makefile -index 455df67..3178740 100644 ---- a/Makefile -+++ b/Makefile -@@ -41,6 +41,7 @@ prog-subdirs = auth proc exec term \ - random \ - procfs \ - startup \ -+ init \ - - ifeq ($(HAVE_SUN_RPC),yes) - prog-subdirs += nfs nfsd -diff --git a/daemons/Makefile b/daemons/Makefile -index d16680e..db1acc7 100644 ---- a/daemons/Makefile -+++ b/daemons/Makefile -@@ -22,7 +22,9 @@ makemode := utilities - - targets = rc getty mail.local console-run runttys runsystem - special-targets = rc runsystem --SRCS = rc.sh runsystem.sh getty.c lmail.c console-run.c runttys.c -+SRCS = rc.sh runsystem.sh getty.c lmail.c console-run.c runttys.c \ -+ runsystem.hurd \ -+ - installationdir = $(libexecdir) - - HURDLIBS = fshelp ports shouldbeinlibc -diff --git a/daemons/rc.sh b/daemons/rc.sh -index 5cf44fa..1240883 100644 ---- a/daemons/rc.sh -+++ b/daemons/rc.sh -@@ -2,9 +2,6 @@ - - PATH=/bin:/sbin - --# Start the default pager. It will bail if there is already one running. --/hurd/mach-defpager -- - # Set up swap space. This will complain if no default pager is functioning. - swapon -a - -diff --git a/daemons/runsystem.hurd b/daemons/runsystem.hurd -new file mode 100644 -index 0000000..f4f2771 ---- /dev/null -+++ b/daemons/runsystem.hurd -@@ -0,0 +1,155 @@ -+#!/bin/bash -+# -+# This program is run by /hurd/init at boot time after the essential -+# servers are up, and is responsible for running the "userland" parts of a -+# normal system. This includes running the single-user shell as well as a -+# multi-user system. This program is expected never to exit. -+# -+ -+ -+### -+### Where to find programs, etc. -+### -+ -+PATH=/bin:/sbin -+export PATH -+ -+umask 022 -+ -+# If we lose badly, try to exec each of these in turn. -+fallback_shells='/bin/sh /bin/bash /bin/csh /bin/ash /bin/shd' -+ -+# Shell used for normal single-user startup. -+SHELL=/bin/sh -+ -+# Programs that do multi-user startup. -+RUNCOM=/libexec/rc -+RUNTTYS=/libexec/runttys -+# Signals that we should pass down to runttys. -+runttys_sigs='TERM INT HUP TSTP' -+ -+### -+ -+ -+# If we get a SIGLOST, attempt to reopen the console in case -+# our console ports were revoked. This lets us print messages. -+function reopen_console () -+{ -+ exec 1>/dev/console 2>&1 || exit 3 -+} -+trap 'reopen_console' SIGLOST -+ -+ -+# Call this when we are losing badly enough that we want to punt normal -+# startup entirely. We exec a single-user shell, so we will not come back -+# here. The only way to get to multi-user from that shell will be -+# explicitly exec this script or something like that. -+function singleuser () -+{ -+ test $# -eq 0 || echo "$0: $*" -+ for try in ${fallback_shells}; do -+ SHELL=${try} -+ exec ${SHELL} -+ done -+ exit 127 -+} -+ -+ -+# See whether pflocal is set up already, and do so if not (install case) -+# -+# Normally this should be the case, but we better make sure since -+# without the pflocal server, pipe(2) does not work. -+if ! test -e /servers/socket/1 ; then -+ # The root filesystem should be read-only at this point. -+ if fsysopts / --update --writable ; then -+ settrans -c /servers/socket/1 /hurd/pflocal -+ else -+ singleuser "Failed to create /servers/socket/1." -+ fi -+fi -+ -+# We expect to be started by console-run, which gives us no arguments and -+# puts FALLBACK_CONSOLE=file-name in the environment if our console is -+# other than a normal /dev/console. -+ -+if [ "${FALLBACK_CONSOLE+set}" = set ]; then -+ singleuser "Running on fallback console ${FALLBACK_CONSOLE}" -+fi -+ -+ -+### -+### Normal startup procedures -+### -+ -+# Parse the multiboot command line. We only pay attention to -s and -f. -+# The first argument is the kernel file name; skip that. -+shift -+flags= -+while [ $# -gt 0 ]; do -+ arg="$1" -+ shift -+ case "$arg" in -+ --*) ;; -+ *=*) ;; -+ -*) -+ flags="${flags}${arg#-}" -+ ;; -+ 'single'|'emergency') # Linux compat -+ flags="${flags}s" -+ ;; -+ 'fastboot') -+ flags="${flags}f" -+ ;; -+ esac -+done -+ -+# Check boot flags. -+case "$flags" in -+*s*) -+ rc=false # force single-user -+ ;; -+*f*) -+ rc="${RUNCOM}" # fastboot -+ ;; -+*) -+ rc="${RUNCOM} autoboot" # multi-user default -+ ;; -+esac -+ -+# Large infinite loop. If this script ever exits, init considers that -+# a serious bogosity and punts to a fallback single-user shell. -+# We handle here the normal transitions between single-user and multi-user. -+while : ; do -+ -+ # Run the rc script. As long as it exits nonzero, punt to single-user. -+ # After the single-user shell exits, we will start over attempting to -+ # run rc; but later invocations strip the `autoboot' argument. -+ until $rc; do -+ rc=${RUNCOM} -+ -+ # Run single-user shell and repeat as long as it dies with a signal. -+ until ${SHELL} || test $? -lt 128; do -+ : -+ done -+ done -+ -+ # Now we are officially ready for normal multi-user operation. -+ -+ # Trap certain signals and send them on to runttys. For this to work, we -+ # must run it asynchronously and wait for it with the `wait' built-in. -+ runttys_pid=0 -+ for sig in $runttys_sigs; do -+ trap "kill -$sig \${runttys_pid}" $sig -+ done -+ -+ # This program reads /etc/ttys and starts the programs it says to. -+ ${RUNTTYS} & -+ runttys_pid=$! -+ -+ # Wait for runttys to die, meanwhile handling trapped signals. -+ wait -+ -+ # Go back to the top of the infinite loop, as if booting single-user. -+ rc=false -+ -+done -diff --git a/daemons/runsystem.sh b/daemons/runsystem.sh -index f4f2771..bd145ed 100644 ---- a/daemons/runsystem.sh -+++ b/daemons/runsystem.sh -@@ -1,9 +1,9 @@ - #!/bin/bash - # - # This program is run by /hurd/init at boot time after the essential --# servers are up, and is responsible for running the "userland" parts of a --# normal system. This includes running the single-user shell as well as a --# multi-user system. This program is expected never to exit. -+# servers are up. It does some initialization of its own and then -+# execs /hurd/init or any other roughly SysV init-compatible program -+# to bring up the "userland" parts of a normal system. - # - - -@@ -22,11 +22,10 @@ fallback_shells='/bin/sh /bin/bash /bin/csh /bin/ash /bin/shd' - # Shell used for normal single-user startup. - SHELL=/bin/sh - --# Programs that do multi-user startup. --RUNCOM=/libexec/rc --RUNTTYS=/libexec/runttys --# Signals that we should pass down to runttys. --runttys_sigs='TERM INT HUP TSTP' -+# The init program to call. -+# -+# Can be overridden using init=something in the kernel command line. -+init=/hurd/init - - ### - -@@ -44,7 +43,7 @@ trap 'reopen_console' SIGLOST - # startup entirely. We exec a single-user shell, so we will not come back - # here. The only way to get to multi-user from that shell will be - # explicitly exec this script or something like that. --function singleuser () -+function singleuser() - { - test $# -eq 0 || echo "$0: $*" - for try in ${fallback_shells}; do -@@ -54,6 +53,8 @@ function singleuser () - exit 127 - } - -+# Print a newline. -+echo - - # See whether pflocal is set up already, and do so if not (install case) - # -@@ -85,20 +86,23 @@ fi - # The first argument is the kernel file name; skip that. - shift - flags= -+single= - while [ $# -gt 0 ]; do - arg="$1" - shift - case "$arg" in - --*) ;; -+ init=*) -+ eval "${arg}" -+ ;; - *=*) ;; - -*) - flags="${flags}${arg#-}" - ;; -- 'single'|'emergency') # Linux compat -- flags="${flags}s" -+ 'single') -+ single="-s" - ;; -- 'fastboot') -- flags="${flags}f" -+ 'fastboot'|'emergency') - ;; - esac - done -@@ -106,50 +110,18 @@ done - # Check boot flags. - case "$flags" in - *s*) -- rc=false # force single-user -- ;; --*f*) -- rc="${RUNCOM}" # fastboot -- ;; --*) -- rc="${RUNCOM} autoboot" # multi-user default -+ single="-s" # force single-user - ;; - esac - --# Large infinite loop. If this script ever exits, init considers that --# a serious bogosity and punts to a fallback single-user shell. --# We handle here the normal transitions between single-user and multi-user. --while : ; do -- -- # Run the rc script. As long as it exits nonzero, punt to single-user. -- # After the single-user shell exits, we will start over attempting to -- # run rc; but later invocations strip the `autoboot' argument. -- until $rc; do -- rc=${RUNCOM} -- -- # Run single-user shell and repeat as long as it dies with a signal. -- until ${SHELL} || test $? -lt 128; do -- : -- done -- done -- -- # Now we are officially ready for normal multi-user operation. -- -- # Trap certain signals and send them on to runttys. For this to work, we -- # must run it asynchronously and wait for it with the `wait' built-in. -- runttys_pid=0 -- for sig in $runttys_sigs; do -- trap "kill -$sig \${runttys_pid}" $sig -- done -+# Start the default pager. It will bail if there is already one running. -+/hurd/mach-defpager - -- # This program reads /etc/ttys and starts the programs it says to. -- ${RUNTTYS} & -- runttys_pid=$! -+# This is necessary to make stat / return the correct device ids. -+# Work around a race condition (probably in the root translator). -+for i in `seq 1 100000` ; do : ; done - -- # Wait for runttys to die, meanwhile handling trapped signals. -- wait -+fsysopts / --update --readonly - -- # Go back to the top of the infinite loop, as if booting single-user. -- rc=false -- --done -+# Finally, start the actual init. -+exec ${init} ${single} -a -diff --git a/init/Makefile b/init/Makefile -new file mode 100644 -index 0000000..07b8026 ---- /dev/null -+++ b/init/Makefile -@@ -0,0 +1,24 @@ -+# -+# Copyright (C) 2013 Free Software Foundation, Inc. -+# -+# This program 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. -+# -+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. -+ -+dir := init -+makemode := server -+ -+SRCS = init.c -+OBJS = $(SRCS:.c=.o) -+target = init -+ -+include ../Makeconf -diff --git a/init/init.c b/init/init.c -new file mode 100644 -index 0000000..b3d3301 ---- /dev/null -+++ b/init/init.c -@@ -0,0 +1,155 @@ -+/* A minimalist init for the Hurd -+ -+ Copyright (C) 2013,14 Free Software Foundation, Inc. -+ 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 Hurd. If not, see <http://www.gnu.org/licenses/>. */ -+ -+#include <argp.h> -+#include <error.h> -+#include <hurd.h> -+#include <signal.h> -+#include <stdio.h> -+#include <string.h> -+#include <sys/types.h> -+#include <sys/wait.h> -+#include <unistd.h> -+#include <version.h> -+ -+const char *argp_program_version = STANDARD_HURD_VERSION (init); -+static pid_t child_pid; -+static int single; -+ -+static struct argp_option -+options[] = -+{ -+ /* XXX: Currently, -s does nothing. */ -+ {"single-user", 's', NULL, 0, "Startup system in single-user mode", 0}, -+ {NULL, 'a', NULL, 0, "Ignored for compatibility with sysvinit", 0}, -+ {0} -+}; -+ -+static char doc[] = "A minimalist init for the Hurd"; -+ -+static error_t -+parse_opt (int key, char *arg, struct argp_state *state) -+{ -+ switch (key) -+ { -+ case 's': -+ single = 1; -+ break; -+ -+ case 'a': -+ /* Ignored. */ -+ break; -+ -+ default: -+ return ARGP_ERR_UNKNOWN; -+ } -+ -+ return 0; -+} -+ -+void -+sigchld_handler(int signal) -+{ -+ /* A child died. Find its status. */ -+ int status; -+ pid_t pid; -+ -+ while (1) -+ { -+ pid = waitpid (WAIT_ANY, &status, WNOHANG | WUNTRACED); -+ if (pid <= 0) -+ break; /* No more children. */ -+ -+ /* Since we are init, orphaned processes get reparented to us and -+ alas, all our adopted children eventually die. Woe is us. We -+ just need to reap the zombies to relieve the proc server of -+ its burden, and then we can forget about the little varmints. */ -+ -+ if (pid == child_pid) -+ { -+ /* The big magilla bit the dust. */ -+ child_pid = -1; -+ -+ char *desc = NULL; -+ if (WIFSIGNALED (status)) -+ asprintf (&desc, "terminated abnormally (%s)", -+ strsignal (WTERMSIG (status))); -+ else if (WIFSTOPPED (status)) -+ asprintf (&desc, "stopped abnormally (%s)", -+ strsignal (WTERMSIG (status))); -+ else if (WEXITSTATUS (status) == 0) -+ desc = strdup ("finished"); -+ else -+ asprintf (&desc, "exited with status %d", -+ WEXITSTATUS (status)); -+ -+ error (0, 0, "child %s", desc); -+ free (desc); -+ -+ /* XXX: launch emergency shell. */ -+ error (23, 0, "panic!!"); -+ } -+ } -+} -+ -+int -+main (int argc, char **argv) -+{ -+ struct argp argp = -+ { -+ .options = options, -+ .parser = parse_opt, -+ .doc = doc, -+ }; -+ argp_parse (&argp, argc, argv, 0, 0, 0); -+ -+ if (getpid () != 1) -+ error (1, 0, "can only be run as PID 1"); -+ -+ struct sigaction sa; -+ sa.sa_handler = SIG_IGN; -+ sa.sa_flags = 0; -+ sigemptyset (&sa.sa_mask); -+ -+ sigaction (SIGHUP, &sa, NULL); -+ sigaction (SIGINT, &sa, NULL); -+ sigaction (SIGQUIT, &sa, NULL); -+ sigaction (SIGTERM, &sa, NULL); -+ sigaction (SIGUSR1, &sa, NULL); -+ sigaction (SIGUSR2, &sa, NULL); -+ sigaction (SIGTSTP, &sa, NULL); -+ -+ sa.sa_handler = sigchld_handler; -+ sa.sa_flags |= SA_RESTART; -+ sigaction (SIGCHLD, &sa, NULL); -+ -+ char *args[] = { "/etc/hurd/runsystem.hurd", NULL }; -+ -+ switch (child_pid = fork ()) -+ { -+ case -1: -+ error (1, errno, "failed to fork"); -+ case 0: -+ execv (args[0], args); -+ error (2, errno, "failed to execv child"); -+ } -+ -+ select (0, NULL, NULL, NULL, NULL); -+ /* Not reached. */ -+ return 0; -+} --- -2.1.0 - diff --git a/debian/patches/startup-0005-startup-do-not-pass-signals-on-to-the-child.patch b/debian/patches/startup-0005-startup-do-not-pass-signals-on-to-the-child.patch deleted file mode 100644 index 33046438..00000000 --- a/debian/patches/startup-0005-startup-do-not-pass-signals-on-to-the-child.patch +++ /dev/null @@ -1,251 +0,0 @@ -From b7eed065f9118964dc875e4f03c8b07332b44a65 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Wed, 18 Sep 2013 22:58:11 +0200 -Subject: [PATCH 5/8] startup: do not pass signals on to the child - -Formerly /hurd/startup would forward all signals to the child it -started (e.g. /libexec/runsystem). - -The motivation for doing so is not revealed in the comments, nor it is -mentioned in the history of the version control system. - -This patch removes the forwarding of signals to the child. - -* startup/startup.c (process_signal): Do not pass signals on to the child. -* startup/stubs.c: Remove file. -* startup/Makefile: Remove stubs.c. ---- - startup/Makefile | 2 +- - startup/startup.c | 49 ------------------- - startup/stubs.c | 139 ------------------------------------------------------ - 3 files changed, 1 insertion(+), 189 deletions(-) - delete mode 100644 startup/stubs.c - -diff --git a/startup/Makefile b/startup/Makefile -index 2d6b892..277fee4 100644 ---- a/startup/Makefile -+++ b/startup/Makefile -@@ -18,7 +18,7 @@ - dir := startup - makemode := server - --SRCS = startup.c stubs.c -+SRCS = startup.c - OBJS = $(SRCS:.c=.o) \ - startupServer.o notifyServer.o startup_replyUser.o msgServer.o \ - startup_notifyUser.o -diff --git a/startup/startup.c b/startup/startup.c -index 29269a6..4c91d4c 100644 ---- a/startup/startup.c -+++ b/startup/startup.c -@@ -904,9 +904,6 @@ frob_kernel_process (void) - static pid_t child_pid; /* PID of the child we run */ - static task_t child_task; /* and its (original) task port */ - --error_t send_signal (mach_port_t msgport, int signal, mach_port_t refport, -- mach_msg_timeout_t); -- - static void launch_something (const char *why); - - -@@ -965,52 +962,6 @@ process_signal (int signo) - } - } - } -- else -- { -- /* Pass the signal on to the child. */ -- task_t task; -- error_t err; -- -- err = proc_pid2task (procserver, child_pid, &task); -- if (err) -- { -- error (0, err, "proc_pid2task on %d", child_pid); -- task = child_task; -- } -- else -- { -- mach_port_deallocate (mach_task_self (), child_task); -- child_task = task; -- } -- -- if (signo == SIGKILL) -- { -- err = task_terminate (task); -- if (err != MACH_SEND_INVALID_DEST) -- error (0, err, "task_terminate"); -- } -- else -- { -- mach_port_t msgport; -- err = proc_getmsgport (procserver, child_pid, &msgport); -- if (err) -- error (0, err, "proc_getmsgport"); -- else -- { -- err = send_signal (msgport, signo, task, -- 500); /* Block only half a second. */ -- mach_port_deallocate (mach_task_self (), msgport); -- if (err) -- { -- error (0, err, "cannot send %s to child %d", -- strsignal (signo), child_pid); -- err = task_terminate (task); -- if (err != MACH_SEND_INVALID_DEST) -- error (0, err, "task_terminate"); -- } -- } -- } -- } - } - - /* Start the child program PROG. It is run via /libexec/console-run -diff --git a/startup/stubs.c b/startup/stubs.c -deleted file mode 100644 -index 5292ab6..0000000 ---- a/startup/stubs.c -+++ /dev/null -@@ -1,139 +0,0 @@ --/* By-hand stubs for some RPC calls -- Copyright (C) 1994,96,99,2000 Free Software Foundation, Inc. -- -- This program 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. -- -- This program 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 this program; if not, write to the Free Software -- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -- --#include <stdlib.h> --#include <hurd/hurd_types.h> --#include <mach.h> --#include <string.h> --#include <assert.h> -- --/* From hurd/msg.defs: */ --#define RPCID_SIG_POST 23000 -- -- --/* Send signal SIGNO to MSGPORT with REFPORT as reference. Don't -- block in any fashion. */ --error_t --send_signal (mach_port_t msgport, -- int signal, -- mach_port_t refport, -- mach_msg_timeout_t timeout) --{ -- error_t err; -- -- /* This message buffer might be modified by mach_msg in some error cases, -- so we cannot safely reuse a static buffer. */ -- struct -- { -- mach_msg_header_t head; -- mach_msg_type_t signaltype; -- int signal; -- mach_msg_type_t sigcode_type; -- natural_t sigcode; -- mach_msg_type_t refporttype; -- mach_port_t refport; -- } -- message = -- { -- { -- /* Message header: */ -- (MACH_MSGH_BITS_COMPLEX -- | MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, -- MACH_MSG_TYPE_MAKE_SEND_ONCE)), /* msgh_bits */ -- sizeof message, /* msgh_size */ -- msgport, /* msgh_remote_port */ -- MACH_PORT_NULL, /* msgh_local_port */ -- 0, /* msgh_seqno */ -- RPCID_SIG_POST, /* msgh_id */ -- }, -- { -- /* Type descriptor for signo */ -- MACH_MSG_TYPE_INTEGER_32, /* msgt_name */ -- 32, /* msgt_size */ -- 1, /* msgt_number */ -- 1, /* msgt_inline */ -- 0, /* msgt_longform */ -- 0, /* msgt_deallocate */ -- 0, /* msgt_unused */ -- }, -- /* Signal number */ -- signal, -- /* Type descriptor for sigcode */ -- { -- MACH_MSG_TYPE_INTEGER_32, /* msgt_name */ -- 32, /* msgt_size */ -- 1, /* msgt_number */ -- 1, /* msgt_inline */ -- 0, /* msgt_longform */ -- 0, /* msgt_deallocate */ -- 0, /* msgt_unused */ -- }, -- /* Sigcode */ -- 0, -- { -- /* Type descriptor for refport */ -- MACH_MSG_TYPE_COPY_SEND, /* msgt_name */ -- 32, /* msgt_size */ -- 1, /* msgt_number */ -- 1, /* msgt_inline */ -- 0, /* msgt_longform */ -- 0, /* msgt_deallocate */ -- 0, /* msgt_unused */ -- }, -- /* Reference port */ -- refport -- }; -- -- err = mach_msg (&message.head, -- MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof message, 0, -- MACH_PORT_NULL, timeout, MACH_PORT_NULL); -- -- switch (err) -- { -- case MACH_SEND_TIMED_OUT: -- /* The send could not complete in time. In this error case, the -- kernel has modified the message buffer in a pseudo-receive -- operation. That means our COPY_SEND refs might now be MOVE_SEND -- refs, in which case each has gained user ref accordingly. To -- avoid leaking those refs, we must clean up the buffer. We don't -- use mach_msg_destroy because it assumes the local/remote ports in -- the header have been reversed as from a real receive, while a -- pseudo-receive leaves them as they were. */ -- if (MACH_MSGH_BITS_REMOTE (message.head.msgh_bits) -- == MACH_MSG_TYPE_MOVE_SEND) -- mach_port_deallocate (mach_task_self (), -- message.head.msgh_remote_port); -- if (message.refporttype.msgt_name == MACH_MSG_TYPE_MOVE_SEND) -- mach_port_deallocate (mach_task_self (), message.refport); -- break; -- -- /* These are the other codes that mean a pseudo-receive modified -- the message buffer and we might need to clean up the send rights. -- None of them should be possible in our usage. */ -- case MACH_SEND_INTERRUPTED: -- case MACH_SEND_INVALID_NOTIFY: -- case MACH_SEND_NO_NOTIFY: -- case MACH_SEND_NOTIFY_IN_PROGRESS: -- assert_perror (err); -- break; -- -- default: /* Other errors are safe to ignore. */ -- break; -- } -- -- return err; --} --- -2.1.0 - diff --git a/debian/patches/startup-0006-startup-be-more-specific-in-the-shutdown-message.patch b/debian/patches/startup-0006-startup-be-more-specific-in-the-shutdown-message.patch deleted file mode 100644 index d2f9f5ce..00000000 --- a/debian/patches/startup-0006-startup-be-more-specific-in-the-shutdown-message.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 4c6541b4955425e62c2014c66bcb541c95c534db Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Wed, 18 Sep 2013 23:12:13 +0200 -Subject: [PATCH 6/8] startup: be more specific in the shutdown message - -Use the BOOT macro to print either halt or reboot instead of the -generic shutdown in the event of an system shutdown. - -* startup/startup.c (reboot_system): Use more specific message. ---- - startup/startup.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/startup/startup.c b/startup/startup.c -index 4c91d4c..0a33855 100644 ---- a/startup/startup.c -+++ b/startup/startup.c -@@ -217,7 +217,7 @@ notify_shutdown (const char *msg) - void - reboot_system (int flags) - { -- notify_shutdown ("shutdown"); -+ notify_shutdown (BOOT (flags)); - - if (fakeboot) - { --- -2.1.0 - diff --git a/debian/patches/startup-0007-startup-fix-the-declaration-of-the-_server-functions.patch b/debian/patches/startup-0007-startup-fix-the-declaration-of-the-_server-functions.patch deleted file mode 100644 index b8577c9d..00000000 --- a/debian/patches/startup-0007-startup-fix-the-declaration-of-the-_server-functions.patch +++ /dev/null @@ -1,28 +0,0 @@ -From bbdbeeba0076f31ad78849be86596528dfbeac85 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Wed, 18 Sep 2013 23:16:34 +0200 -Subject: [PATCH 7/8] startup: fix the declaration of the *_server functions - -* startup/startup.c (demuxer): Fix the declaration of the server functions. ---- - startup/startup.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/startup/startup.c b/startup/startup.c -index 0a33855..fe8471d 100644 ---- a/startup/startup.c -+++ b/startup/startup.c -@@ -501,7 +501,9 @@ static int - demuxer (mach_msg_header_t *inp, - mach_msg_header_t *outp) - { -- extern int notify_server (), startup_server (), msg_server (); -+ extern int notify_server (mach_msg_header_t *, mach_msg_header_t *); -+ extern int startup_server (mach_msg_header_t *, mach_msg_header_t *); -+ extern int msg_server (mach_msg_header_t *, mach_msg_header_t *); - - return (notify_server (inp, outp) || - msg_server (inp, outp) || --- -2.1.0 - diff --git a/debian/patches/startup-0008-startup-bind-the-startup-server-to-servers-startup.patch b/debian/patches/startup-0008-startup-bind-the-startup-server-to-servers-startup.patch deleted file mode 100644 index d3633eb0..00000000 --- a/debian/patches/startup-0008-startup-bind-the-startup-server-to-servers-startup.patch +++ /dev/null @@ -1,344 +0,0 @@ -From ccce2ecc7426fc65d05db387b5d8390644c17dc5 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Thu, 19 Sep 2013 09:15:02 +0200 -Subject: [PATCH 8/8] startup: bind the startup server to /servers/startup - -Previously, the Hurd (ab)used the fact that the startup server speaks -all protocols on its message port. Any server that wished to register -for shutdown notifications would use XXX to get a port to the startup -server. - -This hardcodes the PID of /hurd/startup, and does not allow one to -point a server to ones own startup server (e.g. using remap). - -Bind the startup server to /servers/startup instead. Use this to -contact the startup server. - -* exec/main.c (S_exec_init): Use /servers/startup. Fall back to the -old method so that the system still boots when the node -/servers/startup is missing. -* hurd/paths.h (_SERVERS_STARTUP): New macro. -* libdiskfs/boot-start.c (diskfs_S_fsys_init): Use /servers/startup. -* libdiskfs/init-startup.c (_diskfs_init_completed): Likewise. -* pfinet/main.c (arrange_shutdown_notification): Likewise. -* startup/Makefile (OBJS): Add fsysServer.o. -* startup/startup.c (demuxer): Handle the fsys protocol. -(main): Bind to /servers/startup. -(S_fsys_getroot): Implement fsys_getroot. Stub out the rest. ---- - exec/main.c | 11 ++++- - hurd/paths.h | 1 + - libdiskfs/boot-start.c | 9 ++-- - libdiskfs/init-startup.c | 13 ++++-- - pfinet/main.c | 12 ++--- - startup/Makefile | 2 +- - startup/startup.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++ - 7 files changed, 146 insertions(+), 21 deletions(-) - -diff --git a/exec/main.c b/exec/main.c -index 78faebd..664f150 100644 ---- a/exec/main.c -+++ b/exec/main.c -@@ -251,8 +251,15 @@ S_exec_init (struct trivfs_protid *protid, - - proc_register_version (procserver, host_priv, "exec", "", HURD_VERSION); - -- err = proc_getmsgport (procserver, HURD_PID_STARTUP, &startup); -- assert_perror (err); -+ startup = file_name_lookup (_SERVERS_STARTUP, 0, 0); -+ if (startup == MACH_PORT_NULL) -+ { -+ error (0, errno, "%s", _SERVERS_STARTUP); -+ -+ /* Fall back to abusing the message port lookup. */ -+ err = proc_getmsgport (procserver, HURD_PID_STARTUP, &startup); -+ assert_perror (err); -+ } - mach_port_deallocate (mach_task_self (), procserver); - - /* Call startup_essential task last; init assumes we are ready to -diff --git a/hurd/paths.h b/hurd/paths.h -index 489da57..568e45f 100644 ---- a/hurd/paths.h -+++ b/hurd/paths.h -@@ -26,6 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - #define _SERVERS "/servers/" - #define _SERVERS_CRASH _SERVERS "crash" - #define _SERVERS_EXEC _SERVERS "exec" -+#define _SERVERS_STARTUP _SERVERS "startup" - #define _SERVERS_PROC _SERVERS "proc" - #define _SERVERS_PASSWORD _SERVERS "password" - #define _SERVERS_DEFPAGER _SERVERS "default-pager" -diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c -index 42e991e..cfe2303 100644 ---- a/libdiskfs/boot-start.c -+++ b/libdiskfs/boot-start.c -@@ -33,7 +33,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include <string.h> - #include <argz.h> - #include <error.h> --#include <pids.h> - #include "exec_S.h" - #include "exec_startup_S.h" - #include "fsys_S.h" -@@ -602,9 +601,12 @@ diskfs_S_fsys_init (struct diskfs_control *pt, - - proc_register_version (procserver, host, diskfs_server_name, "", - diskfs_server_version); -+ mach_port_deallocate (mach_task_self (), procserver); - -- err = proc_getmsgport (procserver, HURD_PID_STARTUP, &startup); -- if (!err) -+ startup = file_name_lookup (_SERVERS_STARTUP, 0, 0); -+ if (startup == MACH_PORT_NULL) -+ error (0, errno, "%s", _SERVERS_STARTUP); -+ else - { - startup_essential_task (startup, mach_task_self (), MACH_PORT_NULL, - diskfs_server_name, host); -@@ -612,7 +614,6 @@ diskfs_S_fsys_init (struct diskfs_control *pt, - } - - mach_port_deallocate (mach_task_self (), host); -- mach_port_deallocate (mach_task_self (), procserver); - - _diskfs_init_completed (); - -diff --git a/libdiskfs/init-startup.c b/libdiskfs/init-startup.c -index d10c964..3a588e1 100644 ---- a/libdiskfs/init-startup.c -+++ b/libdiskfs/init-startup.c -@@ -25,8 +25,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include <fcntl.h> - #include <error.h> - #include <hurd/fsys.h> -+#include <hurd/paths.h> - #include <hurd/startup.h> --#include <pids.h> - - #include "startup_S.h" - -@@ -195,15 +195,18 @@ _diskfs_init_completed () - - /* Mark us as important. */ - err = proc_mark_important (proc); -+ mach_port_deallocate (mach_task_self (), proc); - /* This might fail due to permissions or because the old proc server - is still running, ignore any such errors. */ - if (err && err != EPERM && err != EMIG_BAD_ID) - goto errout; - -- err = proc_getmsgport (proc, HURD_PID_STARTUP, &init); -- mach_port_deallocate (mach_task_self (), proc); -- if (err) -- goto errout; -+ init = file_name_lookup (_SERVERS_STARTUP, 0, 0); -+ if (init == MACH_PORT_NULL) -+ { -+ err = errno; -+ goto errout; -+ } - - notify = ports_get_send_right (pi); - ports_port_deref (pi); -diff --git a/pfinet/main.c b/pfinet/main.c -index 5b0262f..3cd5f13 100644 ---- a/pfinet/main.c -+++ b/pfinet/main.c -@@ -24,11 +24,11 @@ - #include <arpa/inet.h> - #include <error.h> - #include <argp.h> -+#include <hurd/paths.h> - #include <hurd/startup.h> - #include <string.h> - #include <fcntl.h> - #include <version.h> --#include <pids.h> - - /* Include Hurd's errno.h file, but don't include glue-include/hurd/errno.h, - since it #undef's the errno macro. */ -@@ -154,7 +154,6 @@ arrange_shutdown_notification () - { - error_t err; - mach_port_t initport, notify; -- process_t procserver; - struct port_info *pi; - - shutdown_notify_class = ports_create_class (0, 0); -@@ -169,13 +168,8 @@ arrange_shutdown_notification () - if (err) - return; - -- procserver = getproc (); -- if (!procserver) -- return; -- -- err = proc_getmsgport (procserver, HURD_PID_STARTUP, &initport); -- mach_port_deallocate (mach_task_self (), procserver); -- if (err) -+ initport = file_name_lookup (_SERVERS_STARTUP, 0, 0); -+ if (initport == MACH_PORT_NULL) - return; - - notify = ports_get_send_right (pi); -diff --git a/startup/Makefile b/startup/Makefile -index 277fee4..23d35cb 100644 ---- a/startup/Makefile -+++ b/startup/Makefile -@@ -21,7 +21,7 @@ makemode := server - SRCS = startup.c - OBJS = $(SRCS:.c=.o) \ - startupServer.o notifyServer.o startup_replyUser.o msgServer.o \ -- startup_notifyUser.o -+ startup_notifyUser.o fsysServer.o - target = startup - HURDLIBS = shouldbeinlibc - -diff --git a/startup/startup.c b/startup/startup.c -index fe8471d..ff58270 100644 ---- a/startup/startup.c -+++ b/startup/startup.c -@@ -504,9 +504,11 @@ demuxer (mach_msg_header_t *inp, - extern int notify_server (mach_msg_header_t *, mach_msg_header_t *); - extern int startup_server (mach_msg_header_t *, mach_msg_header_t *); - extern int msg_server (mach_msg_header_t *, mach_msg_header_t *); -+ extern int fsys_server (mach_msg_header_t *, mach_msg_header_t *); - - return (notify_server (inp, outp) || - msg_server (inp, outp) || -+ fsys_server (inp, outp) || - startup_server (inp, outp)); - } - -@@ -583,6 +585,18 @@ 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) -@@ -1544,3 +1558,108 @@ S_msg_report_wait (mach_port_t process, thread_t thread, - *rpc = 0; - return 0; - } -+ -+/* fsys */ -+error_t -+S_fsys_getroot (mach_port_t fsys_t, -+ mach_port_t dotdotnode, -+ uid_t *uids, size_t nuids, -+ uid_t *gids, size_t ngids, -+ int flags, -+ retry_type *do_retry, -+ char *retry_name, -+ mach_port_t *ret, -+ mach_msg_type_name_t *rettype) -+{ -+ int is_root = 0; -+ size_t i; -+ -+ for (i = 0; i < nuids; i++) -+ if (uids[i] == 0) -+ { -+ is_root = 1; -+ break; -+ } -+ -+ if (! is_root) -+ return EPERM; -+ -+ *do_retry = FS_RETRY_NORMAL; -+ *retry_name = '\0'; -+ *ret = startup; -+ *rettype = MACH_MSG_TYPE_COPY_SEND; -+ return 0; -+} -+ -+error_t -+S_fsys_goaway (mach_port_t control, int flags) -+{ -+ return EOPNOTSUPP; -+} -+ -+error_t -+S_fsys_startup (mach_port_t bootstrap, int flags, mach_port_t control, -+ mach_port_t *real, mach_msg_type_name_t *realtype) -+{ -+ return EOPNOTSUPP; -+} -+ -+error_t -+S_fsys_syncfs (mach_port_t control, -+ int wait, -+ int recurse) -+{ -+ return EOPNOTSUPP; -+} -+ -+error_t -+S_fsys_set_options (mach_port_t control, -+ char *data, mach_msg_type_number_t len, -+ int do_children) -+{ -+ return EOPNOTSUPP; -+} -+ -+error_t -+S_fsys_get_options (mach_port_t control, -+ char **data, mach_msg_type_number_t *len) -+{ -+ return EOPNOTSUPP; -+} -+ -+error_t -+S_fsys_getfile (mach_port_t control, -+ uid_t *uids, size_t nuids, -+ uid_t *gids, size_t ngids, -+ char *handle, size_t handllen, -+ mach_port_t *pt, -+ mach_msg_type_name_t *pttype) -+{ -+ return EOPNOTSUPP; -+} -+ -+error_t -+S_fsys_getpriv (mach_port_t control, -+ mach_port_t *host_priv, mach_msg_type_name_t *host_priv_type, -+ mach_port_t *dev_master, mach_msg_type_name_t *dev_master_type, -+ task_t *fs_task, mach_msg_type_name_t *fs_task_type) -+{ -+ return EOPNOTSUPP; -+} -+ -+error_t -+S_fsys_init (mach_port_t control, -+ mach_port_t reply, -+ mach_msg_type_name_t replytype, -+ mach_port_t proc, -+ auth_t auth) -+{ -+ return EOPNOTSUPP; -+} -+ -+error_t -+S_fsys_forward (mach_port_t server, mach_port_t requestor, -+ char *argz, size_t argz_len) -+{ -+ return EOPNOTSUPP; -+} --- -2.1.0 - |