Benutzer-Werkzeuge

Webseiten-Werkzeuge


it-wiki:linux:install_debian_bookworm_on_a_software_raid_and_efi

Debian Bookworm auf einem Software-RAID und EFI installieren

Ich habe von meinem Arbeitgeber ein neues Notebook bekommen. Das Notebook hat zwei identische Festplatten, ideal für ein RAID-System und mein Plan ist, Debian darauf zu installieren. Es stellt sich heraus, dass die Einrichtung eines Software-RAID unter Debian und das anschließende Booten per EFI keine ganz einfache Sache ist.

Die „Hardware“

Das neue Notebook hat eine AMD Ryzen 7 8845HS CPU mit 3,8 GHz und 64 GB RAM. Zusätzlich sind zwei Samsung SSD 980 SSDs mit jeweils 512 GB verbaut.

Erster Versuch

Das Partitionswerkzeug auf dem Debian-Installationsmedium unterstützt nur die manuelle Einrichtung eines RAIDs. Das „Geführte“ Tool erkennt nicht, wenn eine Partition auf einem Software-RAID liegt. Es erstellt ganz freudig alle nötigen Partitionen, inklusive der UEFI (Unified Extensible Firmware Interface, EFI)-Partition, direkt auf dem RAID-Gerät.

Geführter Installer erstellt ESP, LVM und weitere Partitionen auf der einen RAID-Partition

Natürlich schlägt das dann spektakulär fehl!

GRUB-Bootloader installieren: GRUB konnte nicht in „dummy“ installiert werden – Ausführen von „grub-install dummy“ ist fehlgeschlagen. Dies ist ein schwerwiegender Fehler.

GRUB-Bootloader installieren: Installationsschritt ist fehlgeschlagen – Du kannst versuchen, diesen Schritt erneut aus dem Menü aufzurufen oder überspringen und etwas anderes auswählen. Der fehlgeschlagene Schritt ist: GRUB-Bootloader installieren

Die korrekte RAID-Konfiguration herausfinden

Was du auf der ersten Festplatte manuell tun musst:

  • Erstellt eine Boot-Block-Partition und markiere sie als biosgrub (Größe: 1 MB)
  • Erstellt eine EFI-Partition und markiere sie als EFI (Größe: 538 MB, genau wie der geführte Installer sie erstellt)
  • Erstellt eine /boot-Partition und markiere sie als RAID (Größe: 500 MB)
  • Erstellt die Root-Partition / und markiere sie als RAID (Restgröße abzüglich 1,1 GB für Swap in meinem Fall)
  • Erstellt die Swap-Partition und markiere sie als RAID (verbleibender Speicherplatz)

So sieht das dann aus:

Wiederhole diese Schritte für die zweite Festplatte.

Am Ende hast du zwei gleich konfigurierte Festplatten. Nachdem die Partitionen erstellt sind, konfiguriere drei (in meinem Fall) RAID-Geräte:

  • md0: /dev/sda3 + /dev/sdb3
  • md1: /dev/sda4 + /dev/sdb4
  • md2: /dev/sda5 + /dev/sdb5

Die RAID-Geräte nach dem Erstellen der Geräte:

Klicke auf jedes RAID-Gerät und wähle aus, wofür dieses Gerät verwendet wird:

  • md0 wird /boot mit den 500 MB Partitionen
  • md1 wird / mit den großen 478 GB Partitionen
  • md2 wird Swap mit den 1.1 GB Partitionen

Von hier aus kannst Du die Installation fortsetzen. Ab diesem Punkt funktioniert alles.

Nach der Installation

Sobald die Installation abgeschlossen ist und das System ins installierte System gebootet hat, sind noch ein paar zusätzliche Schritte notwendig.

Beobachte zuerst den RAID-Synchronisationsprozess:

cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md2 : active (auto-read-only) raid1 sda5[1] sdb5[0]
      1037312 blocks super 1.2 [2/2] [UU]
        resync=PENDING
 
md1 : active raid1 sdb4[0] sda4[1]
      466664448 blocks super 1.2 [2/2] [UU]
      [>....................]  resync =  1.6% (7880448/466664448) finish=37.0min speed=206184K/sec
      bitmap: 4/4 pages [16KB], 65536KB chunk
 
md0 : active raid1 sdb3[0] sda3[1]
      487424 blocks super 1.2 [2/2] [UU]
        resync=DELAYED
 
unused devices: <none>

Es dauert eine Weile, aber letztendlich müssen alle RAID-Geräte synchronisiert sein.

In meinem Fall war die Swap-Partition auf resync=PENDING und im auto-read-only Modus. Das ist anfangs verzögert, bis die Partition die ersten Schreibzugriffe bekommt. Du kannst das forcieren mit:

mdadm --readwrite /dev/md2
 
cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
 
md2 : active raid1 sda5[0] sdb5[1]
      1037312 blocks super 1.2 [2/2] [UU]
      [===>.................]  resync = 19.4% (201984/1037312) finish=0.0min speed=201984K/sec

EFI-Dateien auf die zweite Festplatte kopieren

Aktuell sind die EFI-Dateien nur auf der ersten Festplatte installiert (/dev/sda2 oder /dev/sdb2, je nachdem, was der Installer gewählt hat). Um auch von der zweiten Festplatte booten zu können, musst Du die Dateien von /dev/sda2 nach /dev/sdb2 oder umgekehrt kopieren. Am besten machst Du das in einem Grub-Hook, der bei jeder Grub-Aktualisierung ausgeführt wird.

Lege folgende Datei unter /etc/grub.d/90_copy_to_boot_efi2 ab, und ersetze $raid_disk_first und $raid_disk_second mit den Gerätenamen Deiner ersten und zweiten Festplatte.

#!/bin/bash
 
set -e # abort on error
set -u # abort on variable not set
#set -x # trace execution
 
# one or both devices can already be mounted, potentially with a label and not with the device name
 
device_first="/dev/{{ raid_disk_first }}"
device_second="/dev/{{ raid_disk_second }}"
 
# the findmnt will fail when the device is not mounted, that is expected
set +e
mountpoint_first=`/usr/bin/findmnt --first-only --noheadings --output=TARGET ${device_first}`
mountpoint_second=`/usr/bin/findmnt --first-only --noheadings --output=TARGET ${device_second}`
set -e
 
 
if [ -z "${mountpoint_first}" ];
then
    # not mounted, create the mount point
    path_first="/efi-first"
    /usr/bin/mkdir "${path_first}"
    echo "No existing mount point found for ${device_first}"
    echo "  Mounting on ${path_first}"
    # and mount the decive
    /usr/bin/mount "${device_first}" "${path_first}"
else
    # already mounted, use the existing mount point
    path_first="${mountpoint_first}"
    echo "Found existing mount point ${mountpoint_first} for device ${device_first}"
fi
 
if [ -z "${mountpoint_second}" ];
then
    # not mounted, create the mount point
    path_second="/efi-second"
    /usr/bin/mkdir "${path_second}"
    echo "No existing mount point found for ${device_second}"
    echo "  Mounting on ${path_second}"
    # and mount the decive
    /usr/bin/mount "${device_second}" "${path_second}"
else
    # already mounted, use the existing mount point
    path_second="${mountpoint_second}"
    echo "Found existing mount point ${mountpoint_second} for device ${device_second}"
fi
 
if [ ! -d "${path_first}/EFI" -a -d "${path_second}/EFI" ];
then
    # there's an "EFI" directory in the second mount point,
    # but not in the first one - this is wrong, and will damage
    # the installation once rsync runs
    echo "There is no 'EFI' directory in the first (source) mount point!"
    echo "But there is an 'EFI' directory in the second (destination) mount point!"
    echo "This will not work, possibly switch the devices!"
    echo "Source: ${device_first} (mounted on: ${path_first})"
    echo "Destination: ${device_second} (mounted on: ${path_second})"
    exit 1
fi
 
 
#echo "rsync --dry-run --verbose --times --recursive --delete \"${path_first}/\" \"${path_second}/\""
#rsync --dry-run --verbose --times --recursive --delete "${path_first}/" "${path_second}/"
rsync --verbose --times --recursive --delete "${path_first}/" "${path_second}/"
 
 
if [ -z "${mountpoint_first}" ];
then
    # unmount the device
    /usr/bin/umount "${path_first}"
    # remove the directory
    /usr/bin/rmdir "${path_first}"
fi
 
if [ -z "${mountpoint_second}" ];
then
    # unmount the device
    /usr/bin/umount "${path_second}"
    # remove the directory
    /usr/bin/rmdir "${path_second}"
fi
 
exit 0

Die sind für Ansible. Ich setze dieses Skript mit einem Playbook ein:

- hosts: all
  become: yes
  force_handlers: True
  vars:
    raid_disk_first: "sdb2"
    raid_disk_second: "sda2"
  tasks:

    - name: rsync packages
      ansible.builtin.apt:
        name:
          - rsync
        state: present

    - name: Upload copy_to_boot_efi2.sh
      ansible.builtin.template:
        src: "{{ playbook_dir }}/files/copy_to_boot_efi2.sh"
        dest: "/etc/grub.d/90_copy_to_boot_efi2"
        owner: "root"
        group: "root"
        mode: "0700"

Und zum Schluß installieren wir den Bootloader in beide Festplatten und updaten unseren Grub:

 grub-install /dev/sda  
 grub-install /dev/sdb  
 update-grub

Jedes Mal, wenn sich etwas auf der ursprünglichen EFI-Partition ändert, wird das Skript die andere Partition mounten und deren Inhalt synchronisieren.

Erkenntnisse

Verwende nicht den geführten Installer. Er akzeptiert fröhlich – und fälschlicherweise – eine Partition auf einem RAID, und erstellt zusätzliche Partitionen und sogar ein LVM auf genau dieser RAID-Partition. Alle Partitionen müssen manuell erstellt werden.

Wenn Du einfach nur den Anfang der Festplatte mit dd überschreibst, bevor Du neu installierst, und dann exakt dieselben Partitionen erstellst: Der Debian-Installer erkennt die RAID-Signatur der vorherigen Swap-Partition – und startet automatisch das RAID für diese Partition. Danach lässt sich auf dieser Partition nichts mehr ändern. Ich habe angefangen, wipefs zu verwenden, nachdem ich diesen Umstand herausgefunden habe.

Grub Script

Das Skript für den Grub-Hook ist auch in diesem Repository hier verfügbar: uefi-copy-with-grub.

it-wiki/linux/install_debian_bookworm_on_a_software_raid_and_efi.txt · Zuletzt geändert: 2025/04/30 06:28 von marko