A Whirlwind Tour of Init Systems and Services
Services
A daemon is a long-running background process, like a web server or CRON job scheduler. An initialization system (init system for short) is a program that:
- Starts up daemons after the OS boots
- Group daemons together into a collection called a run level or target and determines which run level or target is selected at startup.
- Ensure that daemons boot after their dependencies. For example, a daemon that requires network interfaces should start only after network interfaces have loaded.
- Offer convenient commands to start, stop, pause, restart, or reload configuration files for these daemons.
- Allows daemons to automatically restart after crashes.
When a daemon is managed by an init system, we call it a service.
Init Systems
- classic init systems — These refer to the init systems on the UNIX System V (aka SysVinit) as well as BSD (aka Bsdinit)
- upstart — An init system popularized by Ubuntu, it offers improvements over classic init systems, such as support for handling system events like the a device is plugged into the machine. Note that upstart is backwards compatible with SysVinit.
- systemd — A more advanced than the classic init systems or upstart, systemd can also manage sockets, devices, and mount points. The latest versions of Fedora and RHEL use Systemd.
Note you can have more than one init system on a machine, but you can only have one active at a time.
The init process
The classic init systems as well as upstart will have init
as the process with pid 1. When the systems boots, this init
process will spawn processes corresponding to the services it is managing. On systemd, the process with pid 1 is called systemd
.
$ pstree -p
init(1)─┬
│
├─acpid(1023)
├─atd(1025)
├─cron(1024)
├─dbus-daemon(480)
├─dhclient3(890)
├─getty(998)
├─getty(1005)
├─getty(1010)
├─getty(1011)
├─getty(1013)
├─getty(1137)
├─irqbalance(1027)
├─rsyslogd(485)─┬─{rsyslogd}(486)
│ ├─{rsyslogd}(487)
│ └─{rsyslogd}(488)
├─sshd(1581)────bash(2050)───pstree(2150)
├─udevd(389)─┬─udevd(742)
│ └─udevd(797)
├─upstart-socket-(583)
├─upstart-udev-br(385)
└─whoopsie(1030)───{whoopsie}(1072)
Run Levels
Init systems support a feature called run level, a number that determines which services should be running and which services should be stopped. The *nix standard 7 run levels are:
- 0 Halt — all services are shut down
- 1 Single User Mode — root account is automatically logged in. Only command-line interface is available. Other users cannot log into the machine. Network interfaces not started.
- 2 Multiuser Mode — users can log into the machine but only the command-line interface is available. Some network interfaces are started but others are not.
- 3 Extended Multiuser Mode — users can log in to the machine, but only command-line interface available. All network interfaces available. This is the common default run level for servers.
- 4 User Define — users can customize this run level.
- 5 Graphical Mode — users can log in. Command-line and graphical interface are available. All network interfaces started. This is the common default run level for desktop machines.
- 6 Reboot — the server is rebooted
Which services run at what run level is determined by script files in directories of the form /etc/rc.d/rc*.d
. More on this later.
SysVinit
On SysVinit systems, to list the available services and manage their run levels , use chkconfig
.
chkconfig --list
# see all services available, not just services that are runningchkconfig --list ssh
# see the run levels of the service
# recall, that SysVinit supports run levelschkconfig --level 3 ssh on
# set the run level for the ssh servicechkconfig --level 5 ssh off
# set the run level for the ssh service
SysVinit uses the service
command to manage services.
# see all services that are running
service --status-all | grep running# see the status of a specific service
service ssh status# stop a specific service
service ssh stop# start a specific service
service ssh start# restart a specific service
service ssh restart# reload a specific service
service ssh reload
Restarting vs Reloading
A worthwhile question is what is the difference between reloading and restarting a service. With restart, the service actually stops and starts again. With reload, the service never stops, the config files are just reloaded again.
Adding New Services to SysVinit
To add a new service, add a BASH script in /etc/rc.d/init.d
and make sure it handles the service
command options: start
stop
restart
reload
.
# /etc/rcd/init.d/my_new_service# chkconfig: 2345 25 10start() {
...
}stop() {
...
}restart() {
...
}
Note the chkconfig: 2345 25 10
declarative means the run levels for this service are 2,3,4, and 5 with 25 being the start order and 10 is its stop order, which determines when this service starts and stops relative to other services.
The machine knows which services to run at which run level by the script files in /etc/rc.d/rc1.d
,/etc/rc.d/rc2.d
,/etc/rc.d/rc3.d
, /etc/rc.d/rc4.d
, /etc/rc.d/rc5.d
, /etc/rc.d/rc6.d
, /etc/rc.d/rc7.d
where the set of services in run level x
will have their script files in /etc/rc.d/rcx.d
.
After creating creating this file, run chkconfig --add my_new_service
to create run level symbolic links from this file to the directories /etc/rc.d/rc*.d
.
Upstart
On Upstart systems, the initctl
command is used for managing services.
# list all services managed by Upstart
initctl list# filter services by status
initctl list | grep start/running# checking the status of a service
initctl status ssh# stopping a service
initctl stop ssh# starting a service
initctl start ssh# restarting a service
initctl restart ssh
But note that Upstart is backwards compatible with SysVinit so all the above commands could have been run with service
too.
The run levels and other configurations of Upstart services is determined by the files in /etc/init/
. For example, from the configuration for the sshd
daemon, we see its run levels are 2, 3, 4, and 5.
cat /etc/init/ssh.conf# ssh - OpenBSD Secure Shell server
#
# The OpenSSH server provides secure shell access to the system.description "OpenSSH server"start on filesystem or runlevel [2345]
stop on runlevel [!2345]respawn
respawn limit 10 5
umask 022# 'sshd -D' leaks stderr and confuses things in conjunction with 'console log'
console nonepre-start script
test -x /usr/sbin/sshd || { stop; exit 0; }
test -e /etc/ssh/sshd_not_to_be_run && { stop; exit 0; }
test -c /dev/null || { stop; exit 0; }mkdir -p -m0755 /var/run/sshd
end script# if you used to set SSHD_OPTS in /etc/default/ssh, you can change the
# 'exec' line here instead
exec /usr/sbin/sshd -D
Adding New Services to Upstart
In upstart, all service configuration files are located in /etc/init
as text format. They use a special syntax for directing Upstart on how to deal with a particular service.
# /etc/init/my_awesome_service.confstart on runlevel 6task exec /usr/sbin/my_awesome_daemon
Systemd
The command to see services on Systemd is systemctl
.
# list all services available
# --type=service filters out one time jobs
systemctl list-unit-files --type=service# enable a service
systemctl enable sshd.service# disable a service
systemctl disable sshd.service# see the status of a service
systemctl status sshd.service# start a service
systemctl start sshd.service# stop a service
systemctl stop sshd.service# restart a service
systemctl restart sshd.service# reload a service
systemctl reload sshd.service
The configuration files for services under Systemd live in lib/systemd/system/
.