Please check the status of this specification in Launchpad before editing it. If it is Approved, contact the Assignee or another knowledgeable person before making changes.
Launchpad entry: https://launchpad.net/distros/ubuntu/+spec/replacement-initscripts
Packages affected: upstart, sysvinit
The primary source of tasks in the boot sequence comes from the initscripts package, which are implemented as serial shell scripts within the sysv-rc framework. This specification proposes their replacement with event-based upstart jobs.
You may want to look at UbuntuBootupHowto for a practical look on how to use Upstart in ubuntu.
Our boot sequence is currently slow, full of race conditions and poor interactions, especially with competition between the series of tasks run by sysv-rc, udev and sometimes just with the kernel. We developed upstart so that we could have a truly event driven boot sequence that would be fast, reliable and flexible; we should take advantage of it.
This specification is the logical next step of the ReplacementInit specification implemented for edgy, see that specification for use cases.
The boot sequence is a complex series of moving parts, and any replacement should be done in stages with ample testing between. Therefore this specification does not specify the ultimate final result, and instead specifies the pattern of work and draft of the likely outcome.
The new boot sequence will be driven by events received from the kernel, and generated by upstart as a result of running other tasks. Where possible, tasks that do not conflict will be run in parallel, and will only be run once their needs are met.
A draft chart based on the current boot sequence is given below. Note that there are already known bugs in this chart, as these bugs exist in our current boot sequence.
Rationale for Changes
A few changes were made in the above chart compared to the actual current boot sequence, the rationale for these is given below.
/dev mounted by new task.
Currently the /dev filesystem is mounted by the udev init script, and filesystems underneath mounted by the mountdevsubfs init script. This has been rearranged so that /dev and the other filesystems are mounted first, and the events caused by that are used to start udev. This should make maintenance significantly easier.
udev and cold plugging separated.
In the upstart world, udev is a service that we want to be respawned if it dies. The cold plugging and module loading is something that we want to do as a result of this. Therefore they have been split into different jobs.
Network and block device events from udev.
We have race-free notification of addition and removal of network devices, interfaces and block devices from the kernel via the udev daemon. Rules will ensure that upstart can use these as a major source of events.
filesystem checking and mounting. This is currently a couple of very complicated scripts; in the event-driven model, we split them into many very small, easy to read scripts. The particular advantage here is that they're much easier to handle, and can be run outside of the boot sequence.
MD, LVM, EVMS.
The Set up keyboard task needs to happen after devices have been cold plugged, as it needs access to the tty devices. The current boot sequence runs this before, relying on the static devices or some to have come from the initramfs. This is not ideal.
Unconfirmed by Scott:
procps may need to come after module-init-tools in order to set sysctls made available by modules? --ColinWatson
The use of "started" and "stopped" is confusing; it would be nice if you could clarify it. --IanJackson
Some dependencies appear to be missing. For example, in theory this could start multiuser daemons with the hostname unset and no lo interface. --IanJackson
It would be nice if / and other filesystems were handled slightly differently; it may be possible to bring the system up a little faster by knowing that some jobs only require a writable / (specifically /etc/mtab creation), and once / is up it should be possible to allow recovering other broken filesystems in a more comfortable way (e.g. multiple VTs). --ColinWatson
The implementation process of this specification will be performed on a task-by-task basis. We can do this because existing init scripts will continue to be run by upstart once the jobs it manages have been run.
The order of work will be roughly:
Kernel filesystems, udev and cold plugging. In order to get the maximum benefit, we should ensure that at least the kernel filesystems and udev daemon are managed by upstart; and that udev emits events that the rest of the system can use.
- Filesystem mounting and unmounting. The most critical job of the boot sequence, so it's important to get it right and spend the most time here.
- Network device configuration. The next highest source of races, so our next target; this will also sort out the issue of network filesystems.
System setup and cleanups. Other jobs run within the current rcS such as setting up the keyboard and console, and cleaning out temporary directories.
Ideally the /etc/rcS.d directory of a fresh install, or one with only packages from main should be empty. We'll continue to run anything here, of course.
If there is time, jobs from rc2 will be tackled. Priorities are:
dbus and services. This will gain a particular benefit as upstart can manage making sure services are restarted when dbus is, and stopped first, etc.
- X display manager and dependencies. The X display manager is the daemon we want started as early as possible, so we should try and get this managed within upstart. Any dependencies should be managed as well to ensure that we're race free.
- Hardware services such as CUPS, ACPId, etc.
- Network services.
Care will be taken to use appropriate dependency relationships throughout the development plan, so that partial upgrades are held rather than broken, when all the pieces are not in place. For example, startup-tasks and initscripts will use Breaks to make it obvious that they require similar versions.