Linux boot up process - Upstart
by Wenwei Weng
Booting a Linux installation involves multiple stages and software components, including firmware initialization, execution of a boot loader, loading and startup of a Linux kernel image, and execution of various startup scripts and daemons. In the previous post, sysvinit is discussed. Now we look into upstart.
Upstart is an event-based replacement for the /sbin/init daemon which handles starting of tasks and services during boot, stopping them during shutdown and supervising them while the system is running.
It was originally developed for the Ubuntu distribution, but is intended to be suitable for deployment in all Linux distributions as a replacement for the venerable System-V init.
Make sure upstart version of /sbin/init is installed in the system
cgr@cgr-tst1:~$ /sbin/init --version
init (upstart 1.12.1)
Copyright (C) 2006-2014 Canonical Ltd., 2011 Scott James Remnant
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
cgr@cgr-tst1:~$
upstart based init File structure
One of key thing upstart is that it is backward compatible with sysvinit, i.e. all the file /etc/inittab, /etc/init.d, /etc/rc[0-6].d/ are still valid.
For upstart, there is a new directory /etc/init/, which holds Job configuration files, see below for a typical ubuntu 14.04 desktop system.
cgr@cgr-tst1:/etc/init$ ls
acpid.conf modemmanager.conf rcS.conf
alsa-restore.conf mountall-bootclean.sh.conf rc-sysinit.conf
alsa-state.conf mountall.conf resolvconf.conf
alsa-store.conf mountall-net.conf rfkill-restore.conf
anacron.conf mountall-reboot.conf rfkill-store.conf
apport.conf mountall.sh.conf rsyslog.conf
avahi-cups-reload.conf mountall-shell.conf ser2net.conf
avahi-daemon.conf mountdevsubfs.sh.conf setvtrgb.conf
bluetooth.conf mounted-debugfs.conf shutdown.conf
bootmisc.sh.conf mounted-dev.conf ssh.conf
checkfs.sh.conf mounted-proc.conf startpar-bridge.conf
checkroot-bootclean.sh.conf mounted-run.conf systemd-logind.conf
checkroot.sh.conf mounted-tmp.conf tty1.conf
console.conf mounted-var.conf tty2.conf
console-font.conf mountkernfs.sh.conf tty3.conf
console-setup.conf mountnfs-bootclean.sh.conf tty4.conf
container-detect.conf mountnfs.sh.conf tty5.conf
control-alt-delete.conf mtab.sh.conf tty6.conf
cron.conf networking.conf udev.conf
cups-browsed.conf network-interface.conf udev-fallback-graphics.conf
cups.conf network-interface-container.conf udev-finish.conf
dbus.conf network-interface-security.conf udevmonitor.conf
dmesg.conf network-manager.conf udevtrigger.conf
failsafe.conf passwd.conf ufw.conf
failsafe-x.conf plymouth.conf upstart-file-bridge.conf
flush-early-job-log.conf plymouth-log.conf upstart-socket-bridge.conf
friendly-recovery.conf plymouth-ready.conf upstart-udev-bridge.conf
gpu-manager.conf plymouth-shutdown.conf ureadahead.conf
hostname.conf plymouth-splash.conf ureadahead-other.conf
hwclock.conf plymouth-stop.conf usb-modeswitch-upstart.conf
hwclock-save.conf plymouth-upstart-bridge.conf wait-for-state.conf
irqbalance.conf procps.conf whoopsie.conf
kmod.conf pulseaudio.conf
lightdm.conf rc.conf
cgr@cgr-tst1:/etc/init$
Writing Jobs
Jobs are defined in files placed in /etc/init, the name of the job is the filename under this directory without the .conf extension. They are plain text files and should not be executable.
The format treats one or more space or tabs as whitespace, which is skipped unless placed in single or double quotes. Line breaks are permitted within quotes, or if preceeded by a backslash. Comments begin with a ‘#’ and continue until the end of the line.
exec and script
All job files must have either an exec or script stanza. This specifies what will be run for the job.
exec /bin/foo --opt -xyz foo bar
script instead gives shell script code that will be executed using /bin/sh. The -e shell option is used, so any command that fails will terminate the script. The stanza is terminated by a line containing just “end script”.
script
# do some stuff
if [ ... ]; then
...
fi
end script
Below is an example of ser2net Job, which is to start “ser2net” job when it is in runlevel 2,3,4,5. In pre-start, it makes sure it is executable.
cgr@cgr-tst1:/etc/init$ cat ser2net.conf
# /usr/local/sbin/ser2net -p 4000 -c /etc/ser2net.conf -P /var/run/ser2net.pid
# The ser2net server provide serail to tcp access to act as console server.
description "ser2net server"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
respawn limit 10 5
umask 022
pre-start script
test -x /usr/local/sbin/ser2net || { stop; exit 0; }
end script
exec /usr/local/sbin/ser2net -p 4000 -c /etc/ser2net.conf -P /var/run/ser2net.pid
cgr@cgr-tst1:/etc/init$
start on and stop on
Your job is now able to be started and stopped manually by a system administrator, however you also probably want it to be started and stopped automatically when events are emitted.
The primary event emitted by upstart is startup which is when the machine is first started (without writable filesystems or networking).
If you’re using the example jobs, you will also have runlevel X events, where X is one of 0–6 or S. Jobs will be run alongside the init scripts for that runlevel.
Finally other jobs generate events as they are run; you can have yours run when another job stops by using stopped job. The other useful job event is started job.
You list the events you want to start your job with start on, and the events that stop your job with stop on.
start on startup
start on runlevel [23]
start on stopped rcS
start on started tty
Job Control
start, stop, status
Jobs may be started and stopped manually by using the start and stop commands, usually installed into /sbin. Each takes a job name, and outputs the final status (see below).
cgr@cgr-tst1:/etc/init$ which start
/sbin/start
cgr@cgr-tst1:/etc/init$ which stop
/sbin/stop
cgr@cgr-tst1:/etc/init$ which status
/sbin/status
cgr@cgr-tst1:/etc/init$ initctl list | grep tty
tty4 start/running, process 1173
tty5 start/running, process 1177
tty2 start/running, process 1183
tty3 start/running, process 1184
tty1 start/running, process 1381
tty6 start/running, process 1188
cgr@cgr-tst1:/etc/init$ sudo stop tty6
[sudo] password for cgr:
tty6 stop/waiting
cgr@cgr-tst1:/etc/init$ initctl list | grep tty
tty4 start/running, process 1173
tty5 start/running, process 1177
tty2 start/running, process 1183
tty3 start/running, process 1184
tty1 start/running, process 1381
tty6 stop/waiting
cgr@cgr-tst1:/etc/init$ sudo start tty6
tty6 start/running, process 8214
cgr@cgr-tst1:/etc/init$ initctl list | grep tty
tty4 start/running, process 1173
tty5 start/running, process 1177
tty2 start/running, process 1183
tty3 start/running, process 1184
tty1 start/running, process 1381
tty6 start/running, process 8214
cgr@cgr-tst1:/etc/init$
cgr@cgr-tst1:/etc/init$ status tty6
tty6 start/running, process 8214
cgr@cgr-tst1:/etc/init$
initctl list
A list of all jobs and their states can be obtained by using initctl list.
cgr@cgr-tst1:/etc/init$ sudo initctl list
avahi-daemon start/running, process 893
mountnfs-bootclean.sh start/running
rsyslog start/running, process 664
tty4 start/running, process 1173
udev start/running, process 290
upstart-udev-bridge start/running, process 281
whoopsie start/running, process 1391
avahi-cups-reload stop/waiting
mountall-net stop/waiting
passwd stop/waiting
rc stop/waiting
startpar-bridge stop/waiting
ureadahead-other stop/waiting
apport start/running
systemd-logind start/running, process 890
tty5 start/running, process 1177
console-setup stop/waiting
gpu-manager stop/waiting
.........................................
network-interface-security (networking) start/running
networking start/running
dmesg stop/waiting
procps stop/waiting
rfkill-restore stop/waiting
tty6 start/running, process 8214
console-font stop/waiting
network-interface-container stop/waiting
ureadahead stop/waiting
cgr@cgr-tst1:/etc/init$
service vs job
The above we discussed is called job, which is defined by a file under /etc/init/ with extention “.conf”. In ubuntu distribution, you will see “service”, which is essentially the task started by sysvinit way.
cgr@cgr-tst1:/etc/init$ sudo service --status-all
[ + ] acpid
[ - ] anacron
[ + ] apparmor
[ ? ] apport
[ + ] avahi-daemon
[ + ] bluetooth
[ - ] brltty
[ ? ] console-setup
[ + ] cron
[ + ] cups
[ + ] cups-browsed
[ - ] dbus
[ ? ] dns-clean
[ + ] friendly-recovery
[ - ] grub-common
[ ? ] irqbalance
[ + ] kerneloops
[ ? ] killprocs
[ ? ] kmod
[ ? ] lightdm
[ ? ] networking
[ ? ] ondemand
[ ? ] pppd-dns
[ - ] procps
[ - ] pulseaudio
[ ? ] rc.local
[ + ] resolvconf
[ - ] rsync
[ + ] rsyslog
[ + ] saned
[ ? ] screen-cleanup
[ ? ] sendsigs
[ - ] ser2net
[ ? ] speech-dispatcher
[ - ] ssh
[ - ] sudo
[ + ] udev
[ ? ] umountfs
[ ? ] umountnfs.sh
[ ? ] umountroot
[ - ] unattended-upgrades
[ - ] urandom
[ - ] x11-common
cgr@cgr-tst1:/etc/init$
initctl list will show the process managed using upstart native file. service will show those using a more traditional init script. systemctl will show the one using systemd native format.
Subscribe via RSS