summaryrefslogtreecommitdiff
path: root/doc/s6-linux-init.html
blob: 4d800cec831cb5a4b406f5c4f8b907b9fe3f2ac6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
<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-linux-init program</title>
    <meta name="Description" content="s6-linux-init: the s6-linux-init program" />
    <meta name="Keywords" content="s6 linux init administration root init boot pid1 pid 1 /sbin/init" />
    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
  </head>
<body>

<p>
<a href="index.html">s6-linux-init</a><br />
<a href="//skarnet.org/software/">Software</a><br />
<a href="//skarnet.org/">skarnet.org</a>
</p>

<h1> The <tt>s6-linux-init</tt> program </h1>

<p>
<tt>s6-linux-init</tt> is a program that is meant to run as pid 1,
as a <em>stage 1 init</em>: it performs the necessary early system preparation
and execs into <a href="//skarnet.org/software/s6/s6-svscan.html">s6-svscan</a>.
</p>

<h2> Interface </h2>

<pre>
     s6-linux-init [ -c <em>basedir</em> ] [ -p <em>initial_path</em> ] [ -s <em>env_store</em> ] [ -m <em>umask</em> ] [ -d <em>slashdev</em> ] [ -D <em>initdefault</em> ] [ -n | -N ] [ -C ] [ -B ] [ <em>args...</em> ]
</pre>

<ul>
 <li> If <tt>s6-linux-init</tt> isn't pid 1, it execs into
<a href="s6-linux-init-telinit.html">s6-linux-init-telinit</a> with the
same arguments. </li>
 <li> Else, it performs some early preparation, spawns a process that
will run the <em>rc.init</em> script, then execs into
<a href="//skarnet.org/software/s6/s6-svscan.html">s6-svscan</a>.  </li>
</ul>

<h2> Options </h2>

<p>
 These options should exactly mirror the options with the same name that
have been given to <a href="s6-linux-init-maker.html">s6-linux-init-maker</a>.
If there is a discrepancy, the system might not boot.
</p>

<ul>
 <li> <tt>-c</tt>&nbsp;<em>basedir</em>&nbsp;: read all its initialization
data from <em>basedir</em>. If the data has not indeed been copied to
<em>basedir</em>, <strong>the system will not boot</strong>. </li>
 <li> <tt>-p</tt>&nbsp;<em>initial_path</em>&nbsp;: the initial value for
the PATH environment variable. </li>
 <li> <tt>-s</tt>&nbsp;<em>env_store</em>&nbsp;: the place where to dump
kernel environment variables. </li>
 <li> <tt>-m</tt>&nbsp;<em>initial_umask</em>&nbsp;: the initial file umask. </li>
 <li> <tt>-d</tt>&nbsp;<em>slashdev</em>&nbsp;: mount a devtmpfs on
<em>slashdev</em>. By default, no such mount is performed - it is assumed
that a devtmpfs is automounted on <tt>/dev</tt> at boot time by the kernel. </li>
 <li> <tt>-D</tt>&nbsp;<em>initdefault</em>&nbsp;: the initial runlevel
to boot to, if it isn't overridden by the kernel command line.
This is only given as a first argument to <em>rc.init</em>.
Default is <tt>default</tt>. </li>
 <li> <tt>-n</tt>&nbsp;: instead of unmounting <tt>/run</tt> and mounting
a tmpfs on it, just remount <tt>/run</tt>. </li>
 <li> <tt>-N</tt>&nbsp;: do not touch <tt>/run</tt> at all. </li>
 <li> <tt>-C</tt>&nbsp;: run in a container. This option modifies a few
of the operations described below, to accommodate running in a container
instead of on real hardware. For instance: it does not scan the command
line for a specific runlevel, it does not trap ctrl-alt-del, and before
anything else it waits for its descriptor 3, if present, to close.
(Docker uses this fd 3 mechanism as synchronization between the Docker
daemon and the container's <tt>init</tt>.) </li>
 <li> <tt>-B</tt>&nbsp;: do not run the catch-all logger. This option
removes the catch-all-logger-related operations from the list below;
<tt>s6-linux-init</tt> will not redirect output descriptors, and will
use a different synchronization mechanism to ensure <tt>rc.init</tt>
only runs when <a href="//skarnet.org/software/s6/s6-svscan.html">s6-svscan</a>
is ready. </li>
</ul>

<h2> Early preparation </h2>

<p>
 When booting a system, <tt>s6-linux-init</tt> performs the following
operations:
</p>

<ul>
 <li> It prints a banner to <tt>/dev/console</tt>. </li>
 <li> It chdirs to <tt>/</tt>. </li>
 <li> It sets the umask to <em>initial_umask</em>. </li>
 <li> It becomes a session leader. </li>
 <li> It mounts a devtmpfs on <em>slashdev</em>, if requested. </li>
 <li> It uses <tt>/dev/null</tt> as its stdin (instead of <tt>/dev/console</tt>).
<tt>/dev/console</tt> is still used, for now, as stdout and stderr. </li>
 <li> It unmounts <tt>/run</tt> (or the directory you have given to the
<tt>--tmpfsdir</tt> configure option at package build time), just in case;
then it creates a tmpfs on it. Alternatively, it remounts <tt>/run</tt>,
or does not touch it at all. </li>
 <li> It copies the whole <tt><em>basedir</em>/run-image</tt> hierarchy to
<tt>/run</tt> (or your chosen tmpfsdir). </li>
 <li> It reads the initial environment from <tt><em>basedir</em>/env</tt>. </li>
 <li> If required, it stores the kernel environment into <em>env_store</em>. </li>
 <li> It performs "the fifo trick", i.e. it redirects its stdout to the
catch-all logger's fifo, without blocking, before the catch-all
logger is even up (because it's a service that will be spawned a bit
later, when <a href="//skarnet.org/software/s6/s6-svscan.html">s6-svscan</a>
is executed). </li>
 <li> It forks a child.
  <ul>
    <li> The child scans the kernel command line to find a suitable runlevel
(<tt>default</tt>, <tt>2</tt>, <tt>3</tt>, <tt>4</tt>, or <tt>5</tt>). If
it doesn't find any kernel command line argument that defines a runlevel,
it uses <em>initdefault</em>. </li>
    <li> The child becomes a session leader. </li>
    <li> The child blocks until the catch-all logger runs. </li>
  </ul> </li>
 <li> It also makes the catch-all logger's fifo its stderr. </li>
 <li> It traps the ctrl-alt-del keyboard combination. </li>
 <li> It execs into <a href="//skarnet.org/software/s6/s6-svscan.html">s6-svscan</a>
with <tt>/run/service</tt> as its scandir (or <em>tmpfsdir</em>/service). </li>
  <ul>
   <li> <a href="//skarnet.org/software/s6/s6-svscan.html">s6-svscan</a>
spawns the early services that are defined in
<tt><em>basedir</em>/run-image/service</tt>, and have been copied into
<tt>/run/service</tt> (or <em>tmpfsdir</em>/service). </li>
   <li> One of those early services is <tt>s6-svscan-log</tt>, which is
the catch-all logger. When this service is up, <tt>s6-linux-init</tt>'s
child unblocks. </li>
   <li> The child execs into <tt><em>basedir</em>/scripts/rc.init</tt>.
The first argument to <em>rc.init</em> is the chosen runlevel. The kernel
command line, as given by the kernel to <tt>s6-linux-init</tt> (i.e. without
the <tt>key=value</tt> arguments, which were passed into <tt>s6-linux-init</tt>'s
environment and were stored into <em>env_store</em>), makes for the rest of
the arguments given to <em>rc.init</em>. </li>
  </ul>
</ul>

<p>
 By the time <em>rc.init</em> runs,
<a href="//skarnet.org/software/s6/s6-svscan.html">s6-svscan</a> is running
as pid 1 and has spawned its early services - at least the catch-all logger,
and the other services, including the early getty if it has been defined, are
started in parallel and will be ready instantly. <em>rc.init</em> can then
perform <em>stage 2</em> of the initialization process, i.e. the handoff to
the service manager.
</p>

<h2> Exit codes </h2>

<p>
 <tt>s6-linux-init</tt> never exits. It spawns the <em>rc.init</em> script
and execs into <a href="//skarnet.org/software/s6/s6-svscan.html">s6-svscan</a>,
which runs forever until the machine stops or reboots.
</p>

<h2> Notes </h2>

<ul>
 <li> The <tt>s6-linux-init</tt>
binary is not meant to be called directly, or be linked to <tt>/sbin/init</tt>
directly, because it takes command-line options.
 Instead, after a
<a href="s6-linux-init-maker.html">s6-linux-init-maker</a> invocation,
the <tt>bin/</tt> subdirectory of the target will contain a script called
<tt>init</tt>, which execs into <tt>s6-linux-init</tt> with the appropriate
command-line options, and <em>is</em> suitable as a <tt>/sbin/init</tt> program.
The <tt>bin/</tt> subdirectory
should be copied by the administrator into <tt>/sbin</tt> for full
interface compatibility with sysvinit. </li>
</ul>

</body>
</html>