18 — Troubleshooting & Recovery
Things break. A service won't start, a disk fills up, boot fails, performance degrades. This chapter is your field guide for diagnosing and fixing Linux problems — the tools, the methodology, and the recovery procedures for when a system is truly stuck.
The Troubleshooting Methodology
- Don't panic, don't reboot (yet). Rebooting destroys evidence (logs, process state,
/proc). Gather information first. - Check the logs. The system tells you what's wrong —
journalctl,dmesg,/var/log/. Read the error. - Isolate the layer. Is it the network? Disk? The app? The kernel? Test each layer independently.
- Reproduce. If you can reproduce the issue, you can test fixes.
- Change one thing at a time. Multiple changes obscure which fix worked (or which broke something else).
- Have a rollback plan. Before changing a config, back it up.
- Document. Once fixed, record the cause and solution.
The First Questions
# Complex Implementation: system health snapshot in 10 commands
systemctl list-units --state=failed # failed services
journalctl -b -p err # current boot, errors only
journalctl -b -1 -p err # previous boot, errors (if rebooted)
dmesg --level=err,crit # kernel errors
uptime # load average
free -h # memory
df -h # disk space
df -i # inodes
ss -tlnp # listening ports
top -b -n 1 | head -20 # top processes
Common Problems & Solutions
"No space left on device"
# Complex Implementation: full disk-space diagnosis
df -h # which filesystem is full?
df -i # maybe inodes are full (not space)?
# Find the biggest consumers:
sudo du -sh /* 2>/dev/null | sort -rh | head
sudo du -sh /var/* 2>/dev/null | sort -rh | head
sudo ncdu / # interactive (if installed)
# Common culprits:
journalctl --disk-usage # journald size
sudo du -sh /var/log /var/cache /var/lib/docker 2>/dev/null
# Find deleted-but-open files (space not freed until fd closes):
sudo lsof +L1
# COMMAND PID USER FD SIZE NLINK NAME
# nginx 1234 root 9w 50G 0 /var/log/nginx/access.log (deleted)
# Fix: restart the process (closes the fd, frees the space)
sudo systemctl restart nginx
"Permission denied" (but permissions look right)
# Complex Implementation: multi-layer permission diagnosis
ls -l file # check owner, group, mode
namei -l /path/to/file # permissions on EACH path component (parent dirs!)
getfacl file # ACLs (might deny even if base perms allow)
ls -Z file # SELinux label (RHEL — SELinux might be blocking)
sudo ausearch -m AVC -ts recent # SELinux denials
lsattr file # extended attributes (immutable?)
Common causes:
- Parent directory lacks
x: you can't access a file if you can't traverse its parent.namei -lreveals this. - SELinux: "Permission denied" with correct Unix perms = SELinux. Check
ausearch -m AVC. - Immutable attribute:
chattr +i filemakes it undeletable. Check withlsattr, remove withchattr -i.
"Service won't start"
systemctl status nginx # status + last log lines
journalctl -u nginx -n 50 # full logs
sudo nginx -t # test config (if it has a config test)
systemctl cat nginx # see the unit file (ExecStart, etc.)
# Run the ExecStart command manually to see the error:
/usr/sbin/nginx -g 'daemon off;'
"Disk full" but du Doesn't Show It
# Complex Implementation: find deleted-but-open files hogging disk space
# — a process holds a large file OPEN but DELETED; space not freed until fd closes
sudo lsof +L1 # list open files with link count 0 (deleted but open)
# COMMAND PID USER FD SIZE NLINK NAME
# nginx 1234 root 9w 50G 0 /var/log/nginx/access.log (deleted)
# Fix: restart the process (closes the fd, frees the space)
sudo systemctl restart nginx
# Or truncate the file via /proc (without restarting):
sudo truncate -s 0 /proc/1234/fd/9
DNS Not Resolving
# Complex Implementation: full DNS diagnostic chain
dig example.com # direct DNS query (bypasses cache)
getent hosts example.com # via NSS (checks /etc/hosts, then DNS)
cat /etc/resolv.conf # nameservers
cat /etc/hosts # stale override?
cat /etc/nsswitch.conf | grep hosts # order: files dns?
ping 8.8.8.8 # is the network up?
dig @8.8.8.8 example.com # query a specific server
resolvectl status # systemd-resolved
sudo resolvectl flush-caches # flush DNS cache
"Read-only file system"
# The filesystem remounted itself read-only (ext4 does this on journal errors to prevent corruption)
mount | grep "ro," # which is read-only?
dmesg | grep -i "error\|ext4" # why? (disk errors, corruption)
sudo fsck /dev/sda1 # check + repair (must be unmounted)
sudo mount -o remount,rw / # try to remount read-write (if safe)
Recovery Procedures
Boot to Rescue Mode
At the GRUB menu:
- Press
eto edit the default entry. - Find the
linuxline. - Append
systemd.unit=rescue.target. Ctrl+Xto boot.
mount -o remount,rw / # if root is read-only
init=/bin/bash (When systemd is broken)
# No systemd, no services, root mounted read-only. Raw shell as PID 1:
mount -o remount,rw /
# fix the problem (e.g., edit /etc/fstab, reinstall a package)
sync
mount -o remount,ro /
exec /sbin/init # start systemd normally
Live USB / Rescue ISO + chroot
# Complex Implementation: chroot to fix an installed system from a live USB
sudo mount /dev/sda2 /mnt # root partition
sudo mount /dev/sda1 /mnt/boot/efi # ESP (if UEFI)
# For LVM:
sudo vgchange -a y # activate all LVM volumes
sudo mount /dev/vg_root/lv_root /mnt
# Bind-mount virtual filesystems for chroot:
sudo mount --bind /dev /mnt/dev
sudo mount --bind /dev/pts /mnt/dev/pts
sudo mount --bind /proc /mnt/proc
sudo mount --bind /sys /mnt/sys
sudo mount --bind /run /mnt/run
sudo chroot /mnt
# Now you're "inside" the installed system — apt/dnf, fsck, etc. work
exit
sudo reboot
Fixing a Broken fstab
# In emergency mode:
mount -o remount,rw /
journalctl -b | grep -i "mount\|fstab"
nano /etc/fstab # comment out the bad line
mount -a # test
systemctl default # continue boot
Diagnostic Tools
strace — Trace Syscalls
# Complex Implementation: find why a program can't open a file
strace -e trace=open,openat myapp 2>&1 | grep ENOENT
# openat(AT_FDCWD, "/etc/myapp/config.yaml", O_RDONLY) = -1 ENOENT (No such file or directory)
# Count syscalls (summary):
strace -c command
# Attach to a running process:
strace -p 1234
# Follow child processes:
strace -f command
lsof — List Open Files
sudo lsof /var/log/syslog # who has this file open?
sudo lsof -i :80 # what's using port 80?
sudo lsof -p 1234 # all files opened by PID 1234
sudo lsof +L1 # deleted but still open (disk space mystery)
tcpdump — Packet Capture
sudo tcpdump -i eth0 port 80 # capture port 80
sudo tcpdump -i eth0 host 8.8.8.8 # capture to/from a host
sudo tcpdump -i eth0 -w capture.pcap # save (for Wireshark)
sudo tcpdump -i any -n -A 'tcp port 80' # all interfaces, numeric, ASCII
sysrq (Magic SysRq) — REISUB
For when the system is completely frozen:
echo 1 | sudo tee /proc/sys/kernel/sysrq # enable
Mnemonic: REISUB (R-E-I-S-U-B) — the safe reboot sequence when frozen:
Alt+SysRq+r— take back control of keyboard from X.Alt+SysRq+e— SIGTERM all processes (except PID 1).Alt+SysRq+i— SIGKILL all processes.Alt+SysRq+s— sync all filesystems.Alt+SysRq+u— remount all filesystems read-only.Alt+SysRq+b— reboot (force).
Always s (sync) before b (reboot) to avoid data loss.
💡 Tips & Tricks
- Idiom: use
journalctl -b -p erras your first "what went wrong?" query — limits to current boot, errors only. Add--sincefor a time window. - Idiom: use
journalctl -b -1 -p errfor previous-boot debugging — when a reboot happened (crash, OOM), shows what happened before. - Idiom: use
lsof +L1to find deleted-but-open files — explains "disk full butdudoesn't show it." A process holds a large deleted file open; space not freed until fd closes. - Idiom: use
strace -e trace=open,openat <cmd> 2>&1 | grep ENOENTto find missing files — reveals exactly which path a program can't find. - Idiom: use
namei -l /path/to/fileto see permissions on each path component — reveals when a "Permission denied" is due to a parent directory lackingx, not the file itself. - Debug: use
sudo ausearch -m AVC -ts recentwhen SELinux blocks something — shows the exact denial. Common on RHEL. - Debug: REISUB is the safe reboot sequence when the system is frozen — always
s(sync) beforeb(reboot) to avoid data loss.
⚠️ Edge Cases & Gotchas
- Don't reboot immediately: rebooting destroys evidence (logs, process state,
/proc). Gather information first. - "Connection refused" vs "Connection timed out": refused = something is listening but refused you (port closed, or firewall REJECT). Timed out = nothing responded (firewall DROP, or network issue). The distinction matters.
fsckon a mounted filesystem can corrupt it: neverfscka mounted ext4/xfs. Unmount first, or boot from a live USB./var/logcan fill up: if logs aren't rotated,/var/logfills up, causing services to fail. SetSystemMaxUse=injournald.confand configurelogrotate.- Auth log locations differ by distro: Debian/Ubuntu uses
/var/log/auth.log; RHEL/Rocky uses/var/log/secure. Usejournalctl -u sshfor portability. dmesgis cleared on reboot: for persistent kernel logs, rely onjournalctl -k(which persists if journald is persistent).- Locked package manager:
sudo rm /var/lib/dpkg/lock-frontendonly if you're SURE no apt is running. Check withlsof /var/lib/dpkg/lock-frontendfirst.
🧠 Quick Quiz
A production server is suddenly unresponsive — SSH hangs, top freezes, even ls takes 30 seconds. You can't get a shell. The system doesn't respond to Ctrl+Alt+Del. What tool can save you, and what's the procedure?
Answer
Magic SysRq (REISUB) — the kernel's built-in emergency recovery mechanism, accessible even when the system is completely frozen.
Prerequisites: kernel.sysrq must be enabled (echo 1 | sudo tee /proc/sys/kernel/sysrq). If it's not enabled, you may not be able to use it (enable it in /etc/sysctl.d/ before you need it).
Procedure — REISUB:
- R (
Alt+SysRq+r) — take back control of the keyboard from X/display manager. - E (
Alt+SysRq+e) — SIGTERM all processes (except PID 1). Gives processes a chance to shut down gracefully. - I (
Alt+SysRq+i) — SIGKILL all processes that didn't respond to SIGTERM. - S (
Alt+SysRq+s) — sync all filesystems (flush dirty pages to disk). Wait for the disk light to stop. - U (
Alt+SysRq+u) — remount all filesystems read-only (clean state for reboot). - B (
Alt+SysRq+b) — reboot.
The critical steps are S (sync) and U (remount read-only) before B (reboot) — this prevents filesystem corruption.
If you don't have a SysRq key (some laptops don't), you can trigger via command line (if you have ANY shell access, even a serial console):
echo s | sudo tee /proc/sysrq-trigger # sync
echo u | sudo tee /proc/sysrq-trigger # remount ro
echo b | sudo tee /proc/sysrq-trigger # reboot
Why this matters: yanking the power on a frozen system can corrupt the filesystem (dirty pages not flushed). REISUB ensures a clean shutdown even when nothing else works.