Files
SnarfCode/scripts/wsl_repair_ext4.sh

113 lines
4.1 KiB
Bash

#!/usr/bin/env bash
set -uo pipefail
echo "=== 1. Detecting Attached RPi SD/SSD in WSL2 ==="
lsblk -o NAME,SIZE,FSTYPE,PARTUUID,MODEL
# Find the newly attached disk (not sda, sdb, sdc, sdd)
TARGET_DEV=""
for dev in /dev/sd[e-z]; do
if [ -b "${dev}2" ]; then
TARGET_DEV="$dev"
break
fi
done
if [ -z "$TARGET_DEV" ]; then
echo "[ERROR] Could not find attached RPi disk (/dev/sde..z with partition 2)!"
exit 1
fi
BOOT_PART="${TARGET_DEV}1"
ROOT_PART="${TARGET_DEV}2"
echo "Target Disk: $TARGET_DEV (Boot: $BOOT_PART, Root: $ROOT_PART)"
blkid "$BOOT_PART" "$ROOT_PART"
echo ""
echo "=== 2. Inspecting Ext4 Superblock BEFORE Repair ($ROOT_PART) ==="
dumpe2fs -h "$ROOT_PART" 2>/dev/null | grep -E "Filesystem volume name|Filesystem UUID|Filesystem state|Errors behavior|Filesystem created|Last mount time|Last write time|Mount count|Maximum mount count|Last checked|Journal|Inode count|Free inodes|Block count|Free blocks"
echo ""
echo "=== 3. Running e2fsck -fy on $ROOT_PART ==="
e2fsck -fy "$ROOT_PART"
FSCK_RC=$?
echo "e2fsck exit code: $FSCK_RC (0=no errors, 1=errors corrected, 2=corrected)"
echo ""
echo "=== 4. Setting Ext4 Errors Behavior to 'continue' ==="
tune2fs -e continue "$ROOT_PART"
dumpe2fs -h "$ROOT_PART" 2>/dev/null | grep -E "Filesystem state|Errors behavior|Last checked"
echo ""
echo "=== 5. Mounting $ROOT_PART & $BOOT_PART to Inspect & Harden OS Config ==="
mkdir -p /mnt/rpi_root /mnt/rpi_boot
mount "$ROOT_PART" /mnt/rpi_root
mount "$BOOT_PART" /mnt/rpi_boot
echo "--- Hostname & Network Config ---"
cat /mnt/rpi_root/etc/hostname 2>/dev/null || true
cat /mnt/rpi_root/etc/network/interfaces 2>/dev/null | grep -v "^#" | grep -v "^$" || true
ip_cfg=$(grep -rn "140.44.4." /mnt/rpi_root/etc/network/ /mnt/rpi_root/etc/NetworkManager/ /mnt/rpi_root/etc/systemd/network/ 2>/dev/null || true)
echo "$ip_cfg"
echo "--- Current /etc/fstab ---"
cat /mnt/rpi_root/etc/fstab
# Harden /etc/fstab (add nofail to /boot/firmware or /boot and any nfs/glusterfs mounts)
cp /mnt/rpi_root/etc/fstab /mnt/rpi_root/etc/fstab.bak
python3 -c '
p = "/mnt/rpi_root/etc/fstab"
with open(p, "r") as f:
lines = f.readlines()
new_lines = []
for line in lines:
s = line.strip()
if not s or s.startswith("#"):
new_lines.append(line)
continue
parts = s.split()
if len(parts) >= 4:
mp, fstype, opts = parts[1], parts[2], parts[3]
if (mp in ("/boot/firmware", "/boot") or fstype == "vfat") and "nofail" not in opts:
parts[3] = opts + ",nofail"
line = "\t".join(parts) + "\n"
elif fstype in ("glusterfs", "nfs", "nfs4", "cifs") and "nofail" not in opts:
parts[3] = opts + ",nofail,x-systemd.automount,x-systemd.device-timeout=30"
line = "\t".join(parts) + "\n"
new_lines.append(line)
with open(p, "w") as f:
f.writelines(new_lines)
'
echo "--- Hardened /etc/fstab ---"
cat /mnt/rpi_root/etc/fstab
# Ensure both /mnt/rpi_boot/cmdline.txt and /mnt/rpi_root/boot/cmdline.txt (if regular file) have fsck.repair=yes and ro
for cpath in /mnt/rpi_boot/cmdline.txt /mnt/rpi_root/boot/cmdline.txt /mnt/rpi_root/boot/firmware/cmdline.txt; do
if [ -f "$cpath" ] && [ ! -L "$cpath" ]; then
if ! grep -q "fsck.repair=yes" "$cpath"; then
sed -i "s/rootfstype=ext4/rootfstype=ext4 fsck.repair=yes/" "$cpath"
fi
if ! grep -qE "(^| )ro( |$)" "$cpath"; then
sed -i "s/rootwait/ro rootwait/" "$cpath"
fi
echo "Verified $cpath: $(cat "$cpath")"
fi
done
echo "--- Checking Kernel Modules in /lib/modules vs Boot Kernel ---"
ls -la /mnt/rpi_root/lib/modules/
ls -la /mnt/rpi_root/boot/
echo "--- Checking Recent Logs / Crash Evidence on Root FS ---"
ls -la /mnt/rpi_root/var/log/ 2>/dev/null | head -n 20
if [ -d /mnt/rpi_root/var/log/journal ]; then
journalctl -D /mnt/rpi_root/var/log/journal -n 30 --no-pager 2>/dev/null || true
fi
tail -n 30 /mnt/rpi_root/var/log/syslog /mnt/rpi_root/var/log/messages /mnt/rpi_root/var/log/daemon.log 2>/dev/null || true
sync
umount /mnt/rpi_boot
umount /mnt/rpi_root
echo "=== 6. Repair and Hardening Complete! Unmounted cleanly. ==="