EX342 Practice ExamLesson 2 of 4
Part A: Boot, storage and evidence (100 points)
Eight tasks: emergency mode, boot arguments, kdump, web console and sos, a lost root password, damaged file systems, LVM and space.
journalctlgrubbykdumpctlcockpitsos reportrd.breakxfs_repaire2fsckvgcfgrestoredf -ilsof
After this lesson you can
- Repair the start-up, storage and space faults of the exam within about 80 minutes, and prove each with its checks.
Setup for Part A
Run as root on node1 last, after the common preparation and the Part C and Part B setups. The last lines reboot the machine into emergency mode on purpose (task A1). Do not read the setup for hints about the faults before you try the tasks: it is here so that you can rebuild the exam.
# --- A6: two damaged file systems on vdb
sfdisk /dev/vdb <<'EOT'
label: gpt
,1G
,
EOT
mkfs.xfs -q -f /dev/vdb1
mkfs.ext4 -q -F -b 4096 /dev/vdb2
mkdir -p /mnt/s
mount /dev/vdb1 /mnt/s && echo ledger-xfs-1 > /mnt/s/ledger.txt && umount /mnt/s
mount /dev/vdb2 /mnt/s && echo ledger-ext4-1 > /mnt/s/ledger.txt && umount /mnt/s
dd if=/dev/zero of=/dev/vdb1 bs=512 count=1 conv=notrunc 2>/dev/null
dd if=/dev/zero of=/dev/vdb2 bs=4096 count=1 conv=notrunc 2>/dev/null
# --- A7: a volume group whose label is wiped
pvcreate -ff -y /dev/vdc && vgcreate vgdata /dev/vdc && lvcreate -y -n lvdata -L 500M vgdata
mkfs.xfs -q /dev/vgdata/lvdata
mount /dev/vgdata/lvdata /mnt/s && echo ledger-lvm-1 > /mnt/s/ledger.txt && umount /mnt/s
vgcfgbackup vgdata && vgchange -an vgdata
dd if=/dev/zero of=/dev/vdc bs=512 count=2 conv=notrunc 2>/dev/null
# --- A8: inode exhaustion on vdd, and a service that holds a deleted file
mkfs.ext4 -q -F -N 256 /dev/vdd
mkdir -p /srv/spool && mount /dev/vdd /srv/spool
for i in $(seq 1 20); do echo "data $i" > /srv/spool/keep-$i.dat; done
for i in $(seq 1 400); do : > /srv/spool/stale-$i.tmp 2>/dev/null || break; done
echo "UUID=$(blkid -s UUID -o value /dev/vdd) /srv/spool ext4 defaults 0 2" >> /etc/fstab
cat > /usr/local/sbin/exporter <<'EOT'
#!/bin/bash
if [ ! -e /run/exporter.done ]; then
dd if=/dev/zero of=/var/tmp/export.dat bs=1M count=300 status=none
exec 3</var/tmp/export.dat; rm -f /var/tmp/export.dat; touch /run/exporter.done
fi
exec sleep infinity
EOT
chmod 755 /usr/local/sbin/exporter
cat > /etc/systemd/system/exporter.service <<'EOT'
[Unit]
Description=Export job
[Service]
ExecStart=/usr/local/sbin/exporter
[Install]
WantedBy=multi-user.target
EOT
systemctl daemon-reload && systemctl enable --now exporter
# --- A5: node2 has an unknown root password
ssh root@node2.lab.example "echo root:\$(openssl rand -base64 18) | chpasswd"
# --- A1 (last): a bad fstab line, then reboot into emergency mode
echo "UUID=00000000-0000-0000-0000-000000000000 /backup xfs defaults 0 0" >> /etc/fstab
mkdir -p /backup
systemctl reboot
The setup makes /dev/vdb1 and /dev/vdb2 unmountable, wipes the label of /dev/vdc, fills the inodes of /dev/vdd, runs a service that holds a 300 MB deleted file, and sets an unknown root password on node2. The tasks do not mention any of that.
Part A marking
| Task | Points | Earned |
|---|---|---|
| A1 Emergency mode | 12 | |
| A2 Journal and arguments | 10 | |
| A3 kdump | 10 | |
| A4 Console and sos | 12 | |
| A5 Root password (node2) | 12 | |
| A6 XFS and ext4 repair | 16 | |
| A7 LVM restore | 16 | |
| A8 Space | 12 | |
| Part A | 100 |
Practice
0 of 8 done
Do these on your own system. They get harder. Check each result, then tick it off.
- Warm-up
A1 · Recover node1 from emergency mode (12 points, 10 min)
After the setup, node1 boots into emergency mode. Log in with the root password and:
- Find out which entry stopped the boot, and why.
- Repair
/etc/fstabso that the machine reaches the default target. Do not delete lines that belong to working file systems. - The data disk that the failed line referred to is not installed: if the file system is optional, boot must not wait for it for more than 5 seconds; if it does not exist, remove the line.
- Continue to the normal target without reinstalling anything.
Check your result
systemctl is-system-runningprintsrunning(ordegradedwith no failed mount units).findmnt --verifyprints no[E]lines.grep -c backup /etc/fstabis0, or the line hasnofailandx-systemd.device-timeout=5.systemctl --failed --no-legend | wc -lprints0.- The line for
/srv/spool(created by A8's setup) is still present and valid.
Hint
journalctl -xb | grep -i mountnames the unit. Emergency mode mounts/read-only:mount -o remount,rw /first. Thensystemctl daemon-reloadandsystemctl default.Solution
journalctl -xb --no-pager | grep -iE 'backup|Dependency failed' | head mount -o remount,rw / findmnt --verify sed -i '\#^UUID=0000.* /backup #d' /etc/fstab systemctl daemon-reload findmnt --verify systemctl default - Practice
A2 · Persistent journal and boot arguments (10 points, 8 min)
On node1:
- The journal must survive reboots.
- For all installed kernels, remove
rhgbandquiet, and addaudit=1. - The default boot kernel must be the one currently running.
- Write the name of the unit that took longest to start during the current boot into
/root/slowest.txt(one line, the unit name only).
Check your result
ls -d /var/log/journalexists, andjournalctl --list-boots | wc -lis at least2after the final reboot.sudo grubby --info=ALL | grep ^argscontainsaudit=1and norhgborquieton every entry.sudo grubby --default-kernelequals/boot/vmlinuz-$(uname -r).cat /root/slowest.txtequals the first unit ofsystemd-analyze blamefor that boot.
Hint
mkdir -p /var/log/journal && systemctl restart systemd-journald.grubby --update-kernel=ALL --args=... --remove-args=.... The blame list is sorted, longest first.Solution
sudo mkdir -p /var/log/journal && sudo systemd-tmpfiles --create --prefix /var/log/journal sudo systemctl restart systemd-journald sudo grubby --update-kernel=ALL --args="audit=1" --remove-args="rhgb quiet" sudo grubby --set-default /boot/vmlinuz-$(uname -r) systemd-analyze blame --no-pager | head -1 | awk '{print $NF}' | sudo tee /root/slowest.txt sudo grubby --info=ALL | grep -E '^(args|index)' - Practice
A3 · Capture-ready kdump (10 points, 10 min)
On node1, configure the machine so that a kernel crash is captured:
- Install what is needed and make sure memory is reserved for the capture kernel (use the default for this machine's memory unless you can justify a number).
- Dumps are written to
/var/crash, usingmakedumpfilewith zero pages, cache pages and free pages excluded (-d 31) and compression. - The service starts at boot and reports operational after the reboot.
Check your result
rpm -q kexec-toolsis installed;grep -o 'crashkernel=[^ ]*' /proc/cmdlineis non-empty after the final reboot.grep -E '^path /var/crash' /etc/kdump.confandgrep -E '^core_collector .*-d 31' /etc/kdump.conf.systemctl is-enabled kdumpisenabled;sudo kdumpctl statusprintsKdump is operational.
Hint
kdumpctl reset-crashkernel --kernel=ALLsets the default reservation; it applies at the next boot.core_collector makedumpfile -l --message-level 7 -d 31is the usual line. Restartkdumpafter editing the file.Solution
sudo dnf install -y kexec-tools grep -o 'crashkernel=[^ ]*' /proc/cmdline || sudo kdumpctl reset-crashkernel --kernel=ALL sudo sed -i -E 's|^#?path .*|path /var/crash|; s|^#?core_collector .*|core_collector makedumpfile -l --message-level 7 -d 31|' /etc/kdump.conf sudo systemctl enable --now kdump sudo systemctl reboot # after the reboot sudo kdumpctl status - Practice
A4 · Web console, metrics and a support archive (12 points, 10 min)
On node1:
- Install the web console and make it available at boot. It must be reachable on port 9090 from other hosts through the firewall (permanently).
- Metrics history must be recorded and survive reboots (the console's history page must work).
- Create a support archive for case
EX342-A4, containing only thenetworking,systemdandselinuxplugin data, written to/root/cases, without being asked any question. Keep the checksum file beside it.
Check your result
systemctl is-enabled cockpit.socketisenabled;sudo firewall-cmd --permanent --list-servicescontainscockpit.systemctl is-enabled pmloggerisenabledandsystemctl is-active pmloggerisactive;rpm -q cockpit-pcp.ls /root/cases/sosreport-EX342-A4.tar.xzand the matching.sha256file exist.tar tfof the archive showssos_commands/networking/,sos_commands/systemd/andsos_commands/selinux/but nosos_commands/kernel/entries.
Hint
systemctl enable --now cockpit.socket;firewall-cmd --permanent --add-service=cockpitthen--reload.sos report --batch --case-id EX342-A4 -o networking,systemd,selinux --tmp-dir /root/cases.Solution
sudo dnf install -y cockpit cockpit-pcp sos sudo systemctl enable --now cockpit.socket pmlogger sudo firewall-cmd --permanent --add-service=cockpit && sudo firewall-cmd --reload sudo mkdir -p /root/cases sudo sos report --batch --case-id EX342-A4 -o networking,systemd,selinux --tmp-dir /root/cases ls /root/cases tar tf /root/cases/sosreport-*EX342-A4*.tar.xz | grep -c 'sos_commands/kernel' || true - Practice
A5 · Reset the root password of node2 (12 points, 10 min)
Nobody knows the root password of node2. Using only its console:
- Set the root password of
node2toEx342!Resetwithout logging in first. - After the change the system must still be fully functional: SELinux enforcing, correct labels on the authentication files, and the machine booted to its default target.
Check your result
- The hash of root on node2 differs from the one before the task, and matches the password:
ssh alex@node2.lab.example "sudo python3 -c \"import crypt,spwd; h=spwd.getspnam('root').sp_pwdp; print(crypt.crypt('Ex342!Reset', h)==h)\""printsTrue(or log in on the console as root with the new password). ssh alex@node2.lab.example getenforceprintsEnforcing;ssh alex@node2.lab.example sudo ls -Z /etc/shadowshowsshadow_t.ssh alex@node2.lab.example ls /.autorelabelreports no such file (the relabel has run).ssh alex@node2.lab.example systemctl get-defaultismulti-user.target(or the graphical target the lab uses) andis-system-runningisrunning.
Hint
Edit the kernel line in GRUB and add
rd.break. At the prompt:mount -o remount,rw /sysroot,chroot /sysroot,passwd root,touch /.autorelabel,exit,exit. The relabel takes a minute or two.Solution
GRUB: e -> add rd.break to the "linux" line -> Ctrl+xmount -o remount,rw /sysroot chroot /sysroot passwd root # Ex342!Reset touch /.autorelabel exit exit - Set the root password of
- Practice
A6 · Repair a damaged XFS and a damaged ext4 (16 points, 12 min)
On node1, partitions
/dev/vdb1(XFS) and/dev/vdb2(ext4) refuse to mount andblkidshows nothing for them. Each holds a fileledger.txtthat must not be lost.- Repair both file systems. Do not re-create (
mkfs) either of them. For ext4 use a backup superblock; find its location without writing to the device. - Mount them permanently, by UUID, on
/srv/ledger-xfsand/srv/ledger-ext4. - Write the superblock number you used for ext4 into
/root/sb.txt.
Check your result
cat /srv/ledger-xfs/ledger.txtprintsledger-xfs-1;cat /srv/ledger-ext4/ledger.txtprintsledger-ext4-1.findmnt -no FSTYPE,SOURCE /srv/ledger-xfs /srv/ledger-ext4showsxfsandext4;grep -E 'ledger-(xfs|ext4)' /etc/fstabusesUUID=.sudo e2fsck -fn /dev/vdb2ends without errors andxfs_repair -n /dev/vdb1ends clean (unmount first for the check).cat /root/sb.txtcontains32768(or another valid backup number printed bymke2fs -n -b 4096 /dev/vdb2).findmnt --verifyshows no[E]lines.
Hint
xfs_repair -nfirst, thenxfs_repair. For ext4:mke2fs -n -b 4096 /dev/vdb2lists backups (with-nit only prints), thene2fsck -fy -b NUMBER /dev/vdb2. Rune2fsck -fnagain to confirm.Solution
sudo blkid /dev/vdb1 /dev/vdb2; echo "rc=$?" sudo xfs_repair -n /dev/vdb1 | head -8 sudo xfs_repair /dev/vdb1 sudo mke2fs -n -b 4096 /dev/vdb2 | tail -3 sudo e2fsck -fy -b 32768 /dev/vdb2 | tail -4 echo 32768 | sudo tee /root/sb.txt sudo e2fsck -fn /dev/vdb2 | tail -1 sudo mkdir -p /srv/ledger-xfs /srv/ledger-ext4 printf 'UUID=%s /srv/ledger-xfs xfs defaults 0 0\nUUID=%s /srv/ledger-ext4 ext4 defaults 0 2\n' \ "$(sudo blkid -s UUID -o value /dev/vdb1)" "$(sudo blkid -s UUID -o value /dev/vdb2)" | sudo tee -a /etc/fstab sudo systemctl daemon-reload && sudo mount -a cat /srv/ledger-xfs/ledger.txt /srv/ledger-ext4/ledger.txt - Repair both file systems. Do not re-create (
- Practice
A7 · Restore a lost LVM label and metadata (16 points, 12 min)
The volume group
vgdata(on/dev/vdc) has vanished:pvsandvgsshow nothing for that disk. The logical volumelvdataheld an XFS file system with a fileledger.txt.- Restore the physical volume and the volume group using the metadata backup LVM keeps. Do not create a new volume group.
- Activate the logical volume and mount it permanently on
/srv/ledger-lvm. - Keep the original UUIDs: the file system must contain the original
ledger.txt.
Check your result
sudo vgs vgdatashows1PV and1LV;sudo lvs vgdata/lvdatashows thea(active) attribute.cat /srv/ledger-lvm/ledger.txtprintsledger-lvm-1.findmnt /srv/ledger-lvmshows source/dev/mapper/vgdata-lvdata;grep ledger-lvm /etc/fstabhas the entry.sudo pvs -o pv_uuid /dev/vdcequals the UUID in thepv0 { id = ... }block of/etc/lvm/backup/vgdata.
Hint
The PV UUID is in the
pv0block of/etc/lvm/backup/vgdata, not the firstid =(that is the VG).pvcreate -ff --uuid PVUUID --restorefile /etc/lvm/backup/vgdata /dev/vdc, thenvgcfgrestore vgdata, thenvgchange -ay vgdata. If LVM still ignores the disk, checklvmdevices.Solution
sudo pvs; sudo vgs # nothing for vdc sudo vgcfgrestore --list vgdata PVU=$(sudo awk '/pv0 \{/{f=1} f&&/id = /{gsub(/"/,"",$3); print $3; exit}' /etc/lvm/backup/vgdata) sudo pvcreate -ff -y --uuid "$PVU" --restorefile /etc/lvm/backup/vgdata /dev/vdc sudo vgcfgrestore vgdata sudo lvmdevices --adddev /dev/vdc 2>/dev/null || true sudo vgchange -ay vgdata sudo mkdir -p /srv/ledger-lvm echo '/dev/mapper/vgdata-lvdata /srv/ledger-lvm xfs defaults 0 0' | sudo tee -a /etc/fstab sudo systemctl daemon-reload && sudo mount /srv/ledger-lvm cat /srv/ledger-lvm/ledger.txt - Challenge
A8 · Space that cannot be used (12 points, 8 min)
Two space problems on node1:
- Nothing can be created in
/srv/spool(No space left on device) althoughdf -h /srv/spoolshows plenty free. Fix it by removing only the stale files (stale-.tmp); thekeep-.datfiles must stay. Then add a daily job (cron or systemd timer, your choice) that deletesstale-*.tmpfiles older than one day from that directory. df -h /varshows about 300 MB used by something thatdu -sh /varcannot find. Release that space without rebooting and without restoring a file; the cause must not return at the next restart of the offending service.
Check your result
touch /srv/spool/newfilesucceeds;ls /srv/spool/keep-*.dat | wc -lis unchanged (20);df -i /srv/spoolshows IUse% below 90 %.touch -d '3 days ago' /srv/spool/stale-old.tmp; running the job by hand (the cron script orsystemctl start CLEANUP.service) removes it but not/srv/spool/stale-new.tmpcreated now.sudo lsof +L1 2>/dev/null | grep -c deletedis0;systemctl is-active exporterisactive.
Hint
Two different kinds of "full":
df -ifor inodes, and open-but-deleted files (ls -l /proc//fd | grep deleted,lsof +L1). Restarting the owner closes the descriptor and frees the space. A cleanup job needs a command likefind /srv/spool -name 'stale-.tmp' -mtime +0 -delete.Solution
df -h /srv/spool | tail -1; df -i /srv/spool | tail -1 sudo find /srv/spool -name 'stale-*.tmp' -delete touch /srv/spool/newfile && ls /srv/spool/keep-*.dat | wc -l sudo tee /etc/cron.daily/spool-clean <<'EOT' #!/bin/sh find /srv/spool -name 'stale-*.tmp' -mtime +0 -delete EOT sudo chmod 755 /etc/cron.daily/spool-clean df -h /var | tail -1; sudo du -sh /var 2>/dev/null | tail -1 sudo lsof +L1 2>/dev/null | head -3 sudo systemctl restart exporter df -h /var | tail -1 - Nothing can be created in