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.

  • linux
  • boot
  • grub
  • systemd
  • sysvinit
  • virtualization
  • lpic-1

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?

  1. Firmware. The firmware runs a Power-On Self-Test (POST) to check the hardware, then looks for a boot loader on a bootable device.
  2. Boot loader. The boot loader decides which Linux kernel to load and with which options.
  3. Kernel. The kernel loads into memory, prepares the system (including mounting the root filesystem), and starts the initialization program.
  4. 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 the less pager.
  • 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 .efi extension.
  • 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, and menu.lst is 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 0 boots the first entry after the 10-second timeout.
  • 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 rootnoverify and hands off with chainloader +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_TIMEOUT and GRUB_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 with set.
  • 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. rootnoverify is gone. Windows entries use set root with chainloader +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 initctl tool.

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 init finds the init program.
  • readlink -f follows symbolic links (Lesson 4) to the real program.
  • ps -p 1 shows what is actually running as PID 1. This is the most direct check.
  • pstree -p 1 shows 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:

  1. /etc/systemd/system/ holds administrator changes and always wins.
  2. /run/systemd/system/ holds runtime units that disappear at reboot.
  3. /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 a something.conf file in it. The book prints this as service.sshd.d. The correct name is the full unit name followed by .d. sudo systemctl edit sshd creates the drop-in for you.
  • Review overrides: systemd-delta lists 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-default changes the default.target link, which takes effect at the next boot. The book writes set-target in one sentence; the correct command is set-default.
  • isolate switches immediately. It stops everything not wanted by the new target and starts anything it needs. It works only with targets that have AllowIsolate=yes.
  • Checking the current state. systemctl get-default shows only the boot target. To see what’s active now, use systemctl list-units --type=target or check the status of the old target.
  • Short names. The .target suffix 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:
  • runlevel prints the previous and current runlevels. N means there was no previous runlevel (fresh boot).
  • /etc/inittab sets the default runlevel. In the line id:5:initdefault:, the 5 is the default.
  • /etc/init.d/ holds one executable script per service. Each script accepts start, stop, restart, reload, and status.
  • /etc/rc.d/rcN.d/ (one directory for each runlevel, 0–6) holds symbolic links back to those scripts.
  • The rc script runs the links for the chosen runlevel. It runs every K link with stop first, then every S link with start.
# 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.local holds 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, and reboot are symbolic links to systemctl.
  • Each of them can do the others’ jobs with --halt, -p/--poweroff, or --reboot.
  • Power-off relies on ACPI signals. The acpid daemon 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: -H halt, -P power off, -r reboot, -c cancel.
  • TIME: hh:mm in 24-hour time, +n minutes from now, or now. 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 -r or -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-wall to send it only to the administrator.
  • systemctl sends a wall message for emergency, halt, poweroff, reboot, and rescue unless 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 (requires libvirt). virt-manager is 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) or svm (AMD). Many hypervisors also need a 64-bit CPU, which lscpu confirms.
  • Firmware setting. Virtualization must be enabled in the firmware (BIOS/UEFI) setup, or VMs won’t run even on capable hardware.
  • The hypervisor flag. If this flag appears, you are already inside a VM. virt-what or systemd-detect-virt identifies which hypervisor.
  • Kernel modules (Lesson 3). Load what your hypervisor requires. For KVM that’s kvm plus kvm_intel or kvm_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-init package 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.

  1. 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 the hypervisor flag in /proc/cpuinfo).
  2. Mine boot messages. Use dmesg | grep -i and journalctl -b -p err to find the root filesystem device, the kernel command line, and any errors from this boot.
  3. Change GRUB safely. Change GRUB_TIMEOUT in /etc/default/grub, regenerate grub.cfg with the correct command for the distribution, and reboot to confirm. Then edit a menu entry at boot to add systemd.unit=multi-user.target for one boot only, and explain why the change doesn’t persist.
  4. Service life cycle. On a service such as sshd or cron, practice stop/start, disable/enable, is-active/is-enabled, and mask/unmask. Record which commands change now and which change boot.
  5. Override a unit. Use systemctl edit to add Restart=always to a service, then confirm the override with systemctl cat and systemd-delta.
  6. Targets. Isolate multi-user.target from a GUI session, check the result with systemctl list-units --type=target, and return with systemctl default.
  7. Scheduled shutdown with notice. Schedule shutdown -r +15 with a message, check who -T from a second terminal, then cancel with shutdown -c.
  8. 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 .efi files 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.cfg is generated and gets overwritten. Edit /etc/default/grub or /etc/grub.d/, then run grub-mkconfig -o or update-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.” reload rereads a service’s configuration. daemon-reload makes systemd reread unit files.
  • “Enabling a service starts it.” enable affects the next boot only, unless you add --now.
  • “After= makes a unit start the other one.” After/Before set order only. Wants/Requires pull 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 mesg is y. shutdown messages ignore mesg.
  • “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 dmesg and journalctl -b.
  • GRUB 2 is generated, not hand-edited: change /etc/default/grub or /etc/grub.d/, regenerate grub.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, and systemctl manages everything. SysVinit’s runlevels, /etc/inittab, rc scripts, init/telinit, and service still matter for older systems.
  • Change state responsibly: use shutdown with a time and a message, and warn users with wall, /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.