🚨 Recovery Procedures

Backup & Recovery Series: Part 1 — Backup Strategies  |  Part 2 — rsync Deep Dive  |  Part 3 — Recovery Procedures

When Things Go Wrong at 3 AM

Recovery procedures are the documentation you wish you had written before things broke. A system that won't boot, a corrupted filesystem, a forgotten root password, a broken GRUB configuration — these situations are stressful enough without having to think through the steps from scratch under pressure.

This page is a reference for the most common recovery scenarios: entering rescue mode, resetting the root password, repairing GRUB, fixing filesystem corruption, recovering from a full disk, and restoring from backup. Read it before you need it.

Recovery Decision Tree

SymptomGo to
System won't boot — GRUB errorExample 2 — GRUB repair
System won't boot — kernel panic or fsck errorExample 3 — filesystem repair
System boots but hangs at systemdExample 1 — rescue/emergency mode
Forgot root passwordExample 4 — root password reset
Disk full — system degradedExample 5 — full disk recovery
Need to restore files from backupExample 6 — restore from backup
Accidental file deletionExample 7 — file recovery
Need to work on system from outsideExample 8 — live media / chroot

Examples

1
Rescue Mode and Emergency Mode

systemd provides two recovery targets for when normal boot fails:

# Method 1: Boot into rescue mode via GRUB
# At the GRUB menu, press 'e' to edit the boot entry
# Find the line starting with 'linux' and append:
# systemd.unit=rescue.target
# Press Ctrl-X to boot

# Method 2: Append to kernel line at GRUB
# systemd.unit=emergency.target  (even more minimal -- read-only root)

# Once in rescue/emergency mode:
systemctl list-units --failed    # see what failed
journalctl -xb                   # full boot log with explanations

# If filesystem is read-only in emergency mode, remount rw:
mount -o remount,rw /

# Fix the problem, then exit rescue mode
systemctl default    # try normal boot
# or reboot
reboot
Rescue vs Emergency: rescue.target mounts all local filesystems and starts basic services — most things work, root filesystem is read-write. emergency.target is more minimal — only the root filesystem mounted read-only, almost nothing running. Use emergency when rescue won't start due to filesystem corruption.
2
GRUB Repair
# Boot from rescue/live media first if GRUB is completely broken
# From rescue environment, mount the system and chroot in (see Example 8)

# Once you have a working shell (rescue mode or chroot):

# Reinstall GRUB to the MBR (BIOS systems)
sudo grub2-install /dev/sda
sudo grub2-mkconfig -o /boot/grub2/grub.cfg

# UEFI systems
sudo grub2-install --target=x86_64-efi --efi-directory=/boot/efi
sudo grub2-mkconfig -o /boot/grub2/grub.cfg

# On Debian/Ubuntu
sudo grub-install /dev/sda
sudo update-grub

# Regenerate GRUB config (after kernel update or config change)
sudo grub2-mkconfig -o /boot/grub2/grub.cfg    # RHEL
sudo update-grub                                # Debian/Ubuntu

# View current GRUB entries
sudo awk -F\' '/menuentry / {print $2}' /boot/grub2/grub.cfg

# Set default boot entry
sudo grub2-set-default 0    # boot first entry by default
sudo grub2-editenv list     # view saved default
⚠️ Know your disk device name before running grub-install. Running grub-install /dev/sdb when you meant /dev/sda overwrites the wrong disk's MBR. Verify with lsblk or fdisk -l before installing. On UEFI systems verify the EFI partition is mounted at /boot/efi first.
3
Filesystem Repair with fsck
# fsck runs automatically on boot if filesystem is unclean
# To run manually the filesystem MUST be unmounted first

# Check which filesystem needs repair (from boot error or dmesg)
dmesg | grep -i "error\|corrupt\|bad block"
journalctl -b | grep -i "fsck\|ext4\|xfs"

# Unmount before fsck (NEVER run fsck on a mounted filesystem)
sudo umount /dev/sdb1

# Run fsck -- automatically fix errors
sudo fsck -y /dev/sdb1           # ext2/3/4 -- -y answers yes to all
sudo fsck.ext4 -y /dev/sdb1     # explicit ext4
sudo xfs_repair /dev/sdb1       # XFS filesystems

# If root filesystem needs repair -- boot to rescue/emergency
# then remount read-only and run fsck:
mount -o remount,ro /
fsck -y /dev/sda1

# Force fsck on next boot (for root filesystem)
sudo touch /forcefsck           # older method
sudo tune2fs -C 1 /dev/sda1     # set mount count to trigger fsck
sudo shutdown -rF now           # reboot with forced fsck

# Check filesystem health without repairing
sudo fsck -n /dev/sdb1          # dry run -- report only
sudo tune2fs -l /dev/sda1 | grep -i "state\|mount count\|check"
⚠️ Never run fsck on a mounted filesystem. Running fsck on a mounted filesystem will corrupt it further. Always unmount first, or boot to rescue/emergency mode for the root filesystem. XFS cannot be repaired while mounted — use xfs_repair after unmounting.
4
Reset the Root Password
# Method 1: Via GRUB (physical/console access required)

# Step 1: Reboot. At GRUB menu press 'e' to edit
# Step 2: Find the line starting with 'linux'
# Step 3: At the END of that line, add:
#    rd.break
# Step 4: Press Ctrl-X to boot
# You will get a root shell before the filesystem mounts rw

# Step 5: Remount root rw and change password
mount -o remount,rw /sysroot
chroot /sysroot

# Step 6: Change root password
passwd root

# Step 7: If SELinux is enabled, relabel on next boot
touch /.autorelabel

# Step 8: Exit and reboot
exit
reboot

# Method 2: From rescue media / live boot
# Boot live media, mount the system, chroot in (see Example 8)
# Then simply: passwd root
The /.autorelabel touch is critical on SELinux systems. Changing the password in rd.break mode creates the /etc/shadow file with incorrect SELinux contexts. Without touch /.autorelabel, SELinux will deny access to the new password on next boot and login will still fail. The relabel adds several minutes to the next boot — this is normal.
5
Emergency Disk Space Recovery

The system is degraded because a filesystem is full. Services are failing. You need space right now:

# Find what is using space -- fast
df -h                              # which filesystem is full?
du -sh /* 2>/dev/null | sort -rh | head -10    # top directories
du -sh /var/* | sort -rh | head -10
du -sh /var/log/* | sort -rh | head -10

# Find the largest files on a filesystem
find /var -type f -size +100M -ls 2>/dev/null | sort -k7 -rn
find / -xdev -type f -size +500M -ls 2>/dev/null

# Quick wins -- safe things to remove

# Clean package cache
sudo dnf clean all          # RHEL -- can free GBs
sudo apt clean              # Debian

# Remove old kernel packages (keep current + 1)
sudo dnf remove $(dnf repoquery --installonly --latest-limit=-2 -q)

# Truncate (not delete) a log that is too large
# DO NOT delete -- the process has it open
sudo truncate -s 0 /var/log/hugefile.log

# Vacuum the systemd journal
sudo journalctl --vacuum-size=100M

# Find and remove old core dumps
sudo find /var/lib/systemd/coredump -type f -delete
sudo find / -name "core" -type f -ls 2>/dev/null

# Check for deleted files still held open (not releasing space)
sudo lsof | grep deleted | awk '{print $7, $9}' | sort -rn | head -10
# Restart the process holding the deleted file to release space
💡 Truncate, don't delete open log files. If a process has a log file open and you delete it, the file appears gone from the directory but the process still holds it open and keeps writing to it — the disk space is not released until the process closes it. Use truncate -s 0 to empty the file while it stays open. The space is freed immediately.
6
Restore from Backup
# Restore a single file from tar backup
tar -tzf /backup/etc-20260425.tar.gz | grep "nginx.conf"
tar -xzf /backup/etc-20260425.tar.gz -C / etc/nginx/nginx.conf

# Restore a directory from tar backup
tar -xzf /backup/www-20260425.tar.gz -C /restore/
# Then verify before moving to production:
diff -r /restore/var/www/html/ /var/www/html/
mv /var/www/html/ /var/www/html.broken/
mv /restore/var/www/html/ /var/www/html/

# Restore from rsync snapshot
ls /backup/snapshots/           # pick the right date
rsync -av /backup/snapshots/2026-04-25/ /var/www/html/

# Restore specific files from rsync snapshot
rsync -av /backup/snapshots/2026-04-25/config/ /var/www/html/config/

# Restore MySQL database
gunzip -c /backup/mysql-20260425.sql.gz | mysql -u root -p
# Restore single database
gunzip -c /backup/mysql-20260425.sql.gz | grep -A99999 "Current Database: \`mydb\`" | \
    grep -B99999 "Current Database:" | head -n -2 | mysql -u root -p mydb

# Restore PostgreSQL
gunzip -c /backup/postgres-20260425.sql.gz | psql -U postgres
Always restore to a staging location first. Never restore directly over production files without verifying the backup is complete and correct. Restore to /restore/ or a staging server, verify, then move to production. A restore that makes things worse is worse than the original problem.
7
Recover Accidentally Deleted Files
# First check -- is it still open by a process?
sudo lsof | grep deleted | grep myfile
# If found: copy from /proc/PID/fd/FD before the process closes it
sudo cp /proc/12345/fd/3 /recovered/myfile.txt

# extundelete -- recover deleted files from ext3/ext4
sudo dnf install -y extundelete
sudo umount /dev/sdb1     # must be unmounted
sudo extundelete /dev/sdb1 --restore-all
# Recovered files appear in ./RECOVERED_FILES/

# testdisk -- recover lost partitions and files
sudo dnf install -y testdisk
sudo testdisk /dev/sda    # interactive partition recovery

# photorec -- recover files by signature (works on any filesystem)
sudo photorec /dev/sdb1

# Check if file is in a snapshot (LVM snapshot or rsync snapshot)
ls /backup/snapshots/2026-04-24/var/www/html/deletedfile.php

# Check if file is in the backup from yesterday
tar -tzf /backup/www-20260424.tar.gz | grep deletedfile
⚠️ Stop writing to the filesystem immediately. Every write to the filesystem after a deletion can overwrite the deleted file's data blocks. Unmount the filesystem as soon as possible after accidental deletion. The more you write, the less recoverable the file becomes. If it is the root filesystem, boot from rescue media.
8
Chroot from Live Media — The Universal Recovery Tool

When you need to work on a broken system from outside — boot from a live USB or rescue media, then chroot into the installed system:

# Boot from RHEL/Rocky rescue media or any live Linux USB

# Step 1: Identify your disks and partitions
lsblk
fdisk -l

# Step 2: Mount the root filesystem
mount /dev/sda2 /mnt/sysroot      # adjust device as needed

# Step 3: Mount boot partition if separate
mount /dev/sda1 /mnt/sysroot/boot
mount /dev/sda1 /mnt/sysroot/boot/efi    # UEFI systems

# Step 4: Bind mount virtual filesystems
mount --bind /dev  /mnt/sysroot/dev
mount --bind /proc /mnt/sysroot/proc
mount --bind /sys  /mnt/sysroot/sys
mount --bind /run  /mnt/sysroot/run

# Step 5: Chroot into the system
chroot /mnt/sysroot /bin/bash

# Now you are inside the broken system with full access
# Run any repair commands:
passwd root                        # reset root password
grub2-install /dev/sda             # fix GRUB
grub2-mkconfig -o /boot/grub2/grub.cfg
dnf reinstall kernel               # reinstall kernel
vi /etc/fstab                      # fix bad fstab entry

# Step 6: Exit chroot and unmount
exit
umount /mnt/sysroot/dev
umount /mnt/sysroot/proc
umount /mnt/sysroot/sys
umount /mnt/sysroot/run
umount /mnt/sysroot/boot
umount /mnt/sysroot
reboot
chroot is your master key. From a live boot environment you can fix almost anything — reset passwords, repair GRUB, fix a bad /etc/fstab, reinstall packages, edit configuration files. The chroot procedure above is the same regardless of what you are fixing. Learn it once, use it for everything.

Quick Reference

SituationFirst Command
Boot fails at systemdAdd systemd.unit=rescue.target to GRUB kernel line
Filesystem corruption at bootAdd systemd.unit=emergency.target to GRUB kernel line
Fix GRUBgrub2-install /dev/sda && grub2-mkconfig -o /boot/grub2/grub.cfg
Repair filesystemumount /dev/sdXN && fsck -y /dev/sdXN
Reset root passwordAdd rd.break to GRUB, then mount -o remount,rw /sysroot && chroot /sysroot && passwd
Disk full emergencydu -sh /* | sort -rh then dnf clean all or truncate -s 0 bigfile.log
Deleted file still openlsof | grep deleted then cp /proc/PID/fd/N /recovered/file
Restore from tartar -xzf backup.tar.gz -C /restore/ path/to/file
Work on broken systemBoot live media, mount, bind-mount /dev /proc /sys, chroot