added support for fedora layout

This commit is contained in:
robojerk 2025-08-28 11:30:41 -07:00
parent 443558bafc
commit ceb06d340a
2 changed files with 304 additions and 12 deletions

View file

@ -6,21 +6,33 @@
```bash
sudo ./grub-repair.sh detect
```
**What this does**: Shows all available disks, partitions, and identifies which ones are bootable Linux systems.
**When to use**: First step - always run this to see what systems are available before attempting repairs.
**Output**: Lists disks, partitions, filesystem types, and mount points.
### 2. Complete Boot Repair (Recommended)
```bash
sudo ./grub-repair.sh -d /dev/sda -p 1 -b fix-boot
```
**What this does**: Mounts your system, installs GRUB, updates configuration, and repairs EFI - all in one command with automatic backup.
**When to use**: Your system won't boot, GRUB is missing/corrupted, or you need a complete boot recovery.
**Device note**: Replace `/dev/sda` with your actual disk (use `lsblk` to find it).
### 3. Check Status
```bash
sudo ./grub-repair.sh status
```
**What this does**: Shows current mount status, available GRUB configurations, EFI partition status, and backup information.
**When to use**: After mounting or during troubleshooting to see what's currently available and mounted.
**Output**: Current system state, mounted filesystems, and backup locations.
### 4. Clean Up
```bash
sudo ./grub-repair.sh clean
```
**What this does**: Safely unmounts all systems, removes temporary mount points, and cleans up resources.
**When to use**: After completing repairs, when switching between systems, or if something goes wrong.
**Safety**: Automatically unmounts everything in the correct order to prevent data loss.
## Common Scenarios
@ -32,6 +44,12 @@ sudo ./grub-repair.sh detect
# Then repair (replace /dev/sda with your device)
sudo ./grub-repair.sh -d /dev/sda -p 1 -b fix-boot
```
**Step-by-step process**:
1. **Detect**: Identify available systems and their locations
2. **Repair**: Complete boot repair with automatic backup
3. **Reboot**: Restart your system to test the repair
**Device identification**: Use `lsblk` or `fdisk -l` to find your disk name if unsure.
### GRUB Reinstall Only
```bash
@ -47,11 +65,17 @@ sudo ./grub-repair.sh update-grub
# Unmount
sudo ./grub-repair.sh unmount
```
**When to use**: You only need to reinstall GRUB, not perform a complete repair.
**Manual control**: Gives you step-by-step control over the GRUB installation process.
**Safety**: Each step can be verified before proceeding to the next.
### EFI Partition Check and Repair
```bash
sudo ./grub-repair.sh -d /dev/sda check-efi
```
**What this does**: Checks EFI partition health, repairs boot entries, and creates new GRUB boot entries if needed.
**When to use**: EFI boot issues, missing boot entries, or when GRUB isn't showing up in UEFI boot menu.
**Advanced**: Automatically detects your Linux distribution for proper bootloader ID.
## Device Identification
@ -59,16 +83,70 @@ sudo ./grub-repair.sh -d /dev/sda check-efi
- **EFI partition**: Usually the first partition (e.g., `/dev/sda1`)
- **Root partition**: Usually the second partition (e.g., `/dev/sda2`)
**Common device names**:
- **SATA drives**: `/dev/sda`, `/dev/sdb`, `/dev/sdc`
- **NVMe drives**: `/dev/nvme0n1`, `/dev/nvme1n1`
- **USB drives**: `/dev/sdd`, `/dev/sde` (when booted from USB)
## Safety Tips
- Always use `-b` flag for backup
- Test on non-critical systems first
- Keep live ISO handy for recovery
- Document your partition layout
- **Always use `-b` flag for backup** - Creates automatic backups before making changes
- **Test on non-critical systems first** - Verify the script works in your environment
- **Keep live ISO handy for recovery** - You may need to boot from it again if issues arise
- **Document your partition layout** - Note down which partitions are which before starting
- **Use `-v` flag for verbose output** - Get detailed information during operations for troubleshooting
## Troubleshooting
- **Permission denied**: Use `sudo`
- **Device not found**: Check with `lsblk`
- **Mount fails**: Use `clean` command first
- **Verbose output**: Add `-v` flag
- **Permission denied**: Use `sudo` - Script requires root access for system operations
- **Device not found**: Check with `lsblk` - Verify device names and partition layout
- **Mount fails**: Use `clean` command first - Cleans up any partial mounts
- **Verbose output**: Add `-v` flag - Shows detailed operation information
- **Force mode**: Use `-f` flag - Bypass live ISO detection if needed
- **Custom mount point**: Use `-m /path` - Specify custom mount location
## Additional Useful Commands
### Manual Mounting
```bash
# Mount a specific system
sudo ./grub-repair.sh -d /dev/sda -p 1 mount
# Unmount current system
sudo ./grub-repair.sh unmount
# Check what's mounted
sudo ./grub-repair.sh status
```
### Backup and Recovery
```bash
# Create backup only
sudo ./grub-repair.sh backup
# Check backup status
sudo ./grub-repair.sh status
```
### Advanced Options
```bash
# Force mode (bypass live ISO check)
sudo ./grub-repair.sh -f -d /dev/sda detect
# Verbose output for debugging
sudo ./grub-repair.sh -v -d /dev/sda check-efi
# Custom mount point
sudo ./grub-repair.sh -m /mnt/custom -d /dev/sda mount
```
## Quick Recovery Workflow
1. **Boot from Live ISO** - Start your system from a live Linux ISO
2. **Detect Systems** - `sudo ./grub-repair.sh detect`
3. **Identify Target** - Note the device name and partition number
4. **Complete Repair** - `sudo ./grub-repair.sh -d /dev/DEVICE -p PARTITION -b fix-boot`
5. **Clean Up** - `sudo ./grub-repair.sh clean`
6. **Reboot** - Restart and test your system
**Pro tip**: The `-b` flag creates automatic backups, so you can always restore if something goes wrong!

View file

@ -67,6 +67,8 @@ EXAMPLES:
# Complete boot repair with backup
$SCRIPT_NAME -d /dev/sda -p 1 -b fix-boot
# Note: The partition number (-p) is a starting point; the script will
# automatically detect and mount the correct root partition if needed.
# Check and repair EFI only
$SCRIPT_NAME -d /dev/sda check-efi
@ -110,10 +112,30 @@ detect_systems() {
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE,LABEL
echo -e "\nEFI partitions:"
blkid | grep -i "vfat\|fat32" | grep -i "efi\|boot" || echo "No EFI partitions found"
local efi_found=false
for partition in $(blkid | grep -i "vfat\|fat32" | cut -d: -f1); do
if [[ -b "$partition" ]]; then
echo " $partition - $(blkid -s LABEL -o value "$partition" 2>/dev/null || echo 'no label')"
efi_found=true
fi
done
if [[ "$efi_found" == "false" ]]; then
echo "No EFI partitions found"
fi
echo -e "\nLinux partitions:"
blkid | grep -i "ext4\|xfs\|btrfs" || echo "No Linux partitions found"
local linux_found=false
for partition in $(blkid | grep -i "ext4\|xfs\|btrfs" | cut -d: -f1); do
if [[ -b "$partition" ]]; then
local fstype=$(blkid -s TYPE -o value "$partition" 2>/dev/null)
local size=$(lsblk -rno SIZE "$partition" 2>/dev/null)
echo " $partition - $fstype ($size)"
linux_found=true
fi
done
if [[ "$linux_found" == "false" ]]; then
echo "No Linux partitions found"
fi
}
# Function to detect Linux distribution
@ -148,6 +170,115 @@ detect_distribution() {
return 1
}
# Function to detect root partition
detect_root_partition() {
local device="$1"
# Get the parent disk name more robustly
local disk
if command -v lsblk >/dev/null 2>&1; then
# Use lsblk to get parent disk (more reliable for NVMe, etc.)
disk=$(lsblk -rno PKNAME "$device" 2>/dev/null | head -1)
# If no parent found, the device might be a disk itself
if [[ -z "$disk" ]]; then
# Check if the device itself is a disk (not a partition)
local device_type=$(lsblk -rno TYPE "$device" 2>/dev/null)
if [[ "$device_type" == "disk" ]]; then
disk="$device"
else
# Fallback: try to extract disk from device path
disk="${device%[0-9]*}"
fi
fi
else
# Fallback: try to extract disk from device path
disk="${device%[0-9]*}"
fi
if [[ -z "$disk" ]]; then
print_status "$YELLOW" "Warning: Could not determine parent disk for $device"
return 1
fi
# Capture blkid output once for efficiency
local blkid_output=$(blkid 2>/dev/null)
# Look for Linux root partitions (ext4, xfs, btrfs)
local root_partitions=""
# Scan all partitions on the disk
if command -v lsblk >/dev/null 2>&1; then
local all_partitions=$(lsblk -rno NAME "$disk" | grep -E "[0-9]+$")
for partition in $all_partitions; do
local full_path="/dev/$partition"
if [[ -b "$full_path" ]]; then
local fstype=$(echo "$blkid_output" | grep "$full_path:" | grep -o 'TYPE="[^"]*"' | cut -d'"' -f2)
if [[ "$fstype" == "ext4" || "$fstype" == "xfs" || "$fstype" == "btrfs" ]]; then
root_partitions="$root_partitions $full_path"
fi
fi
done
fi
# If we found multiple Linux partitions, try to identify the root
if [[ -n "$root_partitions" ]]; then
# Look for partitions that might be root based on size and mount history
for partition in $root_partitions; do
# Check if this partition has a root filesystem structure
if [[ -b "$partition" ]]; then
# Try to mount temporarily to check for root filesystem structure
local temp_mount="/tmp/root-check-$$"
mkdir -p "$temp_mount"
if mount "$partition" "$temp_mount" 2>/dev/null; then
# Check for common root filesystem indicators
if [[ -d "$temp_mount/etc" && -d "$temp_mount/boot" && -d "$temp_mount/var" ]]; then
umount "$temp_mount"
rmdir "$temp_mount"
echo "$partition"
return 0
fi
umount "$temp_mount"
rmdir "$temp_mount"
fi
fi
done
# If we couldn't identify the root, return the largest partition (common for root)
local largest_partition=""
local largest_size=0
for partition in $root_partitions; do
if [[ -b "$partition" ]]; then
local size=$(lsblk -rno SIZE "$partition" 2>/dev/null | sed 's/[^0-9]//g')
if [[ -n "$size" && "$size" -gt "$largest_size" ]]; then
largest_size="$size"
largest_partition="$partition"
fi
fi
done
if [[ -n "$largest_partition" ]]; then
echo "$largest_partition"
return 0
fi
fi
# Fallback: try common partition numbers (2, 3, 4)
for part_num in 2 3 4; do
local test_partition="${disk}${part_num}"
if [[ -b "$test_partition" ]]; then
local fstype=$(echo "$blkid_output" | grep "$test_partition:" | grep -o 'TYPE="[^"]*"' | cut -d'"' -f2)
if [[ "$fstype" == "ext4" || "$fstype" == "xfs" || "$fstype" == "btrfs" ]]; then
echo "$test_partition"
return 0
fi
fi
done
# If still no root partition found, return empty
return 1
}
# Function to detect EFI partition
detect_efi_partition() {
local device="$1"
@ -244,8 +375,26 @@ mount_system() {
# Create mount point if it doesn't exist
mkdir -p "$MOUNT_POINT"
# Check if the specified partition is actually a root partition
# Note: Modern Linux distributions often use non-standard partition layouts
# (e.g., Fedora-style: EFI=1, Boot=2, Root=3), so we need to be smart
# about detecting which partition is actually the root filesystem
local fstype=$(blkid -s TYPE -o value "$partition_device" 2>/dev/null)
if [[ "$fstype" != "ext4" && "$fstype" != "xfs" && "$fstype" != "btrfs" ]]; then
print_status "$YELLOW" "Warning: Partition $partition_device has filesystem type '$fstype', which may not be a root partition"
print_status "$BLUE" "Attempting to detect the actual root partition..."
local detected_root=$(detect_root_partition "$device")
if [[ -n "$detected_root" ]]; then
print_status "$BLUE" "Detected root partition: $detected_root"
partition_device="$detected_root"
else
print_status "$YELLOW" "Could not detect root partition, proceeding with specified partition"
fi
fi
# Mount root partition
print_status "$BLUE" "Mounting root partition..."
print_status "$BLUE" "Mounting root partition $partition_device..."
if ! mount "$partition_device" "$MOUNT_POINT"; then
print_status "$RED" "Error: Failed to mount root partition $partition_device"
exit 1
@ -257,6 +406,7 @@ mount_system() {
# Mount /proc
# Note: We explicitly unmount on failure rather than relying solely on the trap cleanup
# This provides immediate, targeted cleanup and prevents partial mount states
mkdir -p "$MOUNT_POINT/proc"
if ! mount --bind /proc "$MOUNT_POINT/proc"; then
print_status "$RED" "Error: Failed to mount /proc"
umount "$MOUNT_POINT"
@ -295,11 +445,69 @@ mount_system() {
if [[ -n "$efi_partition" && -b "$efi_partition" ]]; then
print_status "$BLUE" "Mounting EFI partition $efi_partition..."
mkdir -p "$EFI_MOUNT_POINT"
mount "$efi_partition" "$EFI_MOUNT_POINT"
if ! mount "$efi_partition" "$EFI_MOUNT_POINT"; then
print_status "$RED" "Error: Failed to mount EFI partition $efi_partition"
# Note: We explicitly unmount on failure rather than relying solely on the trap cleanup
# This provides immediate, targeted cleanup and prevents partial mount states
umount "$MOUNT_POINT/dev/pts" 2>/dev/null || true
umount "$MOUNT_POINT/dev" 2>/dev/null || true
umount "$MOUNT_POINT/sys" 2>/dev/null || true
umount "$MOUNT_POINT/proc" 2>/dev/null || true
umount "$MOUNT_POINT" 2>/dev/null || true
exit 1
fi
else
print_status "$YELLOW" "Warning: EFI partition not found, some operations may fail"
fi
# Mount boot partition if it exists (modern Fedora-style layout)
# Note: Many modern distributions separate /boot from the root filesystem
# for security and performance reasons. We detect this automatically.
local boot_partition=""
local disk="${device%[0-9]*}"
# Look for a separate boot partition
if command -v lsblk >/dev/null 2>&1; then
local all_partitions=$(lsblk -rno NAME "$disk" | grep -E "[0-9]+$")
for partition in $all_partitions; do
local full_path="/dev/$partition"
if [[ -b "$full_path" ]]; then
local fstype=$(blkid -s TYPE -o value "$full_path" 2>/dev/null)
# Look for ext4/xfs boot partitions that are smaller than root
if [[ "$fstype" == "ext4" || "$fstype" == "xfs" ]]; then
local size=$(lsblk -rno SIZE "$full_path" 2>/dev/null | sed 's/[^0-9]//g')
local root_size=$(lsblk -rno SIZE "$partition_device" 2>/dev/null | sed 's/[^0-9]//g')
if [[ -n "$size" && -n "$root_size" && "$size" -lt "$root_size" && "$size" -gt 1000 ]]; then
# Additional check: verify this looks like a boot partition
local temp_mount="/tmp/boot-check-$$"
mkdir -p "$temp_mount"
if mount "$full_path" "$temp_mount" 2>/dev/null; then
# Check for boot-specific directories or files
if [[ -d "$temp_mount/grub2" || -d "$temp_mount/grub" || -d "$temp_mount/extlinux" || -d "$temp_mount/loader" ]]; then
umount "$temp_mount"
rmdir "$temp_mount"
boot_partition="$full_path"
break
fi
umount "$temp_mount"
rmdir "$temp_mount"
fi
fi
fi
fi
done
fi
if [[ -n "$boot_partition" ]]; then
print_status "$BLUE" "Mounting boot partition $boot_partition..."
mkdir -p "$MOUNT_POINT/boot"
if ! mount "$boot_partition" "$MOUNT_POINT/boot"; then
print_status "$YELLOW" "Warning: Failed to mount boot partition, continuing without it"
# Note: We don't exit here because the boot partition is optional
# The system can still function with just the root and EFI partitions
fi
fi
print_status "$GREEN" "System mounted successfully at $MOUNT_POINT"
}
@ -313,6 +521,12 @@ unmount_system() {
print_status "$GREEN" "EFI partition unmounted"
fi
# Unmount boot partition if it was mounted separately
if mountpoint -q "$MOUNT_POINT/boot"; then
umount "$MOUNT_POINT/boot"
print_status "$GREEN" "Boot partition unmounted"
fi
if mountpoint -q "$MOUNT_POINT/dev/pts"; then
umount "$MOUNT_POINT/dev/pts"
fi