commit-hurd
[Top][All Lists]
Advanced

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

[hurd] 16/64: init: add a minimalist init program


From: Samuel Thibault
Subject: [hurd] 16/64: init: add a minimalist init program
Date: Wed, 10 Dec 2014 15:17:04 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch upstream
in repository hurd.

commit 7e9c559c75901f391b4151ed6cabba74e60f80af
Author: Justus Winter <address@hidden>
Date:   Wed Sep 18 15:29:36 2013 +0200

    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.sh => runsystem.hurd} |   0
 daemons/runsystem.sh                     |  80 ++++++----------
 init/Makefile                            |  24 +++++
 init/init.c                              | 155 +++++++++++++++++++++++++++++++
 7 files changed, 209 insertions(+), 58 deletions(-)

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.sh b/daemons/runsystem.hurd
similarity index 100%
copy from daemons/runsystem.sh
copy to daemons/runsystem.hurd
diff --git a/daemons/runsystem.sh b/daemons/runsystem.sh
index f4f2771..ae25a7d 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 # XXX
 
-  # 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;
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-hurd/hurd.git



reply via email to

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