summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2016-09-10 13:29:56 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2016-09-10 13:29:56 +0000
commitdfa16e4a89158f3d3198db71e2eba3bda9330078 (patch)
treecfa8399e5348c35eae05f59aa0ea8e2e20bd14ba
parentdfc83dd740beaa46b637b87b5a804abf1cff7bee (diff)
downloads6-linux-init-dfa16e4a89158f3d3198db71e2eba3bda9330078.tar.xz
Make s6-linux-init a real init package.
This means: - removing leaky options to s6-linux-init-maker. Default initial_path is now always /usr/bin:/bin; the uid and gid of the catch-all logger (used at boot time) can now be given numerically instead of relying on the (run-time) user db mapping. - moving s6-halt, s6-poweroff and s6-reboot over here, from s6-linux-utils - clarifying on the documentation a bit.
-rw-r--r--doc/index.html6
-rw-r--r--doc/quickstart.html11
-rw-r--r--doc/s6-halt.html55
-rw-r--r--doc/s6-linux-init-maker.html110
-rw-r--r--doc/s6-poweroff.html55
-rw-r--r--doc/s6-reboot.html55
-rw-r--r--doc/upgrade.html7
-rw-r--r--package/deps.mak10
-rw-r--r--package/modes3
-rw-r--r--package/targets.mak5
-rw-r--r--src/init/deps-exe/s6-halt1
-rw-r--r--src/init/deps-exe/s6-poweroff1
-rw-r--r--src/init/deps-exe/s6-reboot1
-rw-r--r--src/init/hpr.c44
-rw-r--r--src/init/s6-halt.c7
-rw-r--r--src/init/s6-linux-init-maker.c43
-rw-r--r--src/init/s6-poweroff.c7
-rw-r--r--src/init/s6-reboot.c7
18 files changed, 359 insertions, 69 deletions
diff --git a/doc/index.html b/doc/index.html
index 47226b4..5c39b78 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -64,7 +64,8 @@ a small FAQ.
<p>
When you <em>build</em> s6-linux-init, the
<a href="s6-linux-init-maker.html">s6-linux-init-maker</a> tool
-is created; then you <em>run</em> that tool to create an init script,
+is created (as well as the shutdown commands);
+ then you <em>run</em> that tool to create an init script,
and then you can <em>boot</em> your system on that init script.
</p>
@@ -122,6 +123,9 @@ the previous versions of s6-linux-init and the current one. </li>
<ul>
<li><a href="s6-linux-init-maker.html">The <tt>s6-linux-init-maker</tt> program</a></li>
+<li><a href="s6-halt.html">The <tt>s6-halt</tt> program</a></li>
+<li><a href="s6-poweroff.html">The <tt>s6-poweroff</tt> program</a></li>
+<li><a href="s6-reboot.html">The <tt>s6-reboot</tt> program</a></li>
</ul>
<h2> Related resources </h2>
diff --git a/doc/quickstart.html b/doc/quickstart.html
index bd758b1..dac9779 100644
--- a/doc/quickstart.html
+++ b/doc/quickstart.html
@@ -20,7 +20,7 @@
<h2> Quickstart </h2>
-<ul>
+<ol>
<li> Install all the s6-linux-init dependencies:
<ul>
<li> <a href="http://skarnet.org/software/skalibs/">skalibs</a> </li>
@@ -35,6 +35,11 @@
<li> Make sure you have a <tt>/run</tt> directory </li>
<li> Write a machine initialization script in <tt>/etc/rc.init</tt> and
a machine shutdown script in <tt>/etc/rc.shutdown</tt>. Make them executable. </li>
+ <li> If, at shutdown time, you need to run a script <em>before</em> the
+supervision tree is torn down (for instance if you're using
+<a href="http://skarnet.org/software/s6-rc/">s6-rc</a> and want to
+cleanly stop all your services), write that script in
+<tt>/etc/rc.tini</tt>. </li>
<li> Check that your devtmpfs is automounted by your kernel at boot time. If it is not,
add the <tt>-d 1</tt> option to the <tt>s6-linux-init-maker</tt> command line below. </li>
<li> As root, run: <pre>
@@ -44,6 +49,10 @@ add the <tt>-d 1</tt> option to the <tt>s6-linux-init-maker</tt> command line be
ln -sf /etc/s6-linux-init/init /sbin/init </pre> </li>
<li> Reboot. </li>
<li> Congratulations! your machine is now running a s6-based init system. </li>
+ <li> To shut the machine down, use the
+<a href="s6-halt.html">s6-halt</a>,
+<a href="s6-poweroff.html">s6-poweroff</a> or
+<a href="s6-reboot.html">s6-reboot</a> command as appropriate. </li>
</ul>
<h2> FAQ </h2>
diff --git a/doc/s6-halt.html b/doc/s6-halt.html
new file mode 100644
index 0000000..b6a326c
--- /dev/null
+++ b/doc/s6-halt.html
@@ -0,0 +1,55 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-linux-init: the s6-halt program</title>
+ <meta name="Description" content="s6-linux-init: the s6-halt program" />
+ <meta name="Keywords" content="s6 linux init administration root utilities shutdown halt poweroff reboot" />
+ <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">s6-linux-init</a><br />
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>s6-halt</tt> program </h1>
+
+<p>
+<tt>s6-halt</tt> sends a signal to process 1 in order to halt the machine;
+or, with the <tt>-f</tt> option, it performs an immediate hard shutdown.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+ s6-halt [ -h | -p | -r ] [ -f ]
+</pre>
+
+<ul>
+ <li> s6-halt sends a signal to process 1. </li>
+ <li> It then exits 0. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-h</tt>&nbsp;: halt. The command will order a halt (i.e. the system will
+be shut down, but the power will remain up), which means
+sending a SIGUSR2 to process 1. This is the default. </li>
+ <li> <tt>-p</tt>&nbsp;: poweroff. The command will order a power off, which means
+sending a SIGUSR1 to process 1. </li>
+ <li> <tt>-r</tt>&nbsp;: reboot. The command will order a reboot, which means
+sending a SIGINT to process 1. </li>
+ <li> <tt>-f</tt>&nbsp;: force. The command will not send any signal to process 1;
+it will just sync the filesystems then tell the kernel to halt, poweroff or reboot.
+<tt>s6-reboot -f</tt> or <tt>s6-poweroff -f</tt> should be the last program
+executed in the lifetime of a machine, at the end of the shutdown script called
+by process 1 when it receives a signal telling it to shut down. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/s6-linux-init-maker.html b/doc/s6-linux-init-maker.html
index e82ce40..4eee9db 100644
--- a/doc/s6-linux-init-maker.html
+++ b/doc/s6-linux-init-maker.html
@@ -51,8 +51,8 @@ machine</em> - else the scripts will crash.
[ -c <em>basedir</em> ] \
[ -l <em>tmpfsdir</em> ] \
[ -b <em>execline_bindir</em> ] \
- [ -u <em>log_user</em> ] \
- [ -g <em>early_getty</em> ] \
+ [ -u <em>log_uid</em> -g <em>log_gid</em> | -U ] \
+ [ -G <em>early_getty</em> ] \
[ -2 <em>stage2</em> ] \
[ -r ] \
[ -Z ] <em>stage2_finish</em> \
@@ -173,48 +173,63 @@ real machine and service initialization should happen in <em>stage2</em>.
<h2> Shutdown sequence </h2>
-<p>
- When s6-svscan is told to exit via an appropriate
-<a href="http://skarnet.org/software/s6/s6-svscanctl.html">s6-svscanctl</a>
-command, it executes into the <em>stage3</em> script, which, like
-<em>stage2</em>, is the responsibility of the administrator. <em>stage3</em>
-is run in the following state:
-</p>
+<ul>
+
+ <li> A shutdown is performed when the administrator runs one of the
+<a href="s6-halt.html">s6-halt</a>,
+<a href="s6-poweroff.html">s6-poweroff</a> or
+<a href="s6-reboot.html">s6-reboot</a> commands. </li>
+
+ <li> Those commands send a signal to the
+<a href="http://skarnet.org/software/s6/s6-svscan.html">s6-svscan</a>
+process running as pid 1; this signal is caught and s6-svscan runs the
+corresponding "signal handler" script that has been placed by
+s6-linux-init-maker into the
+<tt><em>basedir</em>/run-image/service/.s6-svscan</tt> directory (and that
+has been copied at boot time to <tt><em>tmpfsdir</em>/service/.s6-svscan</tt>). </li>
+
+ <li> That script first spawns the <em>stage2_finish</em> script, who
+must have been written by the administrator. The purpose of
+<em>stage2_finish</em> is to perform the high-level shutdown sequence
+while the supervision tree is still alive. Typically, when using a
+service manager, <em>stage2_finish</em> would tell the service manager
+to bring all services down. When using
+<a href="http://skarnet.org/software/s6-rc/">s6-rc</a>, a typical
+<em>stage2_finish</em> script just contains <tt>s6-rc -da change</tt>.
+ More generally speaking, <em>stage2_finish</em> should undo what
+<em>stage2</em> has done at boot time. </li>
+
+ <li> The "signal handler" script then tells s6-svscan to exit via an
+appropriate <a href="http://skarnet.org/software/s6/s6-svscanctl.html">s6-svscanctl</a>
+command: s6-svscan then executes into the <em>stage3</em> script, which, like
+<em>stage2</em> and <em>stage2_finish</em>, is the responsibility of the
+administrator. When <em>stage3</em> runs, the machine is in the following
+state:
<ul>
- <li> It runs as process 1. (Doing so makes it easier to recover after
-killing all processes by <tt>kill -9 -1</tt> or
-<a href="http://skarnet.org/software/s6-portable-utils/s6-nuke.html">s6-nuke</a>). </li>
+ <li> The supervision tree has been torn down: it is not operational
+anymore. (So, commands such as
+<a href="http://skarnet.org/software/s6-rc/s6-rc.html">s6-rc</a>, which
+require a live supervision tree, will not work.)
+ <li> <em>stage3</em> runs as process 1. Doing so makes it easier to recover
+after killing all processes by <tt>kill -9 -1</tt> or
+<a href="http://skarnet.org/software/s6-portable-utils/s6-nuke.html">s6-nuke</a>. </li>
<li> Its working directory is <tt>/</tt> and its stdin is <tt>/dev/null</tt> </li>
<li> Its stdout and stderr are both <tt>/dev/console</tt> </li>
- <li> Depending on the exact s6-svscanctl command that terminated s6-svscan,
-and what has happened before that command was sent, there may or may not be
+ <li> Depending on the exact configuration and what the administrator has
+written in <em>stage2_finish</em>, there may or may not be
long-running services that remain alive. The catch-all logger and its
-supervisor will <em>always</em> be alive, which is not a problem because they
+supervisor will <em>always</em> be alive; this is not a problem because they
do not hold any file descriptor to a filesystem that would need to be
unmounted. </li>
-</ul>
+</ul> </li>
-<p>
- When s6-svscan receives a signal such as SIGINT, typically sent by the
-Ctrl-Alt-Del key combination or a <tt>reboot</tt> or <tt>poweroff</tt>
-command, it will run the corresponding script in
-<tt><em>tmpfsdir</em>/service/.s6-svscan</tt>, which will first run
-<em>stage2_finish</em>, then send an exit command to s6-svscan as
-described above. This is useful if some commands need to be run before
-s6-svscan executes into <em>stage3</em>: for instance, if the machine
-state is maintained by a service manager such as
-<a href="http://skarnet.org/software/s6-rc/">s6-rc</a>, all the
-services can be turned off in <em>stage2_finish</em> while s6-svscan
-is still alive, and then the last steps of the shutdown procedure can
-be performed in <em>stage3</em>.
-</p>
+<li> The last command that <em>stage3</em> executes should be
+<tt>s6-$1 -f</tt>, <tt>$1</tt> being the first argument that has been
+given to it. This command will instantly execute the hard system halt,
+poweroff or reboot that has initially been asked by the admin. </li>
-<p>
- Generally speaking, <em>stage2_finish</em> should undo what
-<em>stage2</em> has done at boot time, so <em>stage3</em> has very
-little work to do.
-</p>
+</ul>
<p>
The <tt>examples/</tt> subdirectory of the s6-linux-init package
@@ -251,11 +266,24 @@ launcher and the first few early commands before PATH can be set.
found. It must be absolute. Default is
<strong><tt>/bin</tt></strong>. </li> <p />
- <li> <tt>-u</tt>&nbsp;<em>log_user</em>&nbsp;: the catch-all
-logger will not run as root, but as <em>log_user</em>. Default is
-<strong><tt>nobody</tt></strong>. </li> <p />
+ <li> <tt>-u</tt>&nbsp;<em>log_uid</em>&nbsp;: the catch-all
+logger will run with the uid <em>log_uid</em>. Default is 0. <li> <p />
+
+ <li> <tt>-g</tt>&nbsp;<em>log_gid</em>&nbsp;: the catch-all
+logger will run with the gid <em>log_gid</em>. Default is 0. <li> <p />
+
+ <li> <tt>-U</tt>&nbsp;: the correct <em>log_uid</em> and
+<em>log_gid</em> values for the catch-all logger will be read from the
+UID and GID environment variables that have been passed to
+s6-linux-init-maker. This allows for invocations such as
+<tt>s6-envuidgid nobody s6-linux-init-maker -U ...</tt> so that
+the catch-all logger runs as the <tt>nobody</tt> user. Be aware that
+this option is only safe when the user database on the
+<em>boot-time</em> machine is the same as on the <em>run-time</em>
+machine, else the catch-all logger may run with an unexpected uid
+and gid. </li>
- <li> <tt>-g</tt>&nbsp;<em>early_getty</em>&nbsp;: if this option
+ <li> <tt>-G</tt>&nbsp;<em>early_getty</em>&nbsp;: if this option
is set, s6-linux-init-maker will define a service that will run
very early, before <em>stage2</em> is executed. This early service
should be a getty, to allow logins even if <em>stage2</em> fails.
@@ -297,9 +325,7 @@ absolutely necessary for
<a href="http://skarnet.org/software/s6-portable-utils/">s6-portable-utils</a> and
<a href="http://skarnet.org/software/s6-linux-utils/">s6-linux-utils</a>
binaries to be accessible via <em>initial_path</em>, else the machine
-will not boot. Default is the value that has been compiled in
-<a href="http://skarnet.org/software/skalibs/">skalibs</a> via the
-<tt>--with-default-path</tt> configure option, i.e. by default
+will not boot. Default is
<strong><tt>/usr/bin:/bin</tt></strong>. </li> <p />
<li> <tt>-m</tt>&nbsp;<em>initial_umask</em>&nbsp;: the value of
diff --git a/doc/s6-poweroff.html b/doc/s6-poweroff.html
new file mode 100644
index 0000000..9a268af
--- /dev/null
+++ b/doc/s6-poweroff.html
@@ -0,0 +1,55 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-linux-init: the s6-poweroff program</title>
+ <meta name="Description" content="s6-linux-init: the s6-poweroff program" />
+ <meta name="Keywords" content="s6 linux init administration root utilities shutdown halt poweroff reboot" />
+ <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">s6-linux-init</a><br />
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>s6-poweroff</tt> program </h1>
+
+<p>
+<tt>s6-poweroff</tt> sends a signal to process 1 in order to power off the machine;
+or, with the <tt>-f</tt> option, it performs an immediate hard shutdown.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+ s6-poweroff [ -h | -p | -r ] [ -f ]
+</pre>
+
+<ul>
+ <li> s6-poweroff sends a signal to process 1. </li>
+ <li> It then exits 0. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-h</tt>&nbsp;: halt. The command will order a halt (i.e. the system will
+be shut down, but the power will remain up), which means
+sending a SIGUSR2 to process 1. </li>
+ <li> <tt>-p</tt>&nbsp;: poweroff. The command will order a power off, which means
+sending a SIGUSR1 to process 1. This is the default. </li>
+ <li> <tt>-r</tt>&nbsp;: reboot. The command will order a reboot, which means
+sending a SIGINT to process 1. </li>
+ <li> <tt>-f</tt>&nbsp;: force. The command will not send any signal to process 1;
+it will just sync the filesystems then tell the kernel to halt, poweroff or reboot.
+<tt>s6-reboot -f</tt> or <tt>s6-poweroff -f</tt> should be the last program
+executed in the lifetime of a machine, at the end of the shutdown script called
+by process 1 when it receives a signal telling it to shut down. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/s6-reboot.html b/doc/s6-reboot.html
new file mode 100644
index 0000000..e116235
--- /dev/null
+++ b/doc/s6-reboot.html
@@ -0,0 +1,55 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>s6-linux-init: the s6-reboot program</title>
+ <meta name="Description" content="s6-linux-init: the s6-reboot program" />
+ <meta name="Keywords" content="s6 linux init administration root utilities shutdown halt poweroff reboot" />
+ <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="index.html">s6-linux-init</a><br />
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>s6-reboot</tt> program </h1>
+
+<p>
+<tt>s6-reboot</tt> sends a signal to process 1 in order to reboot the machine;
+or, with the <tt>-f</tt> option, it performs an immediate reboot.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+ s6-reboot [ -h | -p | -r ] [ -f ]
+</pre>
+
+<ul>
+ <li> s6-reboot sends a signal to process 1. </li>
+ <li> It then exits 0. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-h</tt>&nbsp;: halt. The command will order a halt (i.e. the system will
+be shut down, but the power will remain up), which means
+sending a SIGUSR2 to process 1. </li>
+ <li> <tt>-p</tt>&nbsp;: poweroff. The command will order a power off, which means
+sending a SIGUSR1 to process 1. </li>
+ <li> <tt>-r</tt>&nbsp;: reboot. The command will order a reboot, which means
+sending a SIGINT to process 1. This is the default. </li>
+ <li> <tt>-f</tt>&nbsp;: force. The command will not send any signal to process 1;
+it will just sync the filesystems then tell the kernel to halt, poweroff or reboot.
+<tt>s6-reboot -f</tt> or <tt>s6-poweroff -f</tt> should be the last program
+executed in the lifetime of a machine, at the end of the shutdown script called
+by process 1 when it receives a signal telling it to shut down. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 49dbb2e..bc2c722 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -31,6 +31,13 @@ dependency bumped to 2.1.0.0. </li>
dependency bumped to 2.2.0.0. </li>
<li> <a href="http://skarnet.org/software/s6/">s6</a>
dependency bumped to 2.4.0.0. </li>
+ <li> <a href="s6-halt.html">s6-halt</a>,
+ <a href="s6-poweroff.html">s6-poweroff</a> and
+ <a href="s6-reboot.html">s6-reboot</a> moved from
+<a href="http://skarnet.org/software/s6-linux-utils/">s6-linux-utils</a>
+to s6-linux-init. </li>
+ <li> <a href="s6-linux-init-maker.html">s6-linux-init-maker</a>
+options modified. (Read the documentation!) </li>
</ul>
<h2> in 0.1.0.0 </h2>
diff --git a/package/deps.mak b/package/deps.mak
index f1fb7db..95fbd4b 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -2,7 +2,17 @@
# This file has been generated by tools/gen-deps.sh
#
+src/init/hpr.o src/init/hpr.lo: src/init/hpr.c
+src/init/s6-halt.o src/init/s6-halt.lo: src/init/s6-halt.c
src/init/s6-linux-init-maker.o src/init/s6-linux-init-maker.lo: src/init/s6-linux-init-maker.c
+src/init/s6-poweroff.o src/init/s6-poweroff.lo: src/init/s6-poweroff.c
+src/init/s6-reboot.o src/init/s6-reboot.lo: src/init/s6-reboot.c
+s6-halt: EXTRA_LIBS :=
+s6-halt: src/init/s6-halt.o -lskarnet
s6-linux-init-maker: EXTRA_LIBS :=
s6-linux-init-maker: src/init/s6-linux-init-maker.o -lskarnet
+s6-poweroff: EXTRA_LIBS :=
+s6-poweroff: src/init/s6-poweroff.o -lskarnet
+s6-reboot: EXTRA_LIBS :=
+s6-reboot: src/init/s6-reboot.o -lskarnet
diff --git a/package/modes b/package/modes
index 4b115b4..f2fafad 100644
--- a/package/modes
+++ b/package/modes
@@ -1 +1,4 @@
s6-linux-init-maker 0700
+s6-halt 0700
+s6-poweroff 0700
+s6-reboot 0700
diff --git a/package/targets.mak b/package/targets.mak
index 2330c89..83ed8c5 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -1,6 +1,9 @@
BIN_TARGETS :=
SBIN_TARGETS := \
-s6-linux-init-maker
+s6-linux-init-maker \
+s6-halt \
+s6-poweroff \
+s6-reboot
LIBEXEC_TARGETS :=
diff --git a/src/init/deps-exe/s6-halt b/src/init/deps-exe/s6-halt
new file mode 100644
index 0000000..e7187fe
--- /dev/null
+++ b/src/init/deps-exe/s6-halt
@@ -0,0 +1 @@
+-lskarnet
diff --git a/src/init/deps-exe/s6-poweroff b/src/init/deps-exe/s6-poweroff
new file mode 100644
index 0000000..e7187fe
--- /dev/null
+++ b/src/init/deps-exe/s6-poweroff
@@ -0,0 +1 @@
+-lskarnet
diff --git a/src/init/deps-exe/s6-reboot b/src/init/deps-exe/s6-reboot
new file mode 100644
index 0000000..e7187fe
--- /dev/null
+++ b/src/init/deps-exe/s6-reboot
@@ -0,0 +1 @@
+-lskarnet
diff --git a/src/init/hpr.c b/src/init/hpr.c
new file mode 100644
index 0000000..0e1c27a
--- /dev/null
+++ b/src/init/hpr.c
@@ -0,0 +1,44 @@
+/* ISC license. */
+
+#include <unistd.h>
+#include <signal.h>
+#include <sys/reboot.h>
+#include <skalibs/strerr2.h>
+#include <skalibs/sgetopt.h>
+
+#define USAGE PROGNAME " [ -h | -p | -r ] [ -f ]"
+
+int main (int argc, char const *const *argv)
+{
+ int what = WHATDEFAULT ;
+ int force = 0 ;
+ PROG = PROGNAME ;
+
+ {
+ subgetopt_t l = SUBGETOPT_ZERO ;
+ for (;;)
+ {
+ register int opt = subgetopt_r(argc, argv, "hprf", &l) ;
+ if (opt == -1) break ;
+ switch (opt)
+ {
+ case 'h' : what = 1 ; break ;
+ case 'p' : what = 2 ; break ;
+ case 'r' : what = 3 ; break ;
+ case 'f' : force = 1 ; break ;
+ default : strerr_dieusage(100, USAGE) ;
+ }
+ }
+ argc -= l.ind ; argv += l.ind ;
+ }
+
+ if (force)
+ {
+ sync() ;
+ reboot(what == 3 ? RB_AUTOBOOT : what == 2 ? RB_POWER_OFF : RB_HALT_SYSTEM) ;
+ strerr_diefu1sys(111, "reboot()") ;
+ }
+ else if (kill(1, what == 3 ? SIGINT : what == 2 ? SIGUSR1 : SIGUSR2) < 0)
+ strerr_diefu1sys(111, "signal process 1") ;
+ return 0 ;
+}
diff --git a/src/init/s6-halt.c b/src/init/s6-halt.c
new file mode 100644
index 0000000..d758030
--- /dev/null
+++ b/src/init/s6-halt.c
@@ -0,0 +1,7 @@
+/* ISC license. */
+
+#undef PROGNAME
+#define PROGNAME "s6-halt"
+#undef WHATDEFAULT
+#define WHATDEFAULT 1
+#include "hpr.c"
diff --git a/src/init/s6-linux-init-maker.c b/src/init/s6-linux-init-maker.c
index c37b67c..60c5353 100644
--- a/src/init/s6-linux-init-maker.c
+++ b/src/init/s6-linux-init-maker.c
@@ -4,8 +4,6 @@
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
-#include <pwd.h>
-#include <skalibs/config.h>
#include <skalibs/uint64.h>
#include <skalibs/uint.h>
#include <skalibs/gidstuff.h>
@@ -13,12 +11,13 @@
#include <skalibs/allreadwrite.h>
#include <skalibs/buffer.h>
#include <skalibs/strerr2.h>
+#include <skalibs/env.h>
#include <skalibs/stralloc.h>
#include <skalibs/djbunix.h>
#include <skalibs/sgetopt.h>
#include <skalibs/skamisc.h>
-#define USAGE "s6-linux-init-maker [ -c basedir ] [ -l tmpfsdir ] [ -b execline_bindir ] [ -u log_user ] [ -g early_getty_cmd ] [ -2 stage2_script ] [ -r ] [ -Z finish_script ] [ -3 stage3_script ] [ -p initial_path ] [ -m initial_umask ] [ -t timestamp_style ] [ -d dev_style ] [ -s env_store ] [ -e initial_envvar ... ] dir"
+#define USAGE "s6-linux-init-maker [ -c basedir ] [ -l tmpfsdir ] [ -b execline_bindir ] [ -u log_uid -g log_gid | -U ] [ -G early_getty_cmd ] [ -2 stage2_script ] [ -r ] [ -Z finish_script ] [ -3 stage3_script ] [ -p initial_path ] [ -m initial_umask ] [ -t timestamp_style ] [ -d dev_style ] [ -s env_store ] [ -e initial_envvar ... ] dir"
#define dieusage() strerr_dieusage(100, USAGE)
#define dienomem() strerr_diefu1sys(111, "stralloc_catb") ;
@@ -38,11 +37,11 @@ static char const *init_script = "/etc/rc.init" ;
static char const *tini_script = "/etc/rc.tini" ;
static char const *shutdown_script = "/etc/rc.shutdown" ;
static char const *bindir = "/bin" ;
-static char const *initial_path = SKALIBS_DEFAULTPATH ;
+static char const *initial_path = "/usr/bin:/bin" ;
static char const *env_store = 0 ;
static char const *early_getty = 0 ;
-static uid_t uncaught_logs_uid ;
-static gid_t uncaught_logs_gid ;
+static uid_t uncaught_logs_uid = 0 ;
+static gid_t uncaught_logs_gid = 0 ;
static unsigned int initial_umask = 022 ;
static unsigned int timestamp_style = 1 ;
static unsigned int slashdev_style = 2 ;
@@ -356,23 +355,32 @@ static inline void make_image (char const *base)
auto_script(base, "init", &stage1_script) ;
}
-int main (int argc, char const *const *argv)
+int main (int argc, char const *const *argv, char const *const *envp)
{
- char const *catchall_user = "nobody" ;
PROG = "s6-linux-init-maker" ;
{
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- register int opt = subgetopt_r(argc, argv, "c:l:b:u:g:2:rZ:3:p:m:t:d:s:e:", &l) ;
+ register int opt = subgetopt_r(argc, argv, "c:l:b:u:g:UG:2:rZ:3:p:m:t:d:s:e:", &l) ;
if (opt == -1) break ;
switch (opt)
{
case 'c' : robase = l.arg ; break ;
case 'l' : slashrun = l.arg ; break ;
case 'b' : bindir = l.arg ; break ;
- case 'u' : catchall_user = l.arg ; break ;
- case 'g' : early_getty = l.arg ; break ;
+ case 'u' : if (!uint0_scan(l.arg, &uncaught_logs_uid)) dieusage() ; break ;
+ case 'g' : if (!uint0_scan(l.arg, &uncaught_logs_gid)) dieusage() ; break ;
+ case 'U' :
+ {
+ char const *x = env_get2(envp, "UID") ;
+ if (!x) strerr_dienotset(100, "UID") ;
+ if (!uint0_scan(x, &uncaught_logs_uid)) strerr_dieinvalid(100, "UID") ;
+ x = env_get2(envp, "GID") ;
+ if (!x) strerr_dienotset(100, "GID") ;
+ if (!uint0_scan(x, &uncaught_logs_gid)) strerr_dieinvalid(100, "GID") ;
+ }
+ case 'G' : early_getty = l.arg ; break ;
case '2' : init_script = l.arg ; break ;
case 'r' : redirect_stage2 = 1 ; break ;
case 'Z' : tini_script = l.arg ; break ;
@@ -407,19 +415,6 @@ int main (int argc, char const *const *argv)
if (slashdev_style > 2)
strerr_dief1x(100, "-d dev_style must be 0, 1 or 2") ;
- {
- struct passwd *pw = getpwnam(catchall_user) ;
- if (!pw)
- {
- if (errno)
- strerr_diefu2sys(111, "getpwnam for ", catchall_user) ;
- else
- strerr_dief3x(100, "getpwnam for ", catchall_user, ": no such user") ;
- }
- uncaught_logs_uid = pw->pw_uid ;
- uncaught_logs_gid = pw->pw_gid ;
- }
-
if (mkdir(argv[0], 0755) < 0)
strerr_diefu2sys(111, "mkdir ", argv[0]) ;
diff --git a/src/init/s6-poweroff.c b/src/init/s6-poweroff.c
new file mode 100644
index 0000000..f9f7747
--- /dev/null
+++ b/src/init/s6-poweroff.c
@@ -0,0 +1,7 @@
+/* ISC license. */
+
+#undef PROGNAME
+#define PROGNAME "s6-poweroff"
+#undef WHATDEFAULT
+#define WHATDEFAULT 2
+#include "hpr.c"
diff --git a/src/init/s6-reboot.c b/src/init/s6-reboot.c
new file mode 100644
index 0000000..0bf8785
--- /dev/null
+++ b/src/init/s6-reboot.c
@@ -0,0 +1,7 @@
+/* ISC license. */
+
+#undef PROGNAME
+#define PROGNAME "s6-reboot"
+#undef WHATDEFAULT
+#define WHATDEFAULT 3
+#include "hpr.c"