FreeBSD mit vollverschlüsseltem ZFS RAID-Z1 als Gast in qemu auf einem debian host

Dabei wiederum ein debian gast im bhyve des virtuellen freebsd

reinhard@finalmedia.de Wed 13 Oct 2021 10:34:46 PM CEST

Spaß mit Virtuellem:

Ziel: auf einem debian host mit qemu genattet ein freebsd als gast mit ZFS auf drei verteilten (redundanz) und identisch vollverschlüsselten LUKS Container Images installieren, dabei das ZFS selbst wiederum erneut mit GELI vollverschlüsseln und dort im freebsd dann mit bhyve hypervisor dann wiederum ein debian 11 linux als gast installieren, der wiederum selbst erneut LVM und eine weitere eigenständige LUKS Verschlüsselung verwendet.



# freebsd und debian iso herunterladen

wget -c https://download.freebsd.org/ftp/releases/ISO-IMAGES/13.0/FreeBSD-13.0-RELEASE-amd64-mini-memstick.img
wget -c https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-11.1.0-amd64-netinst.iso

# alternativ auch statt dem debian netinstaller die dvd
wget -c https://cdimage.debian.org/debian-cd/current/amd64/iso-dvd/debian-11.1.0-amd64-DVD-1.iso

# variablen definition

keyfile="demo.freebsd.luks.key"

imagefile00="demo.freebsd.luks.disk00.img"
imagefile01="demo.freebsd.luks.disk01.img"
imagefile02="demo.freebsd.luks.disk02.img"

# unsere virtuellen festplatten der Demo setzen wir jeweils auf 8GB. Also werden wir auch
# 3x8=24 GB belegen. Für Produktivsysteme würdest du hier natürlich mehr Speicherplatz
# zur Verfügung stellen.

imagesize="8G"

installerfile="FreeBSD-13.0-RELEASE-amd64-mini-memstick.img"

# keyfile mit passphrase für LUKS erstellen.
# Wir verzichten dabei bei dem zufällig erzeugten 32-stelligen Kennwort auf
# potentiell verwechselbare Zeichen wie Eins, Null, Oh, kleines L, großes I etc.

test ! -f "$keyfile" && umask 077 && \
tr -dc "0-9a-zA-Z" < /dev/urandom | tr -d "01IloO" | head -c 32 > "$keyfile"


# 3 LUKS disk images erstellen
# macht jetzt hier scheinbar keinen sinn, weil sie ja alle drei am gleichen platz liegen
# und auch das keyfile direkt daneben. Das ist jetzt nur symbolisch!
# Man verteilt diese image-files dann später auch
# auf separate filer und mountpoints, oder arbeitet direkt mit qemu-nbd auf drei
# separaten hosts direkt übers netzwerk. Nur das winzige keyfile hat man dann dort wo auch
# der hypervisor läuft. zu qemu-nbd erfährst du in einem anderen tutorial mal mehr.

test ! -f "$imagefile00" && qemu-img create -f luks \
--object secret,id=sec0,file="$keyfile" \
-o key-secret=sec0 "$imagefile00" "$imagesize"

test ! -f "$imagefile01" && qemu-img create -f luks \
--object secret,id=sec0,file="$keyfile" \
-o key-secret=sec0 "$imagefile01" "$imagesize"

test ! -f "$imagefile02" && qemu-img create -f luks \
--object secret,id=sec0,file="$keyfile" \
-o key-secret=sec0 "$imagefile02" "$imagesize"


# qemu starten und dabei in den freebsd installer booten
qemu-system-x86_64 -enable-kvm \
-boot menu=on,reboot-timeout=4 -cpu host -smp cores=2 -m 2048 \
-object secret,id=sec0,file="$keyfile" \
-object secret,id=sec1,file="$keyfile" \
-object secret,id=sec2,file="$keyfile" \
-device ahci,id=ahci \
-drive if=none,id=drive0,driver=luks,key-secret=sec0,file="$imagefile00" \
-device ide-drive,bus=ahci.0,drive=drive0 \
-drive if=none,id=drive1,driver=luks,key-secret=sec1,file="$imagefile01" \
-device ide-drive,bus=ahci.1,drive=drive1 \
-drive if=none,id=drive2,driver=luks,key-secret=sec2,file="$imagefile02" \
-device ide-drive,bus=ahci.2,drive=drive2 \
-drive if=none,id=drive3,driver=raw,file="$installerfile" \
-device ide-drive,bus=ahci.3,drive=drive3 \
-vga qxl --sandbox on -usb -k de -monitor /dev/null \
-netdev user,restrict=off,id=net0,hostfwd='tcp:127.0.0.1:2222-:22',hostfwd='tcp:127.0.0.1:5901-:5900' \
-device e1000,netdev=net0 \
-rtc base=localtime,clock=host


QEMU bootet nun in den FreeBSD-Installer. Dann das Setup durchführen und ZFS verwenden, allerdings statt STRIPE eben RAID-Z1 auswählen und auf die 3 Disks verteilen. Nenne den neuen ZFS pool root dann "finalmedia"(!), denn im weiteren Verlauf der Anleitung referenzieren wir diesen Namen.

Zudem Verschlüsselung des ZFS auswählen und auch die SWAP als MIRROR anlegen und zudem verschlüsseln. Eine Passphrase für den ZFS Pool wählen und notieren!. Diese muss dann immer eingegeben werden, wenn freebsd gebootet wird!!!

Hier Schritt für Schritt die Dialoge des Installers:

ESC drücken und die 4 auswählen, um das USB-Installer Image zu booten, das wir ja als viertes AHCI Laufwerk eingebunden haben

QEMU bootet in den FreeBSD Installer...

Hier Punkt 1 und ENTER drücken oder einfach 8 Sekunden warten.

"Install" auswählen...

Deutsches Keyboard "German" auswählen...

Danach wieder im obersten Menüpunkt "Continue with de.kbd keymap" auswählen.

Wir nennen das Testsystem einfach "freebsd". Die Namenswahl steht dir hier aber frei.

Für die demo brauchen wir keine zusätzlichen Systemkomponenten. Die anderen Angaben wählen wir daher alle ab, und wählen dann "OK".

Wir werden darüber informiert, dass wir nur ein Mini-Installer-Image einsetzen und einige Pakete aus dem Internet nachgeladen werden müssen bei der Installation. Iss klar. Bestätigen wir mit "OK".

Wir wählen die virtuelle Netzwerkkarte, die uns qemu zur Verfügung stellt und die ja genattet wird.

"Yes"... Wir konfigurieren eine IPv4 Adresse...

"Yes"... Wir möchten die IPV4 Adresse, die ja von QEMU via dhcp automatisch zur Verfügung gestellt wird.

"No"... IPv6 benötigen wir für die demo nicht.

"OK"... Als DNS wird (bereits via dhcp von qemu propagiert) der 10.0.2.3 eingetragen, da qemu ja als dns proxy fungiert.

Wir wählen als Paketquelle einen deutschen Spiegelserver ftp://ftp.de.freebsd.org

"Auto (ZFS)" Und wir werden die Installation auf ZFS durchführen, automatisiert.

Allerdings passen wir das Setting an. Beim Punkt "T" für Pool Type wählen wir Statt Stripe...

"raidz1" also als Typ RAID-Z1 aus.

und dabei wählen wir die Platten ada0,ada1,ada2. Jedoch nicht ada3, denn das ist unser Installer.

Wir aktivieren mit "E" die ZFS Verschlüsselung

Den Pool-Namen "N" ändern wir von zroot auf finalmedia

Und aktivieren mit "M" auch die SWAP Spiegelung

... sowie mit "W" auch die SWAP Verschlüsselung

Jetzt fahren wir mit der Installation fort, indem wir im obersten Menüpunkt "Proceed with Installation" auswählen

...und erneut mit "YES" bestätigen, dass wir die drei angegeben Laufwerke mit der Installation plattmachen werden.

Hier müssen wir nun eine GELI (Geom ELI) Passphrase definieren, die für die Laufwerks-Vollverschlüsselung verwendet wird.

Du wirst die gewählte Passphrase zweimal eingeben müssen. Notiere dir die Passphrase, die du wählst. Du wirst sie bei jedem Systemstart brauchen, um die AES Vollverschlüsselung zu entsperren.

Verschlüsselung intialisiert und logs gehts mit der Installation und dem Download der übrigen Pakete

Wähle bitte nun ein root-Passwort und merke dir dies!

Du musst es zur Bestätigung erneut eingeben.

Nun noch die Zeitzone definieren. 7 Europe.

Und wir wohnen in Deutschland. Germany.

Wir möchten auch, dass der openssh daemon installiert wird.

Und wir hätten das System gern etwas stärker gehärtet, aktivieren also alle Security Hardening Optionen und bestätigen mit "OK".

"YES", Wir fügen nun noch einen normalen Systemuser hinzu.

Wir verlassen mit Exit den Installer und Wenden damit alle Konfigurationsoptionen an

"No", wir brauchen keine weitere Shell um noch Zusatzänderungen vorzunehmen.

QEMU bitte nun beenden! Nun erneut qemu in freebsd booten. Aber nicht mehr den freebsd installer einhängen. Stattdessen nun die debian iso als cdrom einhängen, damit freebsd damit arbeiten kann und bhyve (dem freebsd hypervisor) davon installieren kann. Unser QEMU Startaufruf sieht daher wie folgt aus.




keyfile="demo.freebsd.luks.key"
imagefile00="demo.freebsd.luks.disk00.img"
imagefile01="demo.freebsd.luks.disk01.img"
imagefile02="demo.freebsd.luks.disk02.img"
imagesize="8G"
isofile="debian-11.1.0-amd64-netinst.iso"

# images erstellen, wenn nicht existent
test ! -f "$imagefile00" && qemu-img create -f luks \
--object secret,id=sec0,file="$keyfile" \
-o key-secret=sec0 "$imagefile00" "$imagesize"
test ! -f "$imagefile01" && qemu-img create -f luks \
--object secret,id=sec0,file="$keyfile" \
-o key-secret=sec0 "$imagefile01" "$imagesize"
test ! -f "$imagefile02" && qemu-img create -f luks \
--object secret,id=sec0,file="$keyfile" \
-o key-secret=sec0 "$imagefile02" "$imagesize"

# qemu starten
qemu-system-x86_64 -enable-kvm \
-boot menu=on,reboot-timeout=4 -cpu host -smp cores=2 -m 2048 \
-object secret,id=sec0,file="$keyfile" \
-object secret,id=sec1,file="$keyfile" \
-object secret,id=sec2,file="$keyfile" \
-device ahci,id=ahci \
-drive if=none,id=drive0,driver=luks,key-secret=sec0,file="$imagefile00" \
-device ide-drive,bus=ahci.0,drive=drive0 \
-drive if=none,id=drive1,driver=luks,key-secret=sec1,file="$imagefile01" \
-device ide-drive,bus=ahci.1,drive=drive1 \
-drive if=none,id=drive2,driver=luks,key-secret=sec2,file="$imagefile02" \
-device ide-drive,bus=ahci.2,drive=drive2 \
-vga qxl --sandbox on -usb -k de -monitor /dev/null \
-netdev user,restrict=off,id=net0,hostfwd='tcp:127.0.0.1:2222-:22',hostfwd='tcp:127.0.0.1:5901-:5900' \
-device e1000,netdev=net0 \
-rtc base=localtime,clock=host \
-cdrom "$isofile" \
-daemonize


Hier nun die GELI Passphrase zum Entsperren der Laufwerksvollverschlüsselung eingeben. Das wird bei jedem Boot-Prozess notwendig sein.

Wir loggen uns nun als root ein, mit dem Kennwort das wir zuvor gesetzt haben.

Wir sorgen nun noch dafür, dass wir uns als root via ssh verbinden können, da wir so bequemer weiterarbeiten können, als im grafikterminal von qemu.

Dazu passen wir die openssh daemon config so an, dass ein rootlogin gestattet wird. Das ist nur temporär! Für den Produktivzugriff später würdest du das wieder zurückstellen und keybasierten login verwenden.

du kannst dich nun auch via ssh zum freebsd verbinden, dazu auf deinem System, auf dem auch der QEMU Hypervisor läuft einfach:

ssh -p 2222 root@127.0.0.1

nutzen, weil wir das ja in qemu auf diesen port durchreichen.



# im freebsd pakete installieren und bhyve an den start bringen


pkg install lsof
pkg install daemontools
service svscan enable
service svscan start

pkg install grub2-bhyve
pkg install bhyve bhyve-firmware bhyve+
pkg install uefi-edk2-bhyve


# eine bridge erzeugen und benennen
ifconfig bridge create name em0bridge
ifconfig em0bridge up

# für die virtuelle maschine ein tap device erzeugen
ifconfig tap create name tapdebianvm

# tap und die em0 nic auf der bridge zusammenführen
ifconfig em0bridge addm tapdebianvm
ifconfig em0bridge addm em0
ifconfig em0 up
ifconfig tapdebianvm up

# ZFS gibt uns tolle möglichkeiten für das disk image der vm...
# cloning und backups. ganz out-of-the-box und ohne dass byhve
# da was tun muss.
# wer das nicht möchte, kann natürlich auch einfach mit einer
# containerdatei arbeiten, die dann regulär im dateisystem liegt.
# wir nutzen aber die funktionalität von ZFS und erstellen daher
# das image in zfs... also
# einen 4GB speicherbereich als virtuelle platte für die vm
# im zfspool erzeugen (unser zroot pool heißt finalmedia)
# damit können wir später bequem ro-snapshots erzeugen und diese
# dann auch sichern.

zfs create -V4G -o volmode=dev finalmedia/debianvm
zfs list


bhyvectl --destroy --vm=debianvm

# debian iso, wenn existent, ansonsten /dev/null
set iso="/dev/iso9660/Debian%2011.0.0%20amd64%20n"
test -e "$iso" || set iso="/dev/null"

# jetzt den hypervisor starten, der dann per VNC erreichbar ist
# auf port 5900. da wir die 5900 im übergeordneten qemu ja durchreichen,
# also von außen via 5901.
# -s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600,wait \

bhyve -c 1 -m 1024M -w -H -D \
-s 0,hostbridge \
-s 3,ahci-cd,"$iso" \
-s 4,ahci-hd,/dev/zvol/finalmedia/debianvm \
-s 5,virtio-net,tapdebianvm \
-s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600 \
-s 30,xhci,tablet \
-s 31,lpc -l com1,stdio \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
debianvm


Auf deinem host, also dem initialen debian host, auf dem qemu läuft, da kannst du nun das hier ausführen

xvncviewer 127.0.0.1::5901

..um zu port 5901 via VNC zu verbinden und dir das setup des inneren debians des byhve anzuzeigen. Hier einfach wie gehabt dann dein Debian installieren.

Da Debian die EFI Payload nicht in "boot" sondern "debian" erzeugt, failed nach der Installation das Booten aus der Platte mit:


BdsDxe: faild to load Boot0001 ... PciRoot... 
Start PXE over IPv4

Warte eine Zeit lang, bis zu in der UEFI Shell landest. Alternativ kannst du im TianoCore auch ESC F2 drücken, um im byhve Menü eine andere Bootquelle zu wählen. Generel musst in die EFI shell. Dort kannst du dann das hier ausführen:


Shell> FS0:
FS:\>cd EFI
FS:\EFI\cd debian
FS:\EFI\debian\>grubx64.efi

Damit bootest du manuell in das frisch installierte Debian Installation.

Dann musst du grub erneut unter dem prefix "boot" installieren, das die UEFI firmware von bhyve erwartet. Also aus dem debian heraus das hier ausführen:


grub-install --bootloader-id=boot

um grub nach EFI/boot statt nach EFI/debian zu installieren. Zudem musst du auch grubx64.efi zu bootx64.efi kopieren. Auch das in dem gebooteten debian:


cd /boot/efi/EFI/boot/
cp grubx64.efi bootx64.efi

Nach einem Neustart solltest du nun in deinem debian landen:


reboot

Hier Screenshots vom Prozess

ÜBUNG01 - RECOVERY eines failed drives im bootfähigen, vollverschlüsselten ZFS mit FreeBSD

reinhard@finalmedia.de Fr 22. Okt 11:20:29 CEST 2021

Beispiel: Simulation des Ausfalls der ersten Platte! (in unserem virtualisieren freebsd ist das dann /dev/ada0)

Wir stoppen qemu. Wir lassen disk0 virtuell failen, indem wir das imagefile im hypervisor filesystem einfach umbenennen:


mv demo.freebsd.luks.disk00.img demo.freebsd.luks.disk00.DEFEKTTEST.img


Im Anschluss erzeugen wir automatisch mit dem bekannten script erneut eine imagedatei für disk0 demo.freebsd.luks.disk00.img als leeres luks image und hängen das leere volume in die vm wieder ein. für den freebsd gast sieht es also so aus, als hätte man ihm die bestehende festplatte ada0 entfernt und durch eine neue, gleichgroße leere Platte ersetzt.



keyfile="demo.freebsd.luks.key"
imagefile00="demo.freebsd.luks.disk00.img"
imagefile01="demo.freebsd.luks.disk01.img"
imagefile02="demo.freebsd.luks.disk02.img"
imagesize="8G"

# images erstellen, wenn nicht existent
test ! -f "$imagefile00" && qemu-img create -f luks \
--object secret,id=sec0,file="$keyfile" \
-o key-secret=sec0 "$imagefile00" "$imagesize"
test ! -f "$imagefile01" && qemu-img create -f luks \
--object secret,id=sec0,file="$keyfile" \
-o key-secret=sec0 "$imagefile01" "$imagesize"
test ! -f "$imagefile02" && qemu-img create -f luks \
--object secret,id=sec0,file="$keyfile" \
-o key-secret=sec0 "$imagefile02" "$imagesize"

# qemu starten
qemu-system-x86_64 -enable-kvm \
-boot menu=on,reboot-timeout=4 -cpu host -smp cores=2 -m 2048 \
-object secret,id=sec0,file="$keyfile" \
-object secret,id=sec1,file="$keyfile" \
-object secret,id=sec2,file="$keyfile" \
-device ahci,id=ahci \
-drive if=none,id=drive0,driver=luks,key-secret=sec0,file="$imagefile00" \
-device ide-drive,bus=ahci.0,drive=drive0 \
-drive if=none,id=drive1,driver=luks,key-secret=sec1,file="$imagefile01" \
-device ide-drive,bus=ahci.1,drive=drive1 \
-drive if=none,id=drive2,driver=luks,key-secret=sec2,file="$imagefile02" \
-device ide-drive,bus=ahci.2,drive=drive2 \
-vga qxl --sandbox on -usb -k de -monitor /dev/null \
-netdev user,restrict=off,id=net0,hostfwd='tcp:127.0.0.1:2222-:22',hostfwd='tcp:127.0.0.1:5901-:5900' \
-device e1000,netdev=net0 \
-rtc base=localtime,clock=host \
-daemonize


SO, was ist nun anders?!

qemu startet... doch der boot failed, weil qemu von AHCI/0 drive booten will, die ja als frisch angelegtes image natürlich leer ist. beim boot in qemu wählen wir also im bootmenu mit der ESC Taste die nächste platte AHCI/1 aus (also 2 drücken).

qemu bootet das FreeBSD von dort und wir werden nach der bekannten GELI passphrase gefragt. Das System fährt dann regulär hoch und ist nutzbar.

Das ZFS im FreeBSD gilt jedoch als DEGRADED, sowie auch der gmirror für die SWAP ist DEGRADED und natürlich fehlt uns auch der bootloader auf der neuen frischen platte. Siehe mit diesen Befehlen im gebooteten FreeBSD Gast:


root@freebsd:~ # zpool status
  pool: finalmedia
 state: DEGRADED
status: One or more devices could not be opened.  Sufficient replicas exist for
        the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-2Q
config:

        NAME            STATE     READ WRITE CKSUM
        finalmedia      DEGRADED     0     0     0
          raidz1-0      DEGRADED     0     0     0
            ada0p3.eli  UNAVAIL      0     0     0  cannot open
            ada1p3.eli  ONLINE       0     0     0
            ada2p3.eli  ONLINE       0     0     0


das hängt damit zusammen, dass es auch gar keine partitionstabelle, kein bootloader und keine GELI Verschlüsselung mehr auf der neuen ausgetauschten leeren ada0 mehr gibt. ist ja blanko device. siehe geometry table:


root@freebsd:~ # geom -t
Geom                    Class      Provider
swap.sync               MIRROR
ada0                    DISK       ada0
  ada0                  DEV
ada1                    DISK       ada1
  ada1                  PART       ada1p1
    ada1p1              LABEL      gpt/gptboot1
      gpt/gptboot1      DEV
    ada1p1              DEV
  ada1                  PART       ada1p2
    swap                MIRROR     mirror/swap
      mirror/swap.eli   ELI        mirror/swap.eli
        swap            SWAP
        mirror/swap.eli DEV
      mirror/swap       DEV
    ada1p2              DEV
  ada1                  PART       ada1p3
    ada1p3.eli          ELI        ada1p3.eli
      ada1p3.eli        DEV
      zfs::vdev         ZFS::VDEV
    ada1p3              DEV
  ada1                  DEV
ada2                    DISK       ada2
  ada2                  PART       ada2p1
    ada2p1              LABEL      gpt/gptboot2
      gpt/gptboot2      DEV
    ada2p1              DEV
  ada2                  PART       ada2p2
    swap                MIRROR     mirror/swap
      mirror/swap.eli   ELI        mirror/swap.eli
        swap            SWAP
        mirror/swap.eli DEV
      mirror/swap       DEV
    ada2p2              DEV
  ada2                  PART       ada2p3
    ada2p3.eli          ELI        ada2p3.eli
      ada2p3.eli        DEV
      zfs::vdev         ZFS::VDEV
    ada2p3              DEV
  ada2                  DEV
ada3                    DISK       ada3
  ada3                  DEV
root@freebsd:~ #


Auch sehen wir deutlich, dass es nur noch auf den beiden verbleibenden Platten sinnvolle Partitionstabellen gibt:


root@freebsd:~ # gpart show
=>      40  16777136  ada1  GPT  (8.0G)
        40      1024     1  freebsd-boot  (512K)
      1064       984        - free -  (492K)
      2048   2097152     2  freebsd-swap  (1.0G)
   2099200  14675968     3  freebsd-zfs  (7.0G)
  16775168      2008        - free -  (1.0M)

=>      40  16777136  ada2  GPT  (8.0G)
        40      1024     1  freebsd-boot  (512K)
      1064       984        - free -  (492K)
      2048   2097152     2  freebsd-swap  (1.0G)
   2099200  14675968     3  freebsd-zfs  (7.0G)
  16775168      2008        - free -  (1.0M)



ok. wir nehmen erst mal die ZFS Partition der alten ada0 aus dem zpool


root@freebsd:~ zpool offline finalmedia ada0p3.eli

Wir klonen nun die partitionstabelle der noch aktiven zweiten Platte (ada1) auf die neue erste Platte (ada0)



root@freebsd:~ gpart backup ada1 | gpart restore ada0


und nun schauen wir uns nochmal die Partitionstabellen an:



root@freebsd:~ gpart show

=>      40  16777136  ada1  GPT  (8.0G)
        40      1024     1  freebsd-boot  (512K)
      1064       984        - free -  (492K)
      2048   2097152     2  freebsd-swap  (1.0G)
   2099200  14675968     3  freebsd-zfs  (7.0G)
  16775168      2008        - free -  (1.0M)

=>      40  16777136  ada2  GPT  (8.0G)
        40      1024     1  freebsd-boot  (512K)
      1064       984        - free -  (492K)
      2048   2097152     2  freebsd-swap  (1.0G)
   2099200  14675968     3  freebsd-zfs  (7.0G)
  16775168      2008        - free -  (1.0M)

=>      40  16777136  ada0  GPT  (8.0G)
        40      1024     1  freebsd-boot  (512K)
      1064       984        - free -  (492K)
      2048   2097152     2  freebsd-swap  (1.0G)
   2099200  14675968     3  freebsd-zfs  (7.0G)
  16775168      2008        - free -  (1.0M)


sieht schon mal gut aus. nun fehlt uns noch der bootloader auf der neuen ada0. Diesen schreiben wir aus dem aktiv gebooteten system auf die neue leere platte


root@freebsd:~ gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
partcode written to ada0p1
bootcode written to ada0

Soweit so gut. Nun ist die zweite partion (swap) ja ein mirror und auch degraded es sind nur die beiden anderen platten drin, nicht unsere ada0. siehe:


root@freebsd:~ # gmirror status
       Name    Status  Components
mirror/swap  DEGRADED  ada1p2 (ACTIVE)
                       ada2p2 (ACTIVE)

wir adden also nochmal die zweite partition der ada0, also ada0p2


root@freebsd:~ # gmirror forget swap
root@freebsd:~ # gmirror insert -h swap /dev/ada0p2

root@freebsd:~ # gmirror status
       Name    Status  Components
mirror/swap  DEGRADED  ada1p2 (ACTIVE)
                       ada2p2 (ACTIVE)
                       ada0p2 (SYNCHRONIZING, 18%)

sehr schön... nach einiger zeit sieht es dann so aus



root@freebsd:~ # gmirror status
       Name    Status  Components
mirror/swap  COMPLETE  ada1p2 (ACTIVE)
                       ada2p2 (ACTIVE)
                       ada0p2 (ACTIVE)


nun müssen wir auch noch GELI (die FreeBSD Laufwerks-Vollverschlüsselung) für ada0 wieder an den start bringen, denn wir haben zwar /dev/ada0p3 aber kein /dev/ada0p3.eli. Siehe auch:


root@freebsd:~ # geli status
           Name  Status  Components
     ada1p3.eli  ACTIVE  ada1p3
     ada2p3.eli  ACTIVE  ada2p3
mirror/swap.eli  ACTIVE  mirror/swap

Wir erstellen ein GELI backup der Partition 3 der noch funktionierenden zweiten Platte (ada1p3) und importieren das in einem rutsch auf die Partition 3 der ausgetauschten ersten Platte (ada0p3)


root@freebsd:~ geli backup ada1p3 /dev/stdout | geli restore /dev/stdin ada0p3

Wir adden nun die partition 3 der ersten neuen platte wieder in geli und werden dabei zur eingabe der GELI passhrase aufgefordert.


root@freebsd:~ # geli attach ada0p3
Enter passphrase:


root@freebsd:~ # geli status
           Name  Status  Components
     ada1p3.eli  ACTIVE  ada1p3
     ada2p3.eli  ACTIVE  ada2p3
mirror/swap.eli  ACTIVE  mirror/swap
     ada0p3.eli  ACTIVE  ada0p3


jetzt existiert auch wieder ein ada0p3.eli, welches wir wieder für den zfs pool nutzen können, siehe


root@freebsd:~ # ls /dev/ada0p3*
/dev/ada0p3     /dev/ada0p3.eli

Wir schalten daher die GELI Partion 3 von ada im ZFS pool wieder online und werden daran erinnert, das Laufwerk zu ersetzen


root@freebsd:~ # zpool online finalmedia ada0p3.eli

warning: device 'ada0p3.eli' onlined, but remains in faulted state
use 'zpool replace' to replace devices that are no longer present

Wir ersetzen das laufwerk durch das neue. Da sich die Nomenklatur nicht geändert hat, müssen wir den Namen nur einmal wählen, weil alt und neu indentisch sind:


root@freebsd:~ # zpool replace finalmedia ada0p3.eli

...und in Kürze beginnt automatisch das resilvering. Schau dir das nach einigen Minuten so an


root@freebsd:~ # zpool status -x
  pool: finalmedia
 state: DEGRADED
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
  scan: resilver in progress since Fri Oct 22 11:30:08 2021
        6.58G scanned at 79.3M/s, 3.78G issued at 45.6M/s, 6.58G total
        1.10G resilvered, 57.47% done, 00:01:02 to go
config:

        NAME                  STATE     READ WRITE CKSUM
        finalmedia            DEGRADED     0     0     0
          raidz1-0            DEGRADED     0     0     0
            replacing-0       DEGRADED     0     0     0
              ada0p3.eli/old  OFFLINE  0     0     0
              ada0p3.eli/old  UNAVAIL  0     0     0  cannot open
              ada0p3.eli      ONLINE       0     0     0  (resilvering)
            ada1p3.eli        ONLINE       0     0     0
            ada2p3.eli        ONLINE       0     0     0

errors: No known data errors



Je nach Größe der Platten, sehen wir dann nach einer gewissen Zeit, dass alles erfolgreich neuversilbert wurde und wieder gesund und munter, strahlend glänzt:


root@freebsd:~ # zpool status -x
all pools are healthy

root@freebsd:~ # zpool status
  pool: finalmedia
 state: ONLINE


  scan: resilvered 2.16G in 00:03:20 with 0 errors on Fri Oct 22 13:03:57 2021
config:

        NAME            STATE     READ WRITE CKSUM
        finalmedia      ONLINE       0     0     0
          raidz1-0      ONLINE       0     0     0
            ada0p3.eli  ONLINE       0     0     0
            ada1p3.eli  ONLINE       0     0     0
            ada2p3.eli  ONLINE       0     0     0

root@freebsd:~ # zfs list
NAME                      USED  AVAIL     REFER  MOUNTPOINT
finalmedia               7.89G  5.33G      128K  /finalmedia
finalmedia/ROOT          1.51G  5.33G      128K  none
finalmedia/ROOT/default  1.51G  5.33G     1.51G  /
finalmedia/debianvm      5.46G  8.84G     1.95G  -
finalmedia/tmp            128K  5.33G      128K  /tmp
finalmedia/usr            941M  5.33G      128K  /usr
finalmedia/usr/home       128K  5.33G      128K  /usr/home
finalmedia/usr/ports      940M  5.33G      940M  /usr/ports
finalmedia/usr/src        128K  5.33G      128K  /usr/src
finalmedia/var            842K  5.33G      128K  /var
finalmedia/var/audit      128K  5.33G      128K  /var/audit
finalmedia/var/crash      128K  5.33G      128K  /var/crash
finalmedia/var/log        202K  5.33G      202K  /var/log
finalmedia/var/mail       128K  5.33G      128K  /var/mail
finalmedia/var/tmp        128K  5.33G      128K  /var/tmp


Also alles wieder ok. wir können nun ein reboot von freebsd durchführen.

Das System wird wieder sauber von der ersten Platte (AHCI/0) booten können und uns auch nach der GELI passphrase fragen.