The box reboots at night and, in the morning, everything - SSH, the web server, your programs - is running again, although nobody logged in to start it. Something started all of it, in the right order, and keeps watching it. This lesson is that something, and how to prove what it is.
What you need to know already: 1.1 Where you are (kernel, OS), 1.3 The tree (symlinks), 1.7 Driving the shell (exit status, signals).
Processes
A program is a file on disk. A process is a program that is running: it has memory, open files, and a place in the queue for the CPU. Run ls twice at once and you have two processes of the same program.
Every process has a number, its PID (process ID). Every process was started by another process, its parent; the new one is the parent's child. Your bash is a process; when you run ls, bash starts ls as its child and waits for it.
$$ is a shell variable holding your own shell's PID.
Boot, in four moves
- Firmware (the small program built into the machine that runs at power-on) hands control to the bootloader, which loads the kernel from
/boot. - The kernel sets up the hardware, then unpacks the initramfs: a tiny starter system held in memory whose only job is to find the real disk and mount it (attach it to the directory tree - lesson 1.20). Now the kernel needs a first real program to run.
- It runs
/sbin/initas PID 1 - the first process. On Ubuntu that path is a symlink to/usr/lib/systemd/systemd. - systemd takes over: it mounts the other disks listed in
/etc/fstab(the file saying which disks to attach where), then starts every service in the right order until the machine counts as "booted". That is your login prompt.
A service (also called a daemon) is a program that runs in the background with no terminal attached - the SSH server, the web server, the scheduler. systemd starts them and restarts them if they die; chapter 2 is all about that.
PID 1 is special
- It is the ancestor of everything. Every process is a descendant of PID 1.
- It adopts orphans. When a parent dies before its child, the child (an orphan) is handed to PID 1 as its new parent.
- It reaps. A finished process leaves its exit status behind, and stays listed as a zombie until its parent reads that status. PID 1 does that for every orphan it adopted, so zombies do not pile up. (Chapter 3 shows a zombie for real.)
- It cannot be killed.
sudo kill -9 1does nothing:killsends a signal to a PID,-9is SIGKILL, and the kernel simply refuses to deliver deadly signals to PID 1. If PID 1 died, the whole machine would stop.
systemd vs launchd
Your Mac's PID 1 is launchd: same job, different everything. Its service definitions are files in /Library/LaunchDaemons (instead of systemd's unit files - its service definitions, chapter 2 - in /etc/systemd/system), you control it with launchctl (instead of systemctl), and it logs differently. The ideas transfer - declare a service, the supervisor starts and restarts it - but none of the commands do.
Two ways to prove PID 1
$ ps -p 1 -o comm=
systemd
$ readlink -f /sbin/init
/usr/lib/systemd/systemd
pslists processes.-p 1means "only PID 1";-o comm=means "print only the command-name column" - the=with nothing after it removes the column heading, so you get one bare word.readlinkprints where a symlink points;-ffollows every hop of a chain of symlinks to the real file at the end.
Different sources - the kernel's process list, and the files on disk - with the same answer. That is what makes it proof rather than a guess.
To see the whole family, pstree draws every process as a tree hanging off PID 1; -p adds each PID in brackets:
systemd(1)─┬─systemd-journal(352)
├─cron(600)
├─sshd(700)───sshd-session(1509)───sshd-session(1565)───bash(1566)
...
Read the sshd line left to right: the SSH server (700) started a process for your connection, which started your bash (1566). ps -o ppid= -p $$ prints your shell's PPID (parent PID) - the 1565 in that chain.
What you can now do
- Say what a process, a PID and a parent are.
- Describe boot: firmware, bootloader, kernel, initramfs, PID 1, services.
- Prove which program is PID 1 two independent ways, and find your shell in the tree.