Linux Operating Systems Fundamentals · Lesson 5
Booting, Initializing, and Virtualizing Linux
The Linux boot sequence from firmware to GRUB to systemd or SysVinit, service and target management, safe shutdowns, user notification, and Linux as a virtualization guest.
Lesson purpose
A Linux administrator has to understand what happens between pressing the power button and seeing a login prompt, because every boot problem lives in one of those stages. This lesson follows the boot sequence from firmware to boot loader to kernel to the initialization system, then covers changing system states, shutting down safely, warning users first, and running Linux as a virtualization guest in a VM, a container, or the cloud.
Learning objectives
- Describe the four stages of the Linux boot process and find boot messages after startup.
- Compare BIOS/MBR and UEFI/ESP firmware booting.
- Configure and interact with GRUB Legacy and GRUB 2, and pass kernel parameters at boot time.
- Identify whether a system uses systemd or SysVinit, and manage services, targets, and runlevels with the matching tools.
- Shut down or reboot a system correctly and notify logged-in users before doing so.
- Explain hypervisors, VM creation methods, containers, and Infrastructure as a Service (IaaS) concepts.
LPIC-1 exam focus
- 101.2 Boot the system
- 101.3 Change runlevels/boot targets and shutdown or reboot system
- 102.2 Install a boot manager
- 102.6 Linux as a virtualization guest
1. The boot process has four stages
Frame the whole lesson around one sequence. When a boot fails, the first troubleshooting question is: which stage did it reach?
- Firmware. The firmware runs a Power-On Self-Test (POST) to check the hardware, then looks for a boot loader on a bootable device.
- Boot loader. The boot loader decides which Linux kernel to load and with which options.
- Kernel. The kernel loads into memory, prepares the system (including mounting the root filesystem), and starts the initialization program.
- Initialization. The init system starts the background services the system needs, such as a graphical display manager on a desktop or web and database services on a server.
Check for understanding: A system shows the GRUB menu, then stops with a “cannot mount root” error. Which stage failed? (The kernel stage. Firmware and the boot loader already did their jobs.)
2. Reading boot messages after the fact
Boot messages scroll past too quickly to read. Some graphical distributions hide them entirely; pressing Esc during boot (or switching consoles with Ctrl+Alt+F1) often shows them.
- Kernel ring buffer. The kernel keeps its messages in a fixed-size circular buffer in memory. New messages push out the oldest ones, so read it soon after boot.
dmesg. Displays the current contents of the kernel ring buffer.journalctl. On systemd systems, reads the journal, which also stores boot messages. It needs administrator privileges for full output and opens in thelesspager.- Log files. Some distributions also write boot messages to
/var/log/boot(Debian-based) or/var/log/boot.log(Red Hat-based).
$ dmesg | less # page through kernel messages
$ dmesg | grep -i sda # search for one device
$ sudo journalctl -b # messages from the current boot
$ sudo journalctl -k # kernel messages only
Teaching point: Don’t read boot output line by line. Pipe it into grep or less (both from Lesson 1) and search for a device name (sda), a key word (fail, disabled), or an item such as BOOT_IMAGE.
3. Firmware: BIOS and UEFI
All PC-compatible systems use built-in firmware to start the installed operating system. Older systems use BIOS; nearly all current systems use UEFI.
BIOS and the master boot record
- BIOS limitation. BIOS could read only one disk sector into memory, which is far too small for an operating system. So booting became a two-part process: BIOS runs a small boot loader, and the boot loader finds and runs the operating system.
- Boot devices. BIOS can load a boot loader from an internal or external hard drive, a CD/DVD, a USB flash drive, or a network server.
- Master boot record (MBR). The first sector of the boot disk. BIOS reads the program stored there into memory. Because it has to fit in one sector, that program mostly points to the rest of the boot loader or to the kernel file on another partition.
- Chainloading. A boot loader can point to another boot loader instead of a kernel. This is how one menu can offer several operating systems.
UEFI and the EFI System Partition
- History. Intel created EFI in 1998. The industry adopted the Unified EFI (UEFI) specification by about 2005, and it is now the standard.
- EFI System Partition (ESP). Instead of one boot sector, UEFI uses a dedicated partition formatted with FAT. It can hold boot loaders of any size and several boot loaders for several operating systems.
- Location on Linux. The ESP is usually mounted at
/boot/efi, and boot loader files use the.efiextension. - Boot manager. UEFI firmware includes a small built-in boot manager. Each boot loader you want to offer must be registered with it.
| Feature | BIOS | UEFI |
|---|---|---|
| Where the boot loader lives | MBR, the first disk sector | .efi files on the ESP |
| Size limit | One sector | None in practice |
| Multiple OS boot loaders | Through chainloading | Registered directly in the boot manager |
| Linux mount point | None | /boot/efi |
$ ls /sys/firmware/efi
Quick check: If that directory exists and contains files, the system booted with UEFI. If you get “No such file or directory,” it booted with BIOS (or UEFI in legacy/compatibility mode).
4. Boot loaders: GRUB Legacy and GRUB 2
The boot loader bridges the firmware and the kernel. The GRand Unified Bootloader (GRUB) is the standard.
- GRUB Legacy (1999). The original GRUB. It offers a menu and an interactive shell.
- GRUB 2 (2005). A complete rewrite. It can load driver modules and use logic to change the menu depending on conditions, such as whether an external drive is connected. Modern distributions use GRUB 2.
Configuring GRUB Legacy
- Configuration file.
/boot/grub/menu.lst. Red Hat-derived distributions use/boot/grub/grub.conf, andmenu.lstis often a symbolic link to it. - Two sections. Global definitions come first, followed by one section per operating system.
| Global setting | Purpose |
|---|---|
default |
Menu entry chosen by default (counting from 0) |
timeout |
Seconds to wait before booting the default |
fallback |
Entry to try if the default fails |
color |
Menu colors: normal pair, then selected pair |
hiddenmenu |
Don’t display the menu |
splashimage |
Background image for the menu |
| Per-OS command | Purpose |
|---|---|
title |
The text shown in the menu; begins each section |
root |
Disk and partition holding /boot |
kernel |
Kernel image to load, plus kernel parameters |
initrd |
Initial RAM disk or filesystem with drivers needed at boot |
rootnoverify |
A non-Linux partition, such as Windows |
chainloader +1 |
Hand off to the boot loader in that partition’s first sector |
Device naming. GRUB Legacy counts disks and partitions from 0: (hd0,0) is the first partition on the first disk, and (hd0,1) is the second partition on the first disk.
default 0
timeout 10
color white/blue yellow/blue
title CentOS Linux
root (hd1,0)
kernel (hd1,0)/boot/vmlinuz ro root=/dev/sda5
initrd /boot/initrd
title Windows
rootnoverify (hd0,0)
chainloader +1
default 0boots the first entry after the 10-secondtimeout.- The CentOS entry lives on the first partition of the second disk,
(hd1,0). - Text after the kernel path (
ro root=/dev/sda5) consists of kernel parameters. - The Windows entry uses
rootnoverifyand hands off withchainloader +1.
The initrd concept. The kernel may need a driver for the root disk’s controller or filesystem before it can mount root. The initial RAM disk (older kernels) or initial RAM filesystem, initramfs (kernel 2.6 and later), holds those modules in memory. The initrd keyword refers to either one.
Installing GRUB Legacy. Install it into the MBR once with grub-install. After that, GRUB Legacy rereads its configuration file on every boot, so editing the file doesn’t require reinstalling.
# grub-install /dev/sda # MBR of the first disk, Linux naming
# grub-install '(hd0)' # same disk, GRUB naming (quotes required)
# grub-install /dev/sda1 # a partition's boot sector, for chainloading
Using the menu. Use the arrow keys and Enter to choose an entry. To edit an entry for one boot: select it and press E, select a line and press E again, then press B to boot. Press C for the GRUB command line and Esc to return to the menu.
Configuring GRUB 2
- File name and location. The generated file is
grub.cfg. On BIOS systems it’s in/boot/grub/or/boot/grub2/. On UEFI systems it’s in/boot/efi/EFI/<distro-name>/. - Don’t edit
grub.cfg. It’s generated. Edit the global settings in/etc/default/grub(for example,GRUB_TIMEOUTandGRUB_CMDLINE_LINUX) and the menu-entry scripts in/etc/grub.d/, then regenerate the file. - Syntax changes. GRUB 2 uses
menuentry "Name" { ... }blocks and assigns values withset. - Partition numbering changes. Disks still start at 0, but partitions now start at 1.
(hd0,1)is the first partition of the first disk. You may also see'hd0,msdos1'for an MBR partition or'hd0,gpt1'for a GPT partition. - Non-Linux entries.
rootnoverifyis gone. Windows entries useset rootwithchainloader +1, just like any other entry.
| GRUB 2 command | Purpose |
|---|---|
menuentry |
Starts an entry; the title appears in the menu |
set root= |
Partition holding /boot |
linux, linux16 |
Kernel image on BIOS systems |
linuxefi |
Kernel image on UEFI systems |
initrd |
Initial RAM filesystem on BIOS systems |
initrdefi |
Initial RAM filesystem on UEFI systems |
menuentry "Fedora" {
set root=(hd0,1)
linux /vmlinuz-6.8.9 ro root=/dev/sda5
initrd /initramfs-6.8.9.img
}
menuentry "Windows" {
set root=(hd0,2)
chainloader +1
}
Rebuilding the configuration. GRUB 2 isn’t reinstalled after a change. Instead, you regenerate grub.cfg. grub-mkconfig (Debian family) and grub2-mkconfig (Red Hat family) are equivalent. Each one writes to standard output unless you use -o. Ubuntu’s update-grub runs grub-mkconfig -o /boot/grub/grub.cfg for you. Distributions also regenerate the file automatically after a kernel update and keep a menu entry for the previous kernel as a fallback.
$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg # Red Hat family
$ sudo update-grub # Ubuntu/Debian
Using the GRUB 2 menu. Some desktops hide the menu. Hold Shift (BIOS) or tap Esc (UEFI) during startup to show it.
| Menu key | Action |
|---|---|
| Arrows | Select an entry |
| Enter | Boot the selected entry |
| E | Edit the selected entry |
| C | Open the GRUB command line |
| P | Enter a password, if one is required |
| Editor key | Action |
|---|---|
| Arrows | Move to the line to change |
| Enter | Add a new line |
| Esc | Discard changes and return to the menu |
| Ctrl+C | Open the GRUB command line |
| Ctrl+X | Boot with the edited entry |
The editor also accepts basic emacs-style editing keys from Lesson 1.
Classroom convention
The book presents both GRUB versions because the exam covers both. In class, treat GRUB 2 as the working standard: edit /etc/default/grub, regenerate with grub-mkconfig -o (or grub2-mkconfig -o), and never hand-edit grub.cfg. Learn GRUB Legacy’s (hd0,0) numbering well enough to recognize it on the exam.
5. Kernel boot parameters
You can pass options to the kernel for a single boot by editing the menu entry. Go to the line starting with kernel (Legacy) or linux (GRUB 2), move to the end, add a space and the parameter, then boot. This is a key troubleshooting technique because nothing is changed permanently.
| Parameter | Effect |
|---|---|
console= |
Set the console device |
debug |
Enable kernel debugging |
init= |
Run a different program instead of /sbin/init, such as init=/bin/bash |
initrd= |
Use a different initial RAM filesystem |
mem= |
Set the total memory the kernel may use |
ro / rw |
Mount the root filesystem read-only or read-write |
root= |
Choose the root filesystem |
rootflags= |
Set mount options for root |
selinux=0 |
Disable SELinux for this boot |
single, S, or 1 |
Boot a SysVinit system into single-user mode |
systemd.unit= |
Boot a systemd system into a specific target, such as systemd.unit=rescue.target |
Security caution: Anyone at the console who can edit the boot entry can add init=/bin/bash and get a root shell without a password. This is why production servers protect GRUB with a password and why physical access counts as a security issue.
6. Alternative boot loaders
- LILO. The original Linux Loader. It couldn’t handle UEFI, and development ended in 2015.
- systemd-boot. A simple UEFI boot manager that is gaining use on systemd distributions. It can load any UEFI boot image.
- U-Boot (Das U-Boot). Common on embedded and ARM devices. It can boot from many kinds of storage.
- SYSLINUX project:
- SYSLINUX boots from FAT filesystems, such as USB flash drives.
- EXTLINUX boots from ext2/3/4 or Btrfs.
- ISOLINUX boots live CDs and DVDs.
- PXELINUX boots from a network server.
- MEMDISK boots old DOS images from the other loaders.
- EFI stub. Since kernel 3.3, UEFI can load a Linux kernel directly with no separate boot loader. This is uncommon because a boot loader offers more flexibility, especially for multi-boot systems.
7. The initialization process
After the kernel starts, it runs the initialization daemon. A service (or daemon) is a background program that performs a particular job. The init system decides which services start, in what order, and how they’re managed afterward.
- SysVinit. Based on Unix System V. It starts services in order using scripts. You’ll mostly find it on older servers.
- systemd. Introduced around 2010 and now the standard on major distributions. It starts services in parallel, which shortens boot time, and it can start services on demand.
- Upstart. Now defunct. It was used by some older releases, such as Ubuntu 6.10–15.04, RHEL 6, and Fedora 9–14. You may still see its
initctltool.
Which init system is this machine using?
The first process has process ID 1 (PID 1), and every service descends from it.
$ which init
/sbin/init
$ readlink -f /sbin/init
/usr/lib/systemd/systemd
$ ps -p 1
PID TTY TIME CMD
1 ? 00:00:06 systemd
$ pstree -p 1 | head
which initfinds the init program.readlink -ffollows symbolic links (Lesson 4) to the real program.ps -p 1shows what is actually running as PID 1. This is the most direct check.pstree -p 1shows every other process as a descendant of PID 1.
These checks aren’t foolproof, so use more than one. All the distributions recommended for this course use systemd.
8. systemd units and unit files
systemd changed how services are managed. Services can start at boot, when a device is attached, when another service starts, when a socket receives a connection, or on a timer.
Units
A unit is anything systemd manages: a service, a group of services, or an action. Every unit has a name, a type, and a configuration file, written as name.type. For example, the SSH daemon is sshd.service.
Unit types include service, target, socket, timer, mount, automount, swap, path, device, slice, scope, and the obsolete snapshot. Focus on service units (one daemon) and target units (groups of units).
$ systemctl list-units # units currently loaded
$ systemctl list-units --type=service # only services
$ systemctl list-unit-files # installed unit files and their states
$ systemctl --no-pager list-units # skip the less pager
Most systemctl output opens in less. Press Q to exit, or add --no-pager.
Where unit files live, and which one wins
When the same unit file exists in more than one place, the higher-priority location wins. Highest priority first:
/etc/systemd/system/holds administrator changes and always wins./run/systemd/system/holds runtime units that disappear at reboot./usr/lib/systemd/system/(or/lib/systemd/system/on some distributions) holds files installed by packages.
The book describes this list as being in “ascending priority order.” The order shown here is the correct one: /etc overrides /usr/lib. That rule is what makes local changes survive package updates.
Enablement states
systemctl list-unit-files shows each unit’s enablement state, which describes when it starts:
- enabled starts at boot.
- disabled doesn’t start at boot.
- static can’t be enabled by itself. It starts when another unit needs it, or manually.
Anatomy of a service unit file
$ systemctl cat sshd.service
# /usr/lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.target
Wants=sshd-keygen.target
[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
The first comment line shows where the file lives. Every service unit has three sections.
[Unit] holds general information and ordering:
| Directive | Meaning |
|---|---|
Description |
Human-readable description |
Documentation |
URIs for man pages or web documentation |
After / Before |
Start order relative to other units. These control order only, not whether the other unit starts. |
Requires |
Start the listed units too. If one fails, this unit doesn’t start. |
Wants |
Start the listed units too, but this unit starts even if they fail. |
Conflicts |
Never run at the same time as the listed units |
[Service] holds how to run the daemon. Only service units have this section. Other unit types have their own, such as [Mount] or [Timer].
| Directive | Meaning |
|---|---|
ExecStart |
Command to start the service |
ExecStop |
Command to stop it |
ExecReload |
Command to reload its configuration |
Type |
Startup type, such as simple, forking, or notify |
Environment / EnvironmentFile |
Environment variables, or a file of them. A leading - means “ignore if the file is missing.” |
Restart |
When to restart automatically: no, on-failure, always, and others |
RemainAfterExit |
yes keeps the unit “active” after the ExecStart process exits |
[Install] holds what happens on enable or disable:
| Directive | Meaning |
|---|---|
WantedBy |
The target that pulls this unit in when it’s enabled |
RequiredBy |
Units that require this one |
Alias |
Other names for the unit |
Also |
Other units to enable or disable with this one, often a .socket unit |
Teaching point: enable creates a symbolic link in the target’s .wants/ directory, based on WantedBy. That’s why WantedBy=multi-user.target means “start this at boot on a multi-user system.”
The main systemd configuration file is /etc/systemd/system.conf. Its defaults are shown commented out. See man systemd-system.conf, man systemd.service, man systemd.unit, and man systemd.directives.
Target units
Targets group units so they start together. They play the role that runlevels played in SysVinit. default.target is a symbolic link to the target used at boot.
$ systemctl get-default
graphical.target
$ systemctl cat graphical.target
[Unit]
Description=Graphical Interface
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes
Read that file as follows: the graphical target requires everything in the multi-user target, adds a display manager, can’t run alongside rescue mode, and (because of AllowIsolate=yes) can be switched to with systemctl isolate.
| Target | Meaning |
|---|---|
graphical.target |
Multi-user with networking and a GUI |
multi-user.target |
Multi-user with networking, no GUI (typical for servers) |
rescue.target |
Maintenance mode: local filesystems, root only, no networking |
emergency.target |
Minimal mode: root filesystem mounted read-only, root only |
runlevelN.target |
Compatibility aliases for SysV runlevels 0–6 |
Changing a unit file safely
- Never edit files under
/usr/lib/systemd/system/or/lib/systemd/system/. Package updates will overwrite them. - To replace a unit: copy it to
/etc/systemd/system/and edit the copy there. It takes precedence. - To add or override only a few directives: create a drop-in directory named
/etc/systemd/system/<unit>.d/, for example/etc/systemd/system/sshd.service.d/, and put asomething.conffile in it. The book prints this asservice.sshd.d. The correct name is the full unit name followed by.d.sudo systemctl edit sshdcreates the drop-in for you. - Review overrides:
systemd-deltalists units that are overridden, extended, or redirected. - Apply the changes: run
systemctl daemon-reload, then restart the service.
$ sudo systemctl edit sshd # opens an editor for a drop-in override
$ systemd-delta # list what overrides what
$ sudo systemctl daemon-reload # reread unit files
$ sudo systemctl restart sshd # apply to the running service
9. Managing services with systemctl
The general syntax is systemctl COMMAND UNIT-NAME.... The .service suffix is optional for services.
| Command | What it does |
|---|---|
start / stop |
Start or stop now |
restart |
Stop and start; starts the unit if it’s stopped |
reload |
Tell the service to reread its own configuration file (for example /etc/ssh/sshd_config) without stopping |
daemon-reload |
Make systemd reread unit files after you change them |
enable / disable |
Start, or don’t start, at boot. Add --now to also start or stop it immediately. |
mask / unmask |
Block, or unblock, a unit from starting at all, whether manually or as a dependency |
status |
Detailed status, including recent log lines |
The distinction students always mix up: reload is for the service’s configuration. daemon-reload is for systemd’s unit files. If you edited /etc/ntp.conf, run systemctl reload ntpd. If you edited ntpd.service, run systemctl daemon-reload.
The other distinction: start/stop affects right now, and enable/disable affects the next boot. They’re independent. A service can be running but disabled, or enabled but stopped.
Reading systemctl status
$ systemctl status sshd
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
Active: active (running) since Sat 2026-09-19 15:52:10 CDT
Main PID: 1130 (sshd)
CGroup: /system.slice/sshd.service
└─1130 /usr/sbin/sshd -D
- Loaded shows the unit file’s path and whether it’s enabled at boot.
- Active shows whether it’s running now.
- Main PID and CGroup show the actual process.
Quick status checks for scripts
| Command | Output |
|---|---|
is-active |
active, inactive, or failed |
is-enabled |
enabled, disabled, static, or masked |
is-failed |
failed if the unit failed; otherwise its current state |
# systemctl stop sshd
# systemctl is-active sshd
inactive
# systemctl start sshd
# systemctl is-active sshd
active
Services fail for many reasons, including hardware problems, missing dependencies, bad permissions, and configuration errors.
10. System-wide systemd commands
Overall health
$ systemctl is-system-running
degraded
$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● rngd.service loaded failed failed Hardware RNG Entropy Gatherer Daemon
| Status | Meaning |
|---|---|
running |
Everything is working |
degraded |
One or more units failed. Check systemctl --failed. |
maintenance |
Rescue or emergency mode |
initializing / starting |
Still booting |
stopping |
Shutting down |
Getting, setting, and switching targets
$ systemctl get-default # boot target
$ sudo systemctl set-default multi-user.target # change the boot target
$ sudo systemctl isolate multi-user.target # switch now
$ sudo systemctl default # go back to the default target
set-defaultchanges thedefault.targetlink, which takes effect at the next boot. The book writesset-targetin one sentence; the correct command isset-default.isolateswitches immediately. It stops everything not wanted by the new target and starts anything it needs. It works only with targets that haveAllowIsolate=yes.- Checking the current state.
systemctl get-defaultshows only the boot target. To see what’s active now, usesystemctl list-units --type=targetor check the status of the old target. - Short names. The
.targetsuffix can be omitted:systemctl isolate rescue.
Rescue and emergency targets
| Rescue target | Emergency target | |
|---|---|---|
| Filesystems | All local filesystems mounted | Only root, mounted read-only |
| Login | Root only | Root only |
| Networking | Off | Off |
| SysV equivalent | Single-user mode (runlevel 1) | None |
| Typical use | Repair disks and configuration | The system can’t even reach rescue mode |
Both modes report maintenance from is-system-running and require the root password. If root has no password, as on some Ubuntu setups, you can’t log in to these modes. Plan for that before you need them. The screen may go blank for a moment when switching, which is normal.
# systemctl isolate emergency
Welcome to emergency mode! After logging in, type "journalctl -xb" to view
system logs, "systemctl reboot" to reboot, "systemctl default" or ^D to
try again to boot into default mode.
Give root password for maintenance
You can also boot straight into one of these modes by adding systemd.unit=rescue.target or systemd.unit=emergency.target to the kernel line in GRUB. The reboot, poweroff, and halt targets also exist, so systemctl isolate reboot reboots the system.
11. SysVinit and runlevels
systemd is backward compatible with SysVinit, and administrators still migrate old servers. Students need to read and operate a SysVinit system even if they never build one.
Lab caution: Run old, unsupported distributions only inside a VM with no network adapter and no shared folders with the host.
Runlevels
SysVinit uses numbered runlevels where systemd uses targets. The meanings differ by distribution family.
| Runlevel | Red Hat family | Debian family |
|---|---|---|
| 0 | Halt / shut down | Halt / shut down |
| 1, s, S | Single-user maintenance (like rescue.target) | Single-user maintenance |
| 2 | Multi-user, no networking | Multi-user with GUI (2–5 are the same by default) |
| 3 | Multi-user with networking, text only | Same as 2 |
| 4 | Custom/unused | Same as 2 |
| 5 | Multi-user with GUI | Same as 2 |
| 6 | Reboot | Reboot |
Runlevels 0 and 6 aren’t really states that the system runs in. They’re transitions.
| Runlevel | systemd target |
|---|---|
| 0 | poweroff.target |
| 1 | rescue.target |
| 3 | multi-user.target |
| 5 | graphical.target |
| 6 | reboot.target |
How SysVinit decides what to start
# runlevel
N 5
# grep :initdefault: /etc/inittab
id:5:initdefault:
runlevelprints the previous and current runlevels.Nmeans there was no previous runlevel (fresh boot)./etc/inittabsets the default runlevel. In the lineid:5:initdefault:, the 5 is the default./etc/init.d/holds one executable script per service. Each script acceptsstart,stop,restart,reload, andstatus./etc/rc.d/rcN.d/(one directory for each runlevel, 0–6) holds symbolic links back to those scripts.- The
rcscript runs the links for the chosen runlevel. It runs everyKlink withstopfirst, then everySlink withstart.
# ls -1F /etc/rc.d/rc3.d/
K01smolt@
K02NetworkManager@
S04readahead_early@
S55cups@
S99local@
# readlink -f /etc/rc.d/rc3.d/S55cups
/etc/rc.d/init.d/cups
In S55cups, S means start (K means kill/stop), 55 is the order (lower runs earlier, similar to systemd’s Before/After), and cups is the service. Because the rc script stops and then starts services this way, it can also move a running system from one runlevel to another.
/etc/rc.localholds custom commands that run after all other startup scripts.- SysVinit scripts are Bash shell scripts. Lesson 9 teaches enough scripting to read them.
SysVinit commands
# init 3 # switch to runlevel 3 (telinit 3 is identical)
# runlevel
5 3
# init 0 # shut down
# init 6 # reboot
The service command runs a script in /etc/init.d/ by its base name: service SCRIPT COMMAND.
# service httpd status
httpd is stopped
# service httpd start
Starting httpd: [ OK ]
# service --status-all | less
service command |
Notes |
|---|---|
start / stop |
stop on an already-stopped service reports FAILED |
restart |
Stop, then start. The stop step reports FAILED if the service wasn’t running. |
reload |
Reread configuration without stopping. Fails on a stopped service. |
status |
Current state |
Teaching point: Many systemd distributions still accept service and init N as compatibility wrappers, but the results can be confusing. Use native systemctl commands on systemd systems.
12. Stopping the system
These commands work on any init system:
| Command | Effect |
|---|---|
halt |
Stop all processes and the CPU. The power may stay on. |
poweroff |
Stop everything and tell the hardware to power off |
reboot |
Stop everything and restart |
shutdown |
The most flexible tool: schedule, warn users, halt, power off, or reboot |
- On systemd systems,
halt,poweroff, andrebootare symbolic links tosystemctl. - Each of them can do the others’ jobs with
--halt,-p/--poweroff, or--reboot. - Power-off relies on ACPI signals. The
acpiddaemon handles hardware events such as pressing the power button or closing a laptop lid.
shutdown
shutdown [OPTIONS] TIME [WALL-MESSAGE]
$ sudo shutdown -r +10 "Rebooting for kernel update. Save your work."
$ sudo shutdown -P 22:30 # power off at 10:30 PM (24-hour time)
$ sudo shutdown -h now # halt immediately
$ sudo shutdown -c # cancel a pending shutdown
- Options:
-Hhalt,-Ppower off,-rreboot,-ccancel. - TIME:
hh:mmin 24-hour time,+nminutes from now, ornow. Without TIME, many distributions assume+1. - WALL-MESSAGE: Sent to every logged-in terminal.
- Default behavior: With no option, the behavior varies by distribution. Always state
-ror-P.
Stuck processes. Shutdown sends every process SIGTERM (Lesson 2) so programs can close their files cleanly. If one refuses to stop, check what it has open with lsof -p PID before resorting to kill -9 PID. SIGKILL can’t be caught, so the process has no chance to clean up.
13. Notifying users
Warn users before any change that will interrupt them, such as a reboot, a switch to rescue mode, or a service outage. Along with email or intranet announcements, Linux provides:
| Tool or file | When users see it |
|---|---|
/etc/issue |
On local terminal (tty) login screens, before login |
/etc/issue.net |
On remote login screens, before login |
/etc/motd |
“Message of the day,” shown after login on a terminal |
notify-send |
Desktop pop-up notification for GUI users |
wall |
Message written to every logged-in terminal (tty#) and terminal emulator (pts/#) whose message status is yes |
$ mesg # show your own status: "is y" or "is n"
$ mesg n # refuse wall messages
$ who -T # + after a name means that user can receive messages
$ wall
System reboot at 5:00 PM. Please save your work.
<Ctrl+D>
- After typing
wall, enter the message and press Ctrl+D to send it. You can also pipe text in:echo "text" | wall. - Recipients press Enter to get their prompt back.
- shutdown’s message ignores
mesg. It reaches every terminal, including users who turned messages off. Some distributions offer--no-wallto send it only to the administrator. - systemctl sends a wall message for
emergency,halt,poweroff,reboot, andrescueunless you add--no-wall.
14. Virtual machines and hypervisors
A virtual machine (VM) is a simulated computer that looks and acts like a physical machine to its users. Creating VMs is called virtualization. The machine running the VMs is the host, and each VM is a guest with its own guest operating system.
Hypervisors
A hypervisor (also called a virtual machine monitor or virtual machine manager, VMM) creates and runs VMs.
| Type 1 (“bare metal”) | Type 2 (“hosted”) | |
|---|---|---|
| Runs on | The hardware directly | An ordinary host operating system |
| Examples | KVM, Xen, Microsoft Hyper-V, VMware ESXi | Oracle VirtualBox, VMware Workstation Player |
| Typical use | Servers and data centers | Desktops, labs, learning |
| Resource planning | Hypervisor plus guests | Host OS plus hypervisor plus every guest |
- KVM has been built into the Linux kernel since 2.6.20. KVM and Hyper-V start from a running OS and then act as Type 1 hypervisors, so they don’t fit neatly in either category.
- With a Type 2 hypervisor, check that the host has enough RAM and CPU for itself and every VM.
- A VM is stored on the host as one file or a set of files, depending on the hypervisor. These files hold the configuration (RAM, CPUs, disks) and the virtual disk contents.
Creating VMs
- From scratch. Define the VM in the hypervisor and install from an ISO. This is how most people start.
- Clone. An identical copy of an existing VM under a new name.
- Template. A non-bootable master image used to create many VMs, built from a configured base VM’s system image.
- OVF/OVA. The Open Virtualization Format, a Distributed Management Task Force (DMTF) standard, exports a VM so another hypervisor can import it. An OVA is a single archive of the OVF files, which is convenient for transfers.
- P2V (physical-to-virtual). Tools that convert an existing physical machine into a VM.
virsh. A command-line and scriptable VM manager (requireslibvirt).virt-manageris its graphical counterpart.
Fix identity after cloning
A clone or template-based VM is an exact copy, so identifiers that should be unique aren’t. Before booting it on the same network, check:
- Host name
- NIC MAC address (Lesson 8)
- IP address, if static
- Machine ID (
/etc/machine-id) - Anything using a UUID
- Configuration files that reference any of these
# rm /etc/machine-id
# rm /var/lib/dbus/machine-id
# systemd-machine-id-setup # or: dbus-uuidgen --ensure
# ln -sf /etc/machine-id /var/lib/dbus/machine-id # if your distro expects the link
Why it matters: Two VMs with the same machine ID can cause DHCP conflicts when the network manager identifies itself by machine ID rather than MAC address. Follow your distribution’s documentation for regenerating identities.
Linux extensions for virtualization
- CPU hardware extensions let the hypervisor use the CPU directly. Check the CPU flags for
vmx(Intel) orsvm(AMD). Many hypervisors also need a 64-bit CPU, whichlscpuconfirms. - Firmware setting. Virtualization must be enabled in the firmware (BIOS/UEFI) setup, or VMs won’t run even on capable hardware.
- The
hypervisorflag. If this flag appears, you are already inside a VM.virt-whatorsystemd-detect-virtidentifies which hypervisor. - Kernel modules (Lesson 3). Load what your hypervisor requires. For KVM that’s
kvmpluskvm_intelorkvm_amd. - Guest additions. Inside the guest, install the hypervisor’s guest tools and drivers for shared folders, better graphics, mouse integration, and time sync.
$ grep -E -o 'vmx|svm|hypervisor' /proc/cpuinfo | sort -u
$ lscpu | grep -i -E 'architecture|virtualization'
$ lsmod | grep -i kvm
$ sudo modprobe kvm_amd
$ systemd-detect-virt # prints "none" on bare metal
15. Containers
A container is virtual, but it isn’t a VM. A VM includes a whole guest operating system. A container shares the host’s kernel and packages only the binaries and libraries its workload needs. A container engine manages containers instead of a hypervisor.
| Virtual machine | Container | |
|---|---|---|
| Managed by | Hypervisor | Container engine (Docker, Podman, LXC) |
| Includes | Full guest OS and kernel | App plus its libraries; uses the host kernel |
| Start time and size | Slower, larger | Faster, smaller |
| Guest OS | Can differ from the host (Windows on Linux) | Must work with the host kernel (Linux containers on Linux) |
- Application containers hold one application or stack, such as a web server. They’re central to DevOps: a developer changes the app in a new container, tests it, and swaps it into production, so development and production environments match and downtime is minimal.
- Operating system containers provide an isolated, complete Linux userspace. Administrators use them to test software on other distributions, or to try an upgraded distribution before upgrading the host.
- Docker is the most popular application container engine. LXC is common for OS containers. Both deploy containers from images.
Misconception to address: Virtualizing or containerizing an app doesn’t make it run faster. Containers make it faster to deploy. An “efficient” hypervisor is one with only a small performance penalty compared with bare metal.
16. Infrastructure as a Service and cloud terms
Running your own data center means paying for hardware, power, and cooling. Infrastructure as a Service (IaaS) providers supply the hypervisors and the data center (servers, storage, and networking), and you reach your VMs or containers over the Internet. Examples include Amazon Web Services (AWS), Google Compute Engine, Microsoft Azure, DigitalOcean, and Rackspace. Most let you choose data center regions near your customers and add regions for performance or disaster recovery.
Service models, from most to least customer control:
- IaaS: raw computing resources (CPU, memory, storage, network). You manage the OS and everything above it.
- PaaS (Platform as a Service): an OS and development platform on which you deploy your code.
- SaaS (Software as a Service): a finished application that you simply use.
A provider offering any of these is a cloud service provider (CSP).
| Term | Meaning |
|---|---|
| Computing (cloud) instance | One VM or container running on the cloud. Starting one is provisioning. |
| Public cloud | Instances reachable over the Internet or APIs, protected by virtual firewalls, gateways, and routers |
| Private cloud | Instances accessible only to their owner, still on the CSP’s infrastructure |
| Hybrid cloud | CSP instances combined with the company’s own data center |
| Elasticity | Automatic scaling. Horizontal: add or remove instances. Vertical: add or remove resources on an instance. |
| Load balancing | Spreading demand across multiple instances |
| Management console / portal | Web interface to create, start, stop, and monitor instances and set access |
| Block storage | Fixed-size volumes attached to an instance like a disk. Accessible only when mounted. |
| Object storage | Data accessed through the console or web APIs, with provider-managed protection |
| Remote access | SSH to the instance with a key pair instead of a password (Lesson 10) |
- cloud-init. Canonical’s industry-standard tool for giving each instance its identity at first boot (host name, users, SSH keys, packages, and scripts) from “user data.” It works on AWS, Azure, DigitalOcean, and others, as well as on local VMs under KVM or VMware. Install the
cloud-initpackage to explore it. - Not every CSP offers every feature. Compare providers against what the organization needs and can afford.
Classroom application
Use a disposable VM for anything that changes the boot configuration, targets, or runlevels, and take a snapshot first. Have students predict the result of each command before running it.
- Identify the platform. Report firmware type (
ls /sys/firmware/efi), init system (ps -p 1), default target (systemctl get-default), and whether the machine is virtual (systemd-detect-virt, or thehypervisorflag in/proc/cpuinfo). - Mine boot messages. Use
dmesg | grep -iandjournalctl -b -p errto find the root filesystem device, the kernel command line, and any errors from this boot. - Change GRUB safely. Change
GRUB_TIMEOUTin/etc/default/grub, regenerategrub.cfgwith the correct command for the distribution, and reboot to confirm. Then edit a menu entry at boot to addsystemd.unit=multi-user.targetfor one boot only, and explain why the change doesn’t persist. - Service life cycle. On a service such as
sshdorcron, practicestop/start,disable/enable,is-active/is-enabled, andmask/unmask. Record which commands change now and which change boot. - Override a unit. Use
systemctl editto addRestart=alwaysto a service, then confirm the override withsystemctl catandsystemd-delta. - Targets. Isolate
multi-user.targetfrom a GUI session, check the result withsystemctl list-units --type=target, and return withsystemctl default. - Scheduled shutdown with notice. Schedule
shutdown -r +15with a message, checkwho -Tfrom a second terminal, then cancel withshutdown -c. - Clone hygiene. Clone a lab VM and compare
/etc/machine-id, the MAC address, and the host name with the original. Fix each one on the clone.
Common misconceptions
- “UEFI loads the boot loader from the MBR.” UEFI loads
.efifiles from the FAT-formatted ESP, usually mounted at/boot/efi. The MBR is part of BIOS booting. - “Edit grub.cfg to change GRUB 2.”
grub.cfgis generated and gets overwritten. Edit/etc/default/grubor/etc/grub.d/, then rungrub-mkconfig -oorupdate-grub. - “GRUB Legacy and GRUB 2 number partitions the same way.” Legacy counts partitions from 0 and GRUB 2 from 1. Both count disks from 0.
- “reload and daemon-reload are the same.”
reloadrereads a service’s configuration.daemon-reloadmakes systemd reread unit files. - “Enabling a service starts it.”
enableaffects the next boot only, unless you add--now. - “
After=makes a unit start the other one.”After/Beforeset order only.Wants/Requirespull other units in. - “Files in /usr/lib/systemd/system override /etc.” The opposite is true:
/etc/systemd/system/has the highest priority. - “Runlevel 3 means the same thing everywhere.” Runlevel meanings differ between Red Hat and Debian families.
- “wall reaches everyone.” It reaches only users whose
mesgis y.shutdownmessages ignoremesg. - “A container is a lightweight VM with its own kernel.” Containers share the host kernel. VMs run their own.
- “Virtualization makes apps faster.” It makes them easier and faster to deploy, not faster to run.
Lesson summary
- Boot is a relay: firmware (POST, then BIOS/MBR or UEFI/ESP) → boot loader (GRUB 2 today) → kernel with its initramfs → init system (PID 1). Troubleshoot by finding the stage that failed, using
dmesgandjournalctl -b. - GRUB 2 is generated, not hand-edited: change
/etc/default/grubor/etc/grub.d/, regenerategrub.cfg, and use one-time kernel parameters at the menu for troubleshooting. - systemd manages units: unit files have
[Unit],[Service], and[Install]sections, local overrides belong in/etc/systemd/system/, targets replace runlevels, andsystemctlmanages everything. SysVinit’s runlevels,/etc/inittab, rc scripts,init/telinit, andservicestill matter for older systems. - Change state responsibly: use
shutdownwith a time and a message, and warn users withwall,/etc/motd, or/etc/issue. - Linux runs as a guest everywhere: know Type 1 vs. Type 2 hypervisors, clones, templates, and OVF/OVA; fix machine identity after cloning; know how containers differ from VMs; and know the core IaaS and cloud vocabulary.
The next lesson is Configuring the GUI, Localization, and Printing.
Course Notes