Menu

[Solution] Dual Boot macOS / zorinOS / Clonezilla recovery using rEFInd (iMac 2015)

4 days ago
2 days ago
  • Ace Ventura

    Ace Ventura - 4 days ago

    Dual Boot macOS / zorinOS / Clonezilla recovery using rEFInd (iMac 2015)

    Overview & Hardware Target

    This guide provides a complete walkthrough for setting up a reliable triple-boot configuration—consisting of macOS Monterey (12.7.6), Zorin OS, and a self-hosted Clonezilla Recovery environment—managed by the rEFInd boot manager.

    This specific deployment is engineered for Late 2015 Retina 5K 27" iMacs (Apple17,1) with an Intel Core i7 processor and AMD Radeon R9 M395X graphics. This hardware suffers from unique quirks, such as inconsistent storage drive enumeration across boots, and severe firmware graphic glitches (GOP EFI corruption resulting in blank screens) if macOS is booted directly without NVRAM firmware pointers.

    Following the layout of this guide guarantees a highly resilient setup where you can easily back up and restore your operating systems to a secondary storage drive with single-key execution pathways, completely avoiding partition locks.


    Hardware Storage Blueprint

    To ensure absolute path stability, this guide utilizes the following dual-drive configuration:

    • Disk 0 (/dev/sda — 120GB Internal Blade SSD): Host drive for the boot systems.

    • sda1: EFI System Partition (ESP) | FAT32

    • sda2: macOS Monterey | APFS

    • sda3: Zorin OS | ext4

    • sda4: Linux Swap | Swap

    • Disk 1 (/dev/sdb — 2TB Mechanical HDD): Consolidated image and user-data repository.

    • sdb1: Data Store | exFAT (Target path: /clonezilla/images/...)


    Phase 1: Disk Partitioning via Linux Live USB

    Boot into a Live Linux environment (e.g., a Zorin Live USB) and open a terminal. We utilize gdisk to achieve precise sector alignment, allowing for cleaner future partition recoveries.

    1. Launch gdisk on the primary blade drive:
    sudo gdisk /dev/sda
    
    1. Execute the partition sequencing:
    2. o $\rightarrow$ Create a brand new GPT partition table $\rightarrow$ y
    3. n $\rightarrow$ Add Partition 1 (ESP): First sector 2048, Last sector 1000000, Type ef00 (EFI System Partition, ~488 MiB)
    4. n $\rightarrow$ Add Partition 2 (macOS): First sector 1001472, Last sector 125000000, Type af0a (Apple APFS, ~59.1 GiB)
    5. n $\rightarrow$ Add Partition 3 (ZorinOS): First sector 125001728, Last sector 225000000, Type 8200 (Linux OS, ~47.7 GiB)
    6. n $\rightarrow$ Add Partition 4 (Swap): First sector 225001472, Last sector default (remaining sectors), Type 8200 (Linux Swap, ~5.7 GiB)
    7. p $\rightarrow$ Print the layout to verify clean, rounded numbers.
    8. w $\rightarrow$ Write partition table to disk $\rightarrow$ y

    9. Format the Filesystems:
      Open GParted GUI:

    10. Format Partition 1 (/dev/sda1) as fat32 and flags as boot, esp.
    11. Format Partition 3 (/dev/sda3) as ext4 and Partition 4 (/dev/sda4) as linux-swap (these will be formatted again during OS installation, but initializing them now ensures installer stability).

    Phase 2: Operating System Deployments

    Step A: Install Zorin OS

    1. Insert and boot your Zorin OS installer USB.
    2. Choose the Advanced / Something Else installation option.
    3. Map /dev/sda3, format it to ext4, and set the mount point to /.
    4. Select /dev/sda4 and set it as swap.
    5. Run the installation and complete it.
    6. Reboot into Zorin OS to finalize the Linux configuration, then power off the system.

    Step B: Install macOS Monterey

    1. Insert and boot your macOS Monterey Installer USB.
    2. Before launching the graphical installer, open the Terminal from the top menu bar.
    3. Find your APFS target volume (which matches your 60GB partition):
    diskutil list
    
    1. Erase and initialize the target partition to APFS:
    diskutil eraseVolume APFS "MacOS" /dev/disk0s2
    diskutil apfs deleteContainer -force disk0s2
    diskutil eraseVolume APFS "MacOS" /dev/disk0s2
    
    1. Exit the Terminal cleanly, then run the standard macOS installer targeting the newly created APFS volume.
    2. Once installation completes, gracefully shut down the machine.

    Phase 3: Setup rEFInd & Firm up NVRAM

    Step A: Disable macOS SIP

    1. Power on the iMac and immediately hold Command (⌘) + R to boot into macOS Recovery Mode.
    2. Open Terminal and disable System Integrity Protection (required to let rEFInd alter startup disks safely):
    csrutil disable
    
    1. Reboot into Zorin OS.

    Step B: Install rEFInd Bootloader

    1. In Zorin OS, download and extract the official rEFInd binary package. Open terminal and navigate to the folder:
    cd /path/to/refind-bin-0.14.2
    sudo ./refind-install
    
    1. Verify NVRAM entries to make sure both primary targets are present:
    efibootmgr
    

    (Ensure you see boot entries pointing to macOS and Ubuntu/ZorinOS)


    Phase 4: Configure the EFI System Partition (ESP)

    Mount the ESP to arrange recovery files and set up rEFInd configuration.

    How to mount ESP:

    • From Zorin OS:
    sudo mkdir -p /mnt/esp
    sudo mount /dev/sda1 /mnt/esp
    sudo nautilus /mnt/esp
    
    • From macOS:
    sudo mkdir -p /Volumes/EFI
    sudo mount -t msdos /dev/disk0s1 /Volumes/EFI
    

    File Arrangement Checklist:

    1. Under /mnt/esp/EFI/, ensure you have:
    2. refind/ (The main rEFInd installation folder)

    3. ubuntu/ (The Zorin OS GRUB boot files)

    4. clonezilla/ (Create this directory)

    5. Copy grubx64.efi from /EFI/ubuntu over to /EFI/clonezilla/. This pre-built file is configured to read local GRUB config structures, making it the perfect engine for booting Clonezilla from the ESP.

    6. Inside /EFI/clonezilla/, place:

    7. The compiled recovery menu configurations (grub.cfg, backupOS_image.cfg, restoreOS_image.cfg).

    8. The system-facing scripts subdirectory (/EFI/clonezilla/scripts/) housing backup-os.sh and restore-os.sh.

    9. The live kernel resources placed directly under /EFI/clonezilla/live/ (vmlinuz, initrd.img, and filesystem.squashfs).


    Configuration Files and Automation Scripts

    Below are the customized, system-specific files optimized for the iMac 2015. Copy these directly into your mapped ESP directory tree.

    1. Main rEFInd Configuration File

    Save this as /EFI/refind/refind.conf:

    # ==============================================================================
    # My iMac 2015 rEFInd Boot Menu
    # ==============================================================================
    use_nvram false
    
    default_selection +
    timeout 300
    shutdown_after_timeout
    
    scanfor manual,external
    scan_all_linux_kernels false
    dont_scan_dirs EFI/BOOT,EFI/Microsoft,EFI/tools
    dont_scan_volumes "Install macOS Monterey","Install macOS","macOS Install","Macintosh HD"
    
    showtools about,reboot,shutdown
    
    # ==============================================================================
    # OPERATING SYSTEM TARGET SELECTIONS
    # ==============================================================================
    
    menuentry "macOS Monterey 12.7.6" {
        icon             EFI/refind/icons/os_mac.png
        firmware_bootnum 80
    }
    
    menuentry "Zorin OS" {
        icon             EFI/refind/icons/os_zorin.png
        loader           EFI/ubuntu/grubx64.efi
    }
    
    menuentry "Clonezilla Suite" {
        icon            EFI/refind/icons/tool_clonezilla.png
        loader          EFI/clonezilla/grubx64.efi
        options         "configfile=/EFI/clonezilla/grub.cfg"
    }
    

    2. Main Clonezilla GRUB Menu

    Save this as /EFI/clonezilla/grub.cfg:

    # ==============================================================================
    # CLONEZILLA RECOVERY MENU
    # /EFI/clonezilla/grub.cfg
    # ==============================================================================
    
    function load_config {
        set cfg_file="$1"
        if [ -f "$cfg_file" ]; then configfile "$cfg_file"; else
            echo "Error: $cfg_file not found!"; sleep --interruptible 5
        fi
    }
    
    menuentry "[1] Restore System (Deploy Saved Images)..." --hotkey=1 {
        load_config /EFI/clonezilla/restoreOS_image.cfg
    }
    
    menuentry "[2] Backup System (Create New Image)..." --hotkey=2 {
        load_config /EFI/clonezilla/backupOS_image.cfg
    }
    
    menuentry "" { true }
    
    menuentry "[3] Clonezilla Advanced Console (Manual Mode)" --hotkey=3 {
        set base_bootargs="boot=live live-media-path=/EFI/clonezilla/live toram=filesystem.squashfs noswap nosplash ip=frommedia keyboard-layouts=NONE locales=en_US.UTF-8 amdgpu.dc=0 amdgpu.dpm=0"
        linux /EFI/clonezilla/live/vmlinuz $base_bootargs ocs_live_run="ocs-live-general"
        initrd /EFI/clonezilla/live/initrd.img
    }
    

    3. Backup Execution Menu

    Save this as /EFI/clonezilla/backupOS_image.cfg:

    # ==============================================================================
    # BACKUPOS_IMAGE.CFG
    # /EFI/clonezilla/backupOS_image.cfg
    # ==============================================================================
    #
    # GLOBAL PARAMETERS & ISOLATED REPOSITORY TARGETS
    #
    # EXPLANATION OF CORE BOOT ARGUMENTS (base_bootargs):
    # boot=live                  : Initializes live, read-only environment.
    # live-media-path            : Points initramfs to the ESP subfolder.
    # toram=filesystem.squashfs  : Copies squashfs to RAM (frees ESP locks).
    # noswap                     : Prevents use of local swap partitions.
    # nosplash                   : Shows verbose kernel boot console logs.
    # ip=frommedia               : Skips DHCP/network config to speed up boot.
    # keyboard-layouts=NONE      : Sets minimal generic keyboard layout.
    # locales=en_US.UTF-8        : Sets universal language locale.
    # amdgpu.dc=0 amdgpu.dpm=0   : Fixes 2015 iMac graphics and SATA bus ordering.
    #
    # ==============================================================================
    
    set base_bootargs="boot=live live-media-path=/EFI/clonezilla/live toram=filesystem.squashfs noswap nosplash ip=frommedia keyboard-layouts=NONE locales=en_US.UTF-8 amdgpu.dc=0 amdgpu.dpm=0"
    
    # Internal execution pathways inside the ESP
    set linux_kernel="/EFI/clonezilla/live/vmlinuz"
    set linux_initrd="/EFI/clonezilla/live/initrd.img"
    
    # Persistent filesystem UUID designation for the image repository
    set repo_base="ocs_repository=\"dev:///UUID=FE7F-7A75\""
    
    # ESP Pre-execution environment mounting routine
    # NOTE: The ESP is re-mounted via ocs_prerun before ocs_live_run ever runs.
    # Scripts are copied into /tmp and the ESP is unmounted to prevent partition locks.
    # Added explicit 'setfont Uni2-DejaVu51x28' to force high-DPI text scaling on console init.
    # macOS - sudo file -s /dev/rdisk0s1 - remove the 0x from 'serial' to locate 8 char UUID string
    set esp_uuid="C412-1D17"
    set script_dir="/tmp/scripts"
    set esp_mount_prerun="ocs_prerun=\"setfont Uni2-DejaVu51x28\" ocs_prerun1=\"mkdir -p /mnt/esp\" ocs_prerun2=\"fsck.fat -a /dev/disk/by-uuid/$esp_uuid\" ocs_prerun3=\"mount -U $esp_uuid -t vfat -o ro /mnt/esp\" ocs_prerun4=\"cp -r /mnt/esp/EFI/clonezilla/scripts $script_dir\" ocs_prerun5=\"umount /mnt/esp\""
    
    # ------------------------------------------------------------------------------
    # SECTION 1: FULLY AUTOMATED TIMESTAMP SNAPSHOT ENGINE
    # ------------------------------------------------------------------------------
    menuentry "[1] Auto-Backup macOS: Save Timestamped Snapshot" --hotkey=1 {
        linux $linux_kernel $base_bootargs $repo_base $esp_mount_prerun ocs_live_run="bash $script_dir/backup-os.sh mac auto reboot"
        initrd $linux_initrd
    }
    
    menuentry "[2] Auto-Backup ZorinOS: Save Timestamped Snapshot" --hotkey=2 {
        linux $linux_kernel $base_bootargs $repo_base $esp_mount_prerun ocs_live_run="bash $script_dir/backup-os.sh zorin auto reboot"
        initrd $linux_initrd
    }
    
    # --- VISUAL SEPARATOR ---
    menuentry "" { true }
    
    # ------------------------------------------------------------------------------
    # SECTION 2: INTERACTIVE CUSTOM LABEL ENGINE
    # ------------------------------------------------------------------------------
    menuentry "[3] macOS [Interactive Custom Name] <- Source: /dev/sda2" --hotkey=3 {
        linux $linux_kernel $base_bootargs $repo_base $esp_mount_prerun ocs_live_run="bash $script_dir/backup-os.sh mac interactive choose"
        initrd $linux_initrd
    }
    
    menuentry "[4] ZorinOS [Interactive Custom Name] <- Source: /dev/sda3" --hotkey=4 {
        linux $linux_kernel $base_bootargs $repo_base $esp_mount_prerun ocs_live_run="bash $script_dir/backup-os.sh zorin interactive choose"
        initrd $linux_initrd
    }
    
    # --- VISUAL SEPARATOR ---
    menuentry "" { true }
    
    # ------------------------------------------------------------------------------
    # CONTROL EXIT ROUTINE
    # ------------------------------------------------------------------------------
    menuentry "[B] <- Cancel & Return to Main Recovery Menu" --hotkey=b {
        configfile /EFI/clonezilla/grub.cfg
    }
    

    4. Restore Execution Menu

    Save this as /EFI/clonezilla/restoreOS_image.cfg:

    # ==============================================================================
    # RESTOREOS_IMAGE.CFG
    # /EFI/clonezilla/restoreOS_image.cfg
    # ==============================================================================
    #
    # GLOBAL PARAMETERS & ISOLATED REPOSITORY TARGETS
    #
    # EXPLANATION OF CORE BOOT ARGUMENTS (base_bootargs):
    # boot=live                  : Initializes live, read-only environment.
    # live-media-path            : Points initramfs to the ESP subfolder.
    # toram=filesystem.squashfs  : Copies squashfs to RAM (frees ESP locks).
    # noswap                     : Prevents use of local swap partitions.
    # nosplash                   : Shows verbose kernel boot console logs.
    # ip=frommedia               : Skips DHCP/network config to speed up boot.
    # keyboard-layouts=NONE      : Sets minimal generic keyboard layout.
    # locales=en_US.UTF-8        : Sets universal language locale.
    # amdgpu.dc=0 amdgpu.dpm=0   : Fixes 2015 iMac graphics and SATA bus ordering.
    #
    # ==============================================================================
    
    set base_bootargs="boot=live live-media-path=/EFI/clonezilla/live toram=filesystem.squashfs noswap nosplash ip=frommedia keyboard-layouts=NONE locales=en_US.UTF-8 amdgpu.dc=0 amdgpu.dpm=0"
    
    # Internal execution pathways inside the ESP
    set linux_kernel="/EFI/clonezilla/live/vmlinuz"
    set linux_initrd="/EFI/clonezilla/live/initrd.img"
    
    # Persistent filesystem UUID designation for the image repository
    set repo_base="ocs_repository=\"dev:///UUID=FE7F-7A75\""
    
    # ESP Pre-execution environment mounting routine
    # NOTE: The ESP is re-mounted via ocs_prerun before ocs_live_run ever runs.
    # Scripts are copied into /tmp and the ESP is unmounted to prevent partition locks.
    # Added explicit 'setfont Uni2-DejaVu51x28' to force high-DPI text scaling on console init.
    # macOS - sudo file -s /dev/rdisk0s1 - remove the 0x from 'serial' to locate 8 char UUID string
    set esp_uuid="C412-1D17"
    set script_dir="/tmp/scripts"
    set esp_mount_prerun="ocs_prerun=\"setfont Uni2-DejaVu51x28\" ocs_prerun1=\"mkdir -p /mnt/esp\" ocs_prerun2=\"fsck.fat -a /dev/disk/by-uuid/$esp_uuid\" ocs_prerun3=\"mount -U $esp_uuid -t vfat -o ro /mnt/esp\" ocs_prerun4=\"cp -r /mnt/esp/EFI/clonezilla/scripts $script_dir\" ocs_prerun5=\"umount /mnt/esp\""
    
    # ------------------------------------------------------------------------------
    # SECTION 1: CHRONOLOGICAL SNAPSHOT ENGINE (LATEST BACKUPS)
    # ------------------------------------------------------------------------------
    menuentry "[1] Auto-Restore macOS: Latest Snapshot" --hotkey=1 {
        linux $linux_kernel $base_bootargs $repo_base $esp_mount_prerun ocs_live_run="bash $script_dir/restore-os.sh mac latest reboot"
        initrd $linux_initrd
    }
    
    menuentry "[2] Auto-Restore ZorinOS: Latest Snapshot" --hotkey=2 {
        linux $linux_kernel $base_bootargs $repo_base $esp_mount_prerun ocs_live_run="bash $script_dir/restore-os.sh zorin latest reboot"
        initrd $linux_initrd
    }
    
    # --- VISUAL SEPARATOR ---
    menuentry "" { true }
    
    # ------------------------------------------------------------------------------
    # SECTION 2: INTERACTIVE NAMED TARGET ENGINE
    # ------------------------------------------------------------------------------
    menuentry "[3] macOS -> [Interactive Image Selection] -> Target: /dev/sda2" --hotkey=3 {
        linux $linux_kernel $base_bootargs $repo_base $esp_mount_prerun ocs_live_run="bash $script_dir/restore-os.sh mac interactive choose"
        initrd $linux_initrd
    }
    
    menuentry "[4] ZorinOS -> [Interactive Image Selection] -> Target: /dev/sda3" --hotkey=4 {
        linux $linux_kernel $base_bootargs $repo_base $esp_mount_prerun ocs_live_run="bash $script_dir/restore-os.sh zorin interactive choose"
        initrd $linux_initrd
    }
    
    # --- VISUAL SEPARATOR ---
    menuentry "" { true }
    
    # ------------------------------------------------------------------------------
    # SECTION 3: FACTORY BASE ENGINE (OLDEST CHRONOLOGICAL SNAPSHOTS)
    # ------------------------------------------------------------------------------
    menuentry "[5] Auto-Restore macOS: Factory Base Setup" --hotkey=5 {
        linux $linux_kernel $base_bootargs $repo_base $esp_mount_prerun ocs_live_run="bash $script_dir/restore-os.sh mac oldest reboot"
        initrd $linux_initrd
    }
    
    menuentry "[6] Auto-Restore ZorinOS: Factory Base Setup" --hotkey=6 {
        linux $linux_kernel $base_bootargs $repo_base $esp_mount_prerun ocs_live_run="bash $script_dir/restore-os.sh zorin oldest reboot"
        initrd $linux_initrd
    }
    
    # --- VISUAL SEPARATOR ---
    menuentry "" { true }
    
    # ------------------------------------------------------------------------------
    # CONTROL EXIT ROUTINE
    # ------------------------------------------------------------------------------
    menuentry "[B] <- Cancel & Return to Main Recovery Menu" --hotkey=b {
        configfile /EFI/clonezilla/grub.cfg
    }
    

    5. Automated OS Backup Script

    Save this as /EFI/clonezilla/scripts/backup-os.sh:

    #!/bin/bash
    # /EFI/clonezilla/backup-os.sh — resolves the target OS partition by PARTUUID and hands it to ocs-sr.
    # Usage: backup-os.sh <mac|zorin> <auto|interactive> <reboot|choose|true>
    set -e
    
    OS_TARGET="${1}"             # mac    | zorin
    MODE="${2:-interactive}"     # auto   | interactive
    POSTACTION="${3:-true}"      # reboot | choose | true
    
    # Validate OS argument and dynamically assign UUID / Paths
    case "$OS_TARGET" in
      mac)
        PARTUUID="b7300478-5dde-4448-9199-b1b40efedef7"
        REPO_DIR="clonezilla/images/macOS"
        LABEL_PREFIX="macOS-"
        LOG_PREFIX="mac"
        ;;
      zorin)
        PARTUUID="32194dc0-7623-4ce8-9895-c2dfff6edfee"
        REPO_DIR="clonezilla/images/zorinOS"
        LABEL_PREFIX="zorinOS-"
        LOG_PREFIX="zorin"
        ;;
      *)
        echo "ERROR: Must specify valid OS target: 'mac' or 'zorin'"
        exit 1
        ;;
    esac
    
    # ==============================================================================
    # CLONEZILLA EXECUTION ENGINE CONFIGURATION (ocs-sr)
    # ==============================================================================
    # -q2             : Forces the engine to use Partclone for optimized block cloning.
    # -j2             : Captures and saves the raw MBR/GPT table metadata.
    # -edio           : Bypasses system file caches to accelerate SSD write bandwidth.
    # -z9p            : Uses multi-threaded parallel ultra-gzip compression for maximum disk space savings.
    # -i 4096         : Sets the file split size threshold to 4096MB chunks.
    # -scs -senc -plu : Skips script verification, encryption setups, and records LVM maps.
    # -fsck-src-part-y: Automatically runs an integrity check on source filesystems before cloning.
    # ==============================================================================
    OCSRUN="ocs-sr -q2 -j2 -edio -z9p -i 4096 -scs -senc -plu -fsck-src-part-y"
    
    # --- PERSISTENT LOGGING ---
    LOG_DIR="/home/partimag/clonezilla/backup-logs"
    mkdir -p "$LOG_DIR"
    LOG_FILE="${LOG_DIR}/${LOG_PREFIX}-backup-$(date +%Y%m%d-%H%M).log"
    exec > >(tee -a "$LOG_FILE") 2>&1
    echo "=== backup-os.sh ($OS_TARGET) started $(date) — mode=$MODE postaction=$POSTACTION ==="
    
    DEV_PATH="/dev/disk/by-partuuid/${PARTUUID}"
    
    if [ ! -e "$DEV_PATH" ]; then
        echo "ERROR: no device found for PARTUUID ${PARTUUID}"
        echo "Check 'lsblk -o NAME,SIZE,FSTYPE,PARTUUID' and update this script."
        exit 1
    fi
    
    TARGET=$(basename "$(readlink -f "$DEV_PATH")")
    echo "Resolved $OS_TARGET PARTUUID ${PARTUUID} -> /dev/${TARGET}"
    
    case "$MODE" in
      auto)
        TIMESTAMP=$(date +%Y%m%d-%H%M)
        IMAGE_NAME="${LABEL_PREFIX}${TIMESTAMP}"
        echo "Starting automated backup into image folder: ${REPO_DIR}/${IMAGE_NAME}"
        set +e
        $OCSRUN -batch -or "/home/partimag/${REPO_DIR}" -p "$POSTACTION" saveparts "$IMAGE_NAME" "$TARGET"
        OCS_RC=$?
        set -e
        ;;
      interactive)
        echo "Starting interactive naming backup sequence..."
        set +e
        $OCSRUN -or "/home/partimag/${REPO_DIR}" -p "$POSTACTION" saveparts ask_user "$TARGET"
        OCS_RC=$?
        set -e
        ;;
      *)
        echo "ERROR: unknown mode '$MODE'"
        exit 1
        ;;
    esac
    
    echo "=== ocs-sr exited with code ${OCS_RC:-unknown} ==="
    cp -f /var/log/clonezilla/clonezilla.log "${LOG_DIR}/clonezilla-internal-$(date +%Y%m%d-%H%M%S).log" 2>/dev/null || echo "(could not copy /var/log/clonezilla/clonezilla.log)"
    echo "Logs saved under ${LOG_DIR} on the repo drive."
    

    6. Automated OS Restore Script

    Save this as /EFI/clonezilla/scripts/restore-os.sh:

    #!/bin/bash
    # /EFI/clonezilla/restore-os.sh — resolves the target OS partition by PARTUUID and hands it to ocs-sr.
    # Usage: restore-os.sh <mac|zorin> <latest|oldest|interactive> <reboot|choose|true>
    set -e
    
    OS_TARGET="${1}"             # mac    | zorin
    MODE="${2:-interactive}"     # latest | oldest | interactive
    POSTACTION="${3:-choose}"    # reboot | choose | true
    
    # Validate OS argument and dynamically assign UUID / Paths
    case "$OS_TARGET" in
      mac)
        PARTUUID="b7300478-5dde-4448-9199-b1b40efedef7"
        REPO_DIR="clonezilla/images/macOS"
        LOG_PREFIX="mac"
        ;;
      zorin)
        PARTUUID="32194dc0-7623-4ce8-9895-c2dfff6edfee"
        REPO_DIR="clonezilla/images/zorinOS"
        LOG_PREFIX="zorin"
        ;;
      *)
        echo "ERROR: Must specify valid OS target: 'mac' or 'zorin'"
        exit 1
        ;;
    esac
    
    # ==============================================================================
    # CLONEZILLA EXECUTION ENGINE CONFIGURATION (ocs-sr)
    # ==============================================================================
    # Explanation of core parameters used for specialized partition targeting:
    #
    # -e1 auto : Auto-detects and adjusts geometry mapping for the target filesystem
    #            boundaries (crucial for maintaining alignment on boot volumes).
    # -e2      : Force-loads CHS (Cylinders, Heads, Sectors) geometry definitions
    #            from EDD (Enhanced Disk Device) to match partition bounds accurately.
    # -t       : Skips MBR/GPT root structure overwrites. Because we are restoring a
    #            single standalone partition, the system's baseline drive partition
    #            table layout should not be touched.
    # -r       : Tries to scale the internal filesystem boundaries up to match the
    #            destination space if the target partition is larger than the source image.
    # -edio    : Enables Direct I/O pipelines inside Partclone, bypassing system file
    #            caches to accelerate write bandwidth on solid-state architectures.
    # -c       : Commands Clonezilla to prompt the user manually for confirmation
    #            before committing hazardous block-level overrides to disk.
    # -k       : Suppresses the generation of a fresh block device layout table (fdisk).
    #            Safeguards neighboring dual-boot target blocks from allocation conflicts.
    # -scr     : Skips checking image consistency right before writing data blocks to
    #            optimize runtime performance.
    # ==============================================================================
    OCSRUN="ocs-sr -e1 auto -e2 -t -r -edio -c -k -scr"
    
    # --- PERSISTENT LOGGING ---
    LOG_DIR="/home/partimag/clonezilla/restore-logs"
    mkdir -p "$LOG_DIR"
    LOG_FILE="${LOG_DIR}/${LOG_PREFIX}-restore-$(date +%Y%m%d-%H%M).log"
    exec > >(tee -a "$LOG_FILE") 2>&1
    echo "=== restore-os.sh ($OS_TARGET) started $(date) — mode=$MODE postaction=$POSTACTION ==="
    
    DEV_PATH="/dev/disk/by-partuuid/${PARTUUID}"
    
    if [ ! -e "$DEV_PATH" ]; then
        echo "ERROR: no device found for PARTUUID ${PARTUUID}"
        echo "Check 'lsblk -o NAME,SIZE,FSTYPE,PARTUUID' and update this script."
        exit 1
    fi
    
    TARGET=$(basename "$(readlink -f "$DEV_PATH")")
    echo "Resolved $OS_TARGET PARTUUID ${PARTUUID} -> /dev/${TARGET}"
    
    case "$MODE" in
      latest)
        IMAGE=$(cd "/home/partimag/${REPO_DIR}" && ls -1td */ | head -n1 | tr -d '/')
        echo "Restoring latest snapshot: ${IMAGE}"
        set +e
        $OCSRUN -batch -scr -p "$POSTACTION" restoreparts "${REPO_DIR}/${IMAGE}" "$TARGET"
        OCS_RC=$?
        set -e
        ;;
      oldest)
        IMAGE=$(cd "/home/partimag/${REPO_DIR}" && ls -1trd */ | head -n1 | tr -d '/')
        echo "Restoring factory-base snapshot: ${IMAGE}"
        set +e
        $OCSRUN -batch -scr -p "$POSTACTION" restoreparts "${REPO_DIR}/${IMAGE}" "$TARGET"
        OCS_RC=$?
        set -e
        ;;
      interactive)
        set +e
        $OCSRUN -or "/home/partimag/${REPO_DIR}" -p "$POSTACTION" restoreparts ask_user "$TARGET"
        OCS_RC=$?
        set -e
        ;;
      *)
        echo "ERROR: unknown mode '$MODE'"
        exit 1
        ;;
    esac
    
    echo "=== ocs-sr exited with code ${OCS_RC:-unknown} ==="
    cp -f /var/log/clonezilla/clonezilla.log "${LOG_DIR}/clonezilla-internal-$(date +%Y%m%d-%H%M%S).log" 2>/dev/null || echo "(could not copy /var/log/clonezilla/clonezilla.log)"
    echo "Logs saved under ${LOG_DIR} on the repo drive -- readable from any OS."
    

    Troubleshooting & Critical Hardware Fail-Safes

    Fail-Safe 1: Boot Order Drift

    Holding down the Option key on the iMac to manually trigger boot partitions can trick the EFI system into permanently overriding your boot configuration. It will often set the Zorin OS GRUB partition (0001) as default.

    • The Fix: Boot directly into Zorin OS, launch terminal, and force the firmware boot priority index back to rEFInd (0000):
    sudo efibootmgr -o 0000
    

    Fail-Safe 2: The Graphics Blank Screen Glitch

    On late 2015 iMac models, booting macOS in a standard method directly out of rEFInd without invoking NVRAM maps can corrupt GOP EFI. This causes rEFInd to load to a blank black screen during future restarts.

    • The Fix: You must perform a hardware NVRAM reset (hold Option (⌥) + Command (⌘) + P + R immediately after turning it on), boot into macOS Recovery Mode (hold Command (⌘) + R), run csrutil disable from terminal, and then manually re-register the primary rEFInd NVRAM layout link:
    # From linux:
    sudo efibootmgr -c -d /dev/sda -p 1 -L "rEFInd Boot Manager" -l "\EFI\refind\refind_x64.efi"
    sudo efibootmgr -o 0000
    

    Fail-Safe 3: Recovering a Deleted macOS NVRAM Entry (Boot0080)

    If you accidentally wipe your NVRAM or lose the specific Boot0080 entry that points directly to macOS, rEFInd will not be able to boot macOS Monterey using the firmware_bootnum 80 rule. You can recreate this entry easily from macOS.

    The Quick "Bless" Method

    Boot into your macOS partition (if you can access it via rEFInd's temporary fallback scans or by holding Option at boot) or boot into macOS Recovery Mode (hold Command (⌘) + R at startup). Open the terminal and run:

    # Force-bless the macOS volume to recreate the NVRAM boot entry
    sudo bless --mount /Volumes/MacOS --setBoot --verbose
    
    # Verify that the boot loader path and NVRAM entry are active
    sudo bless --info /
    
     
  • Steven Shiau

    Steven Shiau - 2 days ago

    Cool. Thanks for sharing that.

     
    ❤️
    1

Log in to post a comment.

MongoDB Logo MongoDB