1 <!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4 <title>Talk: Reordering the Debian boot sequence for correctness and speed
</title>
5 <link rel=
"stylesheet" href=
"../mrtg-td/slides.css" type=
"text/css">
6 <meta http-equiv=
"Content-Type" content=
"text/html; charset=iso-8859-1">
7 <meta name=
"Language" content=
"en">
8 <meta name=
"Author" content=
"Petter Reinholdtsen">
9 <style type=
"text/css">
17 <a href=
"../200706-bootseq/200706-bootseq.html">last related talk
</a>
19 <h1><A href=
"http://www.fosdem.org/2008/schedule/events/debian_boot">Reordering the Debian boot sequence for correctness and speed
</a></h1>
21 <p>There are subtle bugs in the Debian boot and shutdown sequence.
22 They are hard to find, as they normally only affect rare combination
23 of packages, and harder to fix, as they normally require the combined
24 work of several maintainers and changes in several packages. This
25 talk is about the release goal for Lenny to solve them, and gain a few
26 advantages on the way.
</p>
28 <div class=
"presenter">Petter Reinholdtsen - one of the sysvinit maintainers
30 <br>FOSDEM
2008,
2008-
02-
26</div>
34 There are subtle bugs in the debian boot and shutdown sequence. They
35 are hard to find, as they normally only affect rare combination of
36 packages, and harder to fix, as they normally require the combined
37 work of several maintainers and changes in several packages.
39 One way to find these bugs is to document the dependencies of all
40 init.d scripts, and use this information to check that the ordering is
41 correct. When such information is available, it is also possible to
42 reorder the boot and shutdown sequence to make sure all dependencies
45 It is also possible to run scripts in parallel, to speed up the boot,
46 when the order they need to run in is known.
48 This talk is about how all of this can be done with Debian.
55 - how do sysvinit boot work
60 - how does it work in debian
63 - how to verify the boot sequence
65 - dependency graph using dotty
67 - overriding included headers
71 - how to write lsb headers
80 - what is needed to convert
81 - add LSB header to packages and get the change into testing
83 - more users to test headers and detect errors
84 - install and activate insserv by default
88 <h2>SysV init in Debian - Booting
</h2>
90 <p>Note, this is the stuff going on after the initrd part is done.
91 The very early boot is done before hard drive partitions is mounted.
</p>
95 <li>/sbin/init start, which look at /etc/inittab and decides what to
98 <li>The scripts in /etc/rcS.d/ is executed in sequence by
99 /etc/init.d/rc, with
<tt>start
</tt> as the argument.
</li>
101 <li>Depending on the runlevel, the scripts for the given runlevel is
102 executed (normally the ones in /etc/rc2.d/) are executed in
103 sequence, first the stop scripts with
<tt>stop
</tt> as their
104 argument, next the start scripts with
<tt>start
</tt> as their
105 argument. The rc*.d/ directories contain symlinks the files in to
108 <li>The ordering is important.
</li>
110 <li>The single-user runlevel will present a login prompt after rcS.d/
111 was executed. Runlevel
1 is not the single user runlevel, but it
112 behaves as a better single user.
</li>
116 <p>Note that because the Linux kernel is becoming more and more event
117 based, the boot sequence is no longer sequencial.
<p>
119 <h2>SysV init in Debian - Switching runlevels
</h2>
123 <li>Call
<tt>telinit X
</tt> where X is the new runlevel, one of S,
0,
124 1,
2,
3,
4,
5,
6.
</li>
126 <li>init runs in sequence all stop scripts in /etc/rcX.d/ that also
127 has a start symlink in the previous runlevel /etc/rcY.d/, with
128 <tt>stop
</tt> as their argument.
</li>
130 <li>init then run in sequence all start scripts in /etc/rcX.d/, with
131 <tt>start
</tt> as their argument.
</li>
135 <p>Note that switching to runlevel S will not run the scripts in
136 /etc/rcS.d/. To get a similar effect after boot, switch to runlevel
137 1. It will (should) kill all services and prepare the machine for
140 <h2>SysV init in Debian - Shutting down
</h2>
142 <p>This is roughtly equivalent to switching to runlevel
0 (halt) or
6
145 <p>Minor exception: all scripts (both start and stop) are executed
146 with the
<tt>stop
</tt> argument, ignoring their start and stop
147 setting and confusing script writers.
</p>
149 <p>Only stop scripts for services started in the previous runlevel is
152 <h2>The ordering problem
</h2>
154 <p>Script ordering is vital for this to work. And how are the scripts
157 <p>And the numbers are picked using skills, knowledge and negotiation.
158 Getting it right is often hard.
160 <p>The current Debian default is wrong. Stop sequence should by
161 default be the reverse of the start sequence. It isn't.
163 <p>Reordering is hard and require cooperation between maintainers of
164 all packages involved.
166 <h2>The ordering problem - an example
</h2>
168 <p>Given two packages with two scripts inserted with the default
171 <p>Package A: script_a sequence
20 (start and stop)
172 <br>Package B: script_b sequence
20 (start and stop)
174 <p>Along come script C, which should run before script_a and after
175 script_b. Current solution is to change packages A and C or packages
176 B and C to get something like this:
178 <p>Package A: script_a start seq.
22, stop seq.
18
179 <br>Package B: script_b sequence
20 (start and stop)
180 <br>Package C: script_c start seq
21, stop seq
19
182 <p>If other scripts depend on the old order of script_a, they will
183 have to change their sequence number too. Only way to discover this
184 is by a lot of testing, or documenting script dependencies.
186 <h2>An ordering solution
</h2>
188 <p>Let each script document its dependency, and generate sequence
189 numbers using this dependency information. Example:
191 <p>Package A: script_a depend on nothing
192 <br>Package B: script_b depend on nothing
193 <br>Package C: script_c depend on script_b, a dependency of script_a
195 <p>Generated sequence:
197 <p>script_b start seq
1, stop seq
3
198 <br>script_c start seq
2, stop seq
2
199 <br>script_a start seq
3, stop seq
1
201 <p>An implementation of this system is the dependency based boot
202 sequencing, provided in the insserv package. Uses format specified in
203 Linux Software Base to document dependencies.
</p>
205 <h2>Checking the current boot sequence
</h2>
207 <p>Static checking of current headers:
208 <tt>/usr/share/insserv/check-initd-order [-o] [-k]
</tt> - report mismatch
211 <p>Graph of the dependencies:
212 <a href=
"sid-base-boot-20080220.dot"><tt>/usr/share/insserv/check-initd-order -g
</tt></a> - for reviewing dependencies
214 <h2>Enabling dependency based boot sequencing I
</h2>
216 <p><a href=
"insserv-enable.png"><img align=
"right" src=
"insserv-enable.png" width=
"50%"></a>
218 <li>Use the insserv package in unstable and testing
219 <li>Low priority debconf question.
220 <li>Only enabled after verfiying that it is safe to enable
221 <li>Converts all start symlinks in rc0.d/ and rc6.d with stop symlinks.
222 <li>Replaces update-rc.d with wrapper calling insserv
223 <li>All of rc*.d/ is reordered
226 <h2>Enabling dependency based boot sequencing II
</h2>
229 # aptitude install insserv
230 # dpkg-reconfigure insserv
231 info: Checking if it is safe to convert to dependency based boot.
232 info: Backing up existing boot scripts in \
233 /var/lib/insserv/bootscripts-
20080223T0742.tar.gz
234 info: Reordering boot system, log to \
235 /var/lib/insserv/run-
20080223T0742.log
236 info: Recording new boot sequence in \
237 /var/lib/insserv/bootscripts-
20080223T0742-after.list
238 info: Use '/usr/sbin/update-bootsystem-insserv \
239 restore' to restore the old boot sequence.
240 Adding `diversion of /usr/sbin/update-rc.d to \
241 /usr/sbin/update-rc.d.distrib by insserv'
242 success: Boot system successfully converted
243 #
<a href=
"sid-base-seqchanges.txt">/var/lib/insserv/insserv-seq-changes \
244 /var/lib/insserv/bootscripts-
20080223T0742.tar.gz
</a>
248 <h2>With dependency based boot sequencing
</h2>
250 <p>update-rc.d refuse to Insert scripts which create a loop.
</p>
252 <p>update-rc.d require scripts to be inserted in dependency order.
</p>
254 <p>Incorrect dependencies give the wrong boot and shutdown order.
</p>
256 <p>It is possible to enable concurrent booting, running boot scripts
257 in parallel (CONCURRENCY=startpar in /etc/default/rcS)
</p>
259 <h2>Disabling dependency based boot sequencing
</h2>
261 <p>Run
<tt>dpkg-reconfigure insserv
</tt> and disable it.
263 <p>It is always possible to disable just after it was enabled, before
264 any new packages are installed.
</p>
266 <p>To disable it, a backup of the old boot sequence is restored if no
267 changes has been done to the boot sequence since it was enabled.
269 <p>If restoring is not possible, All postinst scripts for packages
270 with init.d scripts will be executed again to get them to call
271 update-rc.d and add the boot scripts again.
273 <h2>LSB headers for insserv
</h2>
276 <li>"Provides" header, list the Facility/service provided by the
277 script. Do not list virtual facilities (like $time)
</li>
279 <li>Runlevel entries (Default-Start and Default-Stop headers), list
280 what runlevels to activate for this script
282 <li>Dependency entries (Required-Start, Required-Stop, Should-Start,
283 Should-Stop, X-Start-Before, X-Stop-After), list the
284 facilities/services needed by this script. It will start after
285 its start dependencies and stop before its stop dependencies. The
286 X-* entreis are reverse dependencies. Required-* are hard
287 dependencies (will install even if they are missing), while
288 Should-* and X-* are soft dependencies (only taken into account if
289 scripts providing them are present).
</li>
293 <h2>What to list as dependencies I
</h2>
295 <p>If your package used the default update-rc.d settings before, this
296 is the header for you:
</p>
299 # Provides: scriptname
300 # Required-Start: $remote_fs $syslog
301 # Required-Stop: $remote_fs $syslog
302 # Default-Start:
2 3 4 5
303 # Default-Stop:
0 1 6
307 <p>$remote_fs is needed by all scripts using files in /usr/. $syslog
308 is needed only by scripts starting services logging to syslog.
</p>
310 <h2>Virtual facilities
</h2>
312 <p>Linux Software Base version
3.2 define these virtual facilities:
317 <dd>all local file systems are mounted. (In Debian, / and /var/ is available)
320 <dd>basic networking support is available. Example: a server program
321 could listen on a socket. (In Debian, network interfaces are up)
324 <dd>daemons providing SunRPC/ONCRPC portmapping service as defined in
325 RFC
1833: Binding Protocols for ONC RPC Version
2 (if present) are
329 <dd>all remote file systems are available. In some configurations,
330 file systems such as /usr may be remote. Many applications that
331 require $local_fs will probably also require $remote_fs. (In Debian,
332 /usr/ and NFS directories are guaranteed to be mounted)
335 <dd>the system time has been set, for example by using a network-based
336 time program such as ntp or rdate, or via the hardware Real Time
340 <dd>system logger is operational.
343 <dd>IP name-to-address translation, using the interfaces described in
344 this specification, are available to the level the system normally
345 provides them. Example: if a DNS query daemon normally provides this
346 facility, then that daemon has been started.
350 <p>All of these represent points in time during boot and shutdown.
352 <h2>What to list as dependencies II
</h2>
354 <p>Normally, the start and stop dependencies are the same.
356 <p>Prefer virtual dependencies over specific dependencies.
358 <p>When using specific dependencies, use the string listed in the
359 provides header of the scripts you depend on.
361 <p>Scripts started in rcS.d/ need extra care.
363 <p>Depend on $remote_fs unless started in rcS.d/. Make sure /usr/ is
364 available during start and that it is stopped before sendsigs kill all
365 processes during shutdown.
</p>
369 <h2>Status of dependency based boot
</h2>
371 <img alt=
"LSB header progress graph" src=
"lsb-header-progress.png" width=
"50%" align=
"right">
373 <p>Release goal for Debian Lenny.
375 <p>Packages with LSB header (in Sid):
654 of
866 (
76%)
376 <br>Unsolved BTS reports:
85
377 <br>Packages without BTS reports: ~
150
378 <br>Last package projected fixed
2008-
07-
19 with the current rate
380 <p>Need better documentation
382 <p>Should update Debian policy to reflect this new feature.
384 <p>Two insserv bugs to fix.
386 <li>Avoid adding unwanted stop symlinks.
387 <li>Do not fail on "fake" loops. (minor)
392 <h2>Tracking status
</h2>
393 debian/rules missing-overrides
394 debian/rules missing-by-popcon
398 http://wiki.debian.org/LSBInitScripts
399 http://wiki.debian.org/LSBInitScripts/DependencyBasedBoot
400 svn+ssh://svn.debian.org/svn/initscripts-ng/trunk/src/insserv
402 <h2>Thank you very much
</h2>
406 <p><a href=
"http://www.hungry.com/~pere/mypapers/200802-bootsequence/200802-bootsequence.html">http://www.hungry.com/~pere/mypapers/
200802-bootsequence/
200802-bootsequence.html
</a></p>