On 06/09/2016 07:46 PM, Andrew McGlashan wrote: > The order of the scripts alone allowed for everything to be very, very > simple and no script relied upon any other; they were self dependent. > If you wanted something to be available before your script, you made > sure your numeric number after the S in the script name (or rather the > symlink name back to the /etc/init.d directory file) was higher. It was > simple, it worked perfectly,
(In the following, for the most part I'm only going to talk about sysvinit, ignoring any other init system.) I think you are suffering from quite a bit of confusion. You need to separate a few concepts apart: - the S**/K** symlinks - how they are generated - startup parallelization Since very old versions of Debian (I don't remember which), you could create symbolic links for init scripts like this: - /etc/rcX.d/SYYname -> /etc/init.d/name - /etc/rcX.d/KYYname -> /etc/init.d/name YY being a number between 00 and 99 here. When changing a runlevel, first all the K** links (in order) of the _new_ runlevel are run and then all the S** links (in order), also of the _new_ runlevel are run. [1] The symlinks would be generated by calling update-rc.d, e.g. via: update-rc.d NAME start 42 2 3 4 5 . stop 75 0 1 6 . This would generate /etc/rc[2345].d/S42NAME, /etc/rc[016].d/K75NAME. The main problem with this scheme alone is that the numbers are actually really arbitrary, so it's not immediately clear which ones to use when writing an init script. This lead to multiple problems, most importantly that if you had two otherwise unrelated services A and B, that don't have any dependency with each other, so they have the same number, e.g. 20. But then a service C comes a long that needs to be started before B but after A, then A and B need to have different numbers regardless. But the numbers of these services are fixed in the Debian package scripts, so the maintainer of the package containing service C needed to convince the maintainers of services A and B to change their number (and if they in turn depend on other scripts, those have to be adapted, too). And this doesn't even leave any room for modifications by the admin, who might need this for local scripts that will never be part of Debian: even if they could convince the maintainers of the packages they'd need to squeeze their own script in between, they'd still have to wait for the next Debian release or do some extensive local modifications. Which is why people had been working on a replacement for a number of years (the Debian wiki claims since 2002, but the link doesn't work). In 2008 an alternative was implemented that was designed to work across distributions, and the LSB standard for init scripts was born. [2] (This was way before systemd btw.) The integration into Debian took a bit longer, and Squeeze was the first Debian version to fully incorporate that. (Although you could still choose to use old system in Squeeze IIRC, support for which was dropped in Wheezy.) Instead of having the numbers fixed, they would be calculated when services were enabled. Now, each service has to declare in form of the so-called LSB header its dependencies relative to other services. Then, when services are enabled/disabled, these dependencies taken into account and the numbers are generated accordingly. (Which is why they rarely exceed 30 now, unless you have really many services.) This now has the huge advantage that if you squeeze in a service between others, the numbers will automatically get recalculated. The following LSB headers are understood in Debian: * Provides: Alternative names for the service for dependency resolution. For example, /etc/init.d/networking has the values 'networking' and 'ifupdown' in there; so anything that orders against either of them will order against networking. * Required-Start: Anything that must be started before this script. insserv and update-rc.d will fail if the required script doesn't exist or is not enabled. (It will not enable that script automatically though, it will just complain.) * Required-Stop: Same as Required-Start, but just that these services have to be kept around during shutdown. Commonly the same as Required-Start, but not necessarily. * Should-Start/Should-Stop: Same as the Required- version, but if the other script is not enabled or not installed, don't consider that to be an error. * X-Start-After:/X-Stop-Before: The inverse dependency, meaning that A: X-Start-After: B is equivalent to B: Should-Start: A * Default-Start: List of runlevels where the service should be started in by default. Typically 2 3 4 5 * Default-Stop: Typically 0 1 6 To enable a service initially, you'd call update-rc.d defaults NAME And to remove the links: update-rc.d remove NAME Important: only the options defaults, remove, enable and disable for update-rc.d will add/remove/change type of S/K symlinks for the service specified. They will never touch the symlinks for other services, and other options will never add/remove/change type. However, calling insserv without parameters (which is what update-rc.d does internally) will cause the existing symlinks to be reordered - so adding a link S42foo somewhere might be renamed to S12foo later, depending on what dependency-based resolution says the number should be. So when you claim the old system where you just put some numbers in there worked 'perfectly', I will disagree vehemently. The dependency- based boot system of Squeeze was a *really* good idea. I remember Gentoo from the mid-2000s once, and back then (before OpenRC) they were using sysvinit + a bunch of bash scripts that were nothing like the standard init scripts used on other distros - instead they'd declare dependencies logically via bash functions. I clearly remember liking that idea MUCH more than the numbered links I knew from other distros, especially when you wanted to write your own script. So to my view, the LSB init script standard is a clear advantage as compared to what was going on before - because you can finally logically declare the relations between services at startup. It's a bit clumsy (comments that are parsed in init scripts), so it's not perfect, but a vast improvement IMHO. Ok, so now that we have dependency-base init script ordering, there's an additional feature added to Debian, namely parallel startup of init scripts. (With sysvinit.) This is done via the startpar binary that was once part of the sysvinit-utils pacakge, but is since Jessie a separate package on its own (named startpar). The idea behind it is the following: if all scripts explicitly declare their dependencies, any script with the same number as another will be in no relation to that, so it's possible to start both in parallel. For example, on a wheezy box I have here, the ntp, rsync and ssh have the same number in /etc/rc3.d, so they can be started at the same time in parallel - and once all 3 are complete, the next service can be started. You can indeed disable this via setting CONCURRENCY=none in the /etc/default/rcS configuration file. Then the startup wil again be completely serialized. (In Jessie and onwards, you can choose to remove the startpar package instead, that will also do the trick.) > Now I have sysvinit isntalled on wheezy, it is failing to run a simple > script during system boot (as part of a planed reboot) and I cannot work > out why. > > # ls -l /etc/{init.d,rc*.d}/*archive* > -rwxr-xr-x 1 root root 1453 Jun 8 04:12 /etc/init.d/archive-system-mail > lrwxrwxrwx 1 root root 29 Jun 3 23:30 > /etc/rc2.d/S02archive-system-mail -> ../init.d/archive-system-mail > lrwxrwxrwx 1 root root 29 Jun 4 03:06 > /etc/rc3.d/S02archive-system-mail -> ../init.d/archive-system-mail > lrwxrwxrwx 1 root root 29 Jun 4 03:07 > /etc/rc4.d/S02archive-system-mail -> ../init.d/archive-system-mail > lrwxrwxrwx 1 root root 29 Jun 4 03:08 > /etc/rc5.d/S02archive-system-mail -> ../init.d/archive-system-mail The low number for a non-rcS service is a very disconcerting, because it could mean that your script isn't properly ordered against other scripts that are started during boot, especially those that mount stuff and such. This is likely caused due to a lack of dependencies. 02 is typically at the point where udev is started, when the root filesystem might still even be mounted read-only. (If you've configured it that way.) I believe that's your actual problem: I think either your script is run, but far too early, or it's not run, because it has a really low number in a non-rcS runlevel, and startpar doesn't cope with that well. (Because rcS -> rc2 transition is not a runlevel transition in Debian, so it's kind of special.) And if I look at the script, there lies your very problem: > Now, I want the archiving script to run on system startup, I don't want > dovecot or exim4 to be running when the script starts, it simply needs > to have the /backup and /var file systems mounted to do it's required job. Ok, so if you depend on local or remote file systems, you need to depend on $local_fs and $remote_fs, respectively. If all your file systems are local, use $local_fs - otherwise $remote_fs (or both). (Technically, $syslog might suffice, because all standard syslog implementations provide $syslog via /etc/insserv.conf, and they themselves depend on $local_fs at least, but IMHO it's better to explicitly write out $remote_fs and $local_fs.) > My script is meant to create a log file in the /var/log directory. If I > run the script manually, it works perfectly. There are some generic > parts in the script, it is a fairly simple script, even if a little bit > over complicated. What do I need to do to fix it? > > Here is the script: > > # cat /etc/init.d/archive-system-mail > #! /bin/sh > ### BEGIN INIT INFO > # Provides: mailarchive > # Required-Start: $syslog > # Required-Stop: $syslog Required-Start: $local_fs $remote_fs $syslog Required-Stop: $local_fs $remote_fs $syslog Plus, maybe, if it is supposed to run _before_ exim4, you could also add the following pseudo-headers: X-Start-Before: exim4 X-Stop-After: exim4 After the modification, run insserv (without parameters) to have it reorder the script with respect to numbering (it should get a higher number now), verify that the numbers of your init scripts are now reordered accordingly and everything should work. (Assuming the script is executable.) > case "$1" in > start) > do_main > ;; > *) > echo "Usage: $SCRIPTNAME {start}" >&2 > exit 3 > ;; > esac This is also not good, because Debian requires you to implement the start, stop, status, restart and force-reload arguments. Maybe that's also something that trips up the logic in your case. If you really don't want them, please at least add something like stop|status|restart|force-reload) exit 0 ;; Regards, Christian [1] I remember really old versions of SuSE, from before 2000, that used a slightly different scheme, which would first run all K** scripts of the old runlevel (so a script would have S** and K** symlinks in the same runlevel) and then the S** scripts of the new runlevel, exluding things that match (so it doesn't stop things that are in both). But IIRC that was never in Debian, and I don't know what SuSE did with that afterwards. [2] https://lists.debian.org/debian-devel-announce/2008/01/msg00004.html
signature.asc
Description: OpenPGP digital signature