A Whirlwind Tour of Init Systems and Services

Managing Services in SysVinit, Upstart, and Systemd

Steven Li
5 min readNov 3, 2017

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 running
chkconfig --list ssh
# see the run levels of the service
# recall, that SysVinit supports run levels
chkconfig --level 3 ssh on
# set the run level for the ssh service
chkconfig --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 none
pre-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/ .

--

--

Steven Li

Writing About Rails, React, Web Application Technology, Databases, and Software Engineering