Mich hat es doch gerade gereizt mit einem Testsystem, und bin auch auf einige Probleme gestoßen. Aber IMHO soweit gelöst, deshalb ein Kurzbericht (am besten erstmal ganz durchlesen):
Ausgang:
Virtualbox mit einem Arch-System und 4 Platten á 8GB (Massenspeicher, Controller SATA, kein (U)EFI)
1) ssd1 (Port0, als SSD markiert)
2) ssd2 (Port1, als SSD markiert)
3) hdd1 (Port3)
4) hdd2 (Port 4)
Gebootet wird als ISO archlinux 2017.11.01
Ziel ist: Ein Nicht-UEFI-System nutzt grub als Bootmanager. Keine eigene Bootpartition. BTRFS-Raid als Dateisysteme, SSDs und HDDs getrennt in zwei BTRFS-Volumes. Gebootet wird von den beiden SSDs, wobei der Ausfall einer Platte überstanden werden soll. Der Einfachheit halber kein Swap(device).
# loadkeys de
# lsblk (und/oder) blkid
(um zu notieren welche Devices welche sind, wir müssen wissen: welche sind die beiden SSDs, welche die HDDs)
(bei mir sind sie in der Reihenfolge der Ports, also sda/sdb sind die beiden SSDs usw.)
# fdisk -l
(listet alle Platten/Partitionen, in Virtualbox haben wir jungfräuliche Platten ohne Disklayout)
# fdisk /dev/sda (also die erste SSD)
(hier wird ein MBR/DOS Disklayout erzeugt, genau das will ich für die SSDs auch haben. Wenn diese ein GPT-Layouttyp haben sollte dieses gelöscht/ersetzt werden. Ich erzeuge eine Partition sda1 mit allen Vorgaben.)
# fdisk /dev/sdb (die zweite SSD)
(genauso wie die erste einrichten)
(jetzt die beiden HDDs, hier will ich eine GPT-layoutTabelle)
# gdisk /dev/sdc
(die GPT-Tabelle wird hier automatisch erstellt, ansonsten sicherstellen das die HDD eine GPT-Partitionlayout hat. Ebenfalls eine Partition sdc1, alle Vorgaben fvon gdisk einfach übernehmen).
# gdisk /dev/sdd
(genauso wie sdc einrichten)
(btrfs einrichten)
# mkfs.btrfs -d raid1 -m raid1 -L vol_root /dev/sda1 /dev/sdb1
# mkfs.btrfs -d raid1 -m raid1 -L vol_tank /dev/sdc1 /dev/sdd1
(zum installieren unter /mnt einhängen)
# mount LABEL=vol_root /mnt
# mkdir -p /mnt/mnt/tank
# mount LABEL=vol_tank /mnt/mnt/tank
(Subvolumes zum Testen auf beiden Verbünden erzeugen)
# mkdir -p /mnt/var/cache/pacman/
# btrfs sub create /mnt/var/cache/pacman/pkg
# mkdir -p /mnt/usr/
# btrfs sub create /mnt/usr/local
# btrfs sub list /mnt
(Zwei subvolumes in vol_root: /var/cache/pacman/pkg und /usr/local)
(nun subvolumes für vol_tank)
# btrfs sub create /mnt/mnt/tank/home
# btrfs sub create /mnt/mnt/tank/data
Hier zeigen sich IMHO die ersten Unfreudlichkeiten von btrfs zu zfs: Das Ziel für diverse btrfs-Operationen definiert sich ausschließlich über den Pfad, nicht über einen Volume-Bezeichner bei z.B. mehreren Volumes wie in unserem Fall. Wie von dir schon bemerkt werden nicht alle Subvolumes von beiden (Toplevel)-Volumes angezeigt:
# btrfs sub list -ap /mnt
(zeigt nur die subvolumes von vol_root, erst mit dem richtigen Pfad gibt es auch Zugriff auf die anderen:)
# btrfs sub list -ap /mnt/mnt/tank
Das halte ich für eine Designschwäche, da man recht höllisch aufpassen muß auf welchem Volume man agiert (z.B. bei scrub, replace, etc.) Auch das die Toplevel-Volume-IDs (und die subvolume-IDs) gleich sind bei beiden Volumes hätte ich jetzt nicht erwartet und hinterläßt einen Zwiespalt ob btrfs das "interne Verwalten" sauber trennen kann. Im weiteren Test war zwar alles sauber und ok, aber manche Möglichkeiten - z.B. mounten von Subvolums anhand der vol_id klappen halt nicht bei identischen IDs in zwei unterschiedlichen Verbünden. Alles in allem ist das Handling von btrfs schon eher auf **ein** (Toplevel)-Volume zugeschnitten. Ich konnte in Dokus jetzt auch nichts entdecken wie man "sauberer" mehrere (Top)-Volumes aufsetzen könnte. Abgesehen von diesen Anmerkungen funktioniert es aber...<g>
Stand:
a) vol_root ist nach /mnt eingehängt (wird / im realen System)
b) vol_tank ist nach /mnt/mnt/tank eingehängt (wird im realen System /mnt/tank, die Subvolumes daraus werden /home und /data)
Weiter mit der Installation:
# pacstrap /mnt base btrfs-progs mc
(mc ist ein Dateimanager mit Schweizer Taschenmesser, mein Favorit... i love it!)
# genfstab -p /mnt >> /mnt/etc/fstab
# arch-chroot /mnt
(Ich halte mich hier - im chroot - nicht groß auf mit Systemkonfiguration wie Zeitzone,Locale,Netzwerk,etc., sondern nur die zum Boot und für btrfs notwendigen Schritte:)
# echo "btr-test" > /etc/hostname
# vi /etc/mkinitcpio.conf
(Oder mit nano oder mcedit(aus mc) editieren. Der Hook btrfs muß *NICHT* rein wie ich früher schrieb, er wird durch udev integriert. Es ist sogar im weiteren Test schädlich btrfs als Hook drinzuhaben um später das System sauber mit nur einer Platte booten zu können. Vorsorglich sollte man aber bei den MODULES=() btrfs eintragen, also MODULES=(btrfs). Später mehr dazu.)
# mkinitcpio -p linux
# pacman -Sy
# pacman -S grub
Den Bootloader jetzt auf beiden Devices installieren, die am Boot beteiligt sind, also die beiden SSDs. Es ist wirklich wichtig zu wissen welches /dev/sdX zu welcher Platte und welchem unserer btrfs-Verbünde gehört!!!)
# grub-install --target=i386-pc /dev/sda
# grub-install --target=i386-pc /dev/sdb
(Wir erwarten hier beidesmal: succesfully installed ö.ä. Der Wert für --target ergibt sich aus unserem Partitionslayout MBR/msdos bei den SSDs, was uns eine eigene /boot erspart. Kein (U)EFI.)
# grub-mkconfig -o /boot/grub/grub.cfg
(grub arbeitet per Default für Devicebezeichner mit UUIDs für seine Einträge, das ist hier auch erstmal OK)
# passwd
(Root PW setzen, oder passwd ganz weglassen)
# exit
(chroot verlassen)
# umount /mnt/mnt/tank
# umount /mnt
Jetzt kann man das ISO entfernen und das System den ersten Boot machen lassen. Wenn virtualbox analog zu meinem obigem Setup genutzt wird geht da auch nichts schief - ansonsten kann alles auf OSI-Layer 8 schiefgehen <g>
Soweit, so gut: Grub als Bootloader startet nun direkt das System mit btrfs-Raid (sda1 u. sdb1). Das zum Punkt: grub kann btrfs booten (direkt halt nur da wie ohne UEFI-Zwänge arbeiten).
Wie sieht es aus:
# loadkeys de
# btrfs file show
(listet beide Volumes auf und zeigt, welche Platten wo dazugehören)
# cat /etc/fstab
(zeigt die Mountpoints für / und /mnt/tank an. Das dort lediglich /dev/sda1 für / und /dev/sdc1 für /mnt/tank steht ist richtig so und wird später noch wichtig. Bitte nicht sofort durch die LABELs oder UUIDs ersetzen (was normalerweise "vernünftig" wäre)
# mkdir /data
(nach /data kommt ein subvolume, das Verzeichnis /home ist ja schon da)
Die angelegten Subvolumes von vol_root sind ja schon im System "aktiv und am richtigen Platz". Um die aus vol_tank haben wir uns noch nicht gekümmert, also editieren wir die /etc/fstab und fügen hinzu:
# HOME subvol von vol_tank
# UUID=lange_nummer /home btrfs defaults 0 0
LABEL=vol_tank /home auto subvol=/home,defaults 0 0
# DATA subvol von vol_tank
LABEL=vol_tank /data auto subvol=/data,defaults 0 0
Hier mußte ich schon testen um die Subvolumes eben als solche einhängen zu können anhand den Infos aus:
https://wiki.archlinux.org/index.php/Btrfs#Mounting_subvolumes
Das Ansprechen über den Mountparameter subvolid= fällt ja flach da die subvolumes aus beiden (Toplevel)-Volumes ja die gleiche "ID"s haben. Namen/Labels kann man den Subvolumes auch nicht verpassen. Geht es über die UUID? Das wollte ich im wieder auskommentierten Eintrag oben (#UUID=lange_nummer) austesten.
btrfs sub show /mnt/tank/home
zeigt zwar eine UUID, leider ist die nicht zum Mounten geeignet. Also blieb nur die Syntax über das LABEL und als Mountparameter bei subvol= der Pfad. Irgendwie "unbefriedigend", aber wenigsten versteht man in einem Jahr noch was man da wohin mountet...
Als andere Alternative könnte man natürlich auch bind-Mounts verwenden um subvolumes an die Stellen einzuhängen die eigentlich außerhalb des Toplevel-Volumes liegen.
# mount /home
# mount /data
binden ad hoc beide Subvolumes an den richtigen Platz, nach einem Reboot sind ebenfalls alle Subvolumes richtig verfügbar.
Jetzt der spannende Teil mit dem Testen (dazu entferne ich im Virtualbox-Manager für diese Maschine das sdd1.vmi bei Massenspeicher. An diesem Punkt ist es auch angeraten einen Sicherungspunkt für die Maschine anzulegen in virtualbox...).
Wider erwarten lande ich genauso in der emercency shell wie du in deinen Posts #9, #14 und #15. Also das mit:
Scanning for Btrfs filesystems
[ 3.637339] BTRFS error (device sdc2): failed to read the system array: -5
[ 3.653485] BTRFS error (device sdc2): open_ctree failed
mount: /new_root: wrong fs type, bad option, bad superblock on /dev/sdc2, missing codepage or helper program, or other error.
You are now being dropped in to an emergecy shell.
Habe ich was vergessen, falsch gemacht? Hmm, eigentlich nicht.
Also virtuelle Maschine ausschalten, in den Einstellungen die sdd1.vdi wieder als Gerät bei Massenspeicher hinzufügen. Die Reihenfolge der 4 Platten ist bei mir automatisch wieder die richtige, ledigliuch den Schalter für "SSD-Laufwerk" muß ich wieder setzen. Man kann vor dem Neustart nun zum Sicherungspunkt zurückkehren (sichere Seite) oder booten und mit einigen btrfs-Meldungen leben. Wir müssen nur sauber booten können um nun einige Konfig-Änderungen durchzuführen. Da ich ohne den alten Sicherungspunkt bootete habe ich sicherheitshalber nochmal ein:
btrfs scrub start /
angestoßen und laufen lassen.
Warum bootet es nicht mit nur einer Disk? An grub liegt es nicht (der startete und beendete sich ja auch nur mit einer Disk). Es muß am initrd-Image liegen.
Nach nochmaliger Überprüfung ob ich eigentlich alles richtig gemacht habe stieß ich dann auf folgendes:
https://wiki.archlinux.org/index.php/Btrfs#Missing_root
Ich habe mich dann für den ersten "Workaround" entschlossen. Also die /etc/mkinitcpio.conf editieren soweit das:
a) btrfs nicht bei den Hooks steht
b) btrfs als zu ladendes Modul in MODULES= steht
(beides hatte ich weiter oben ja schon mal während der Installation so aufgezeigt).
Mit:
mkinitcpio -p linux das initrd neu erstellen lassen.
Der zweite Punkt beim Workaround ist der mit den "degraded" Optionen in fstab und Kernelparameter.
In /etc/fstab also den Eintrag für / editieren und bei den Mountoptionen ein "degraded" anfügen, also "...subvol=/,degraded 0 0"
Weiter editieren die /boot/grub/grub.cfg. Dort den Eintrag "menuentry 'Arch Linux'" suchen, darin etwas runter ist die Kernelzeile:
linux /boot/vmlinuz-linux root=lange_uuid
Hier würde ich quiet erstmal entfernen und hinter "rw" muß dann als weiterer Parameter: rootflags=degraded, also:
linux /boot/vmlinuz-linux root=lange_uuid rw rootflags=degraded
Erstmal rebooten mit allen Platten um zu sehen ob man was falsch geschrieben hat.
Trommelwirbel!
Nachdem ich für die Maschine sdd1.vdi wieder entfernt hatte bootete das System diesmal auch mit nur einer Platte sauber durch.
Was ich vermißt habe waren *auffällige* Warnhinweise bei den Bootmeldungen daß ja eine Platte in einem Volume nicht mehr vorhanden ist. In journalctl -b bzw. durch eingestreute Meldungen auf der Konsole kriegt man es dann aber schon mit.
Stand momentan: Das System ist noch/wieder zu gebrauchen, allerdings ist das btrfs-Raid1 vol_root ja "kaputt". Mit realer Hardware würde man jetzt wohl am besten daß kaputte Device aus dem Verbund entfernen (btrfs dev remove ...), neue HD kaufen, APrtition einrichten und wieder dem vol_root-Verbund hinzufügen.
Da mein virtuelles Device sdd1.vdi ja ok ist habe ich nun erstmal nur folgendes getestet:
a) in dem laufenden "kaputten" System ein paar Dateien aus /vat/cache/pacman/pkg nach /root kopiert um etwas massivere Datenänderungen gegenüber dem nicht eingebundenen sdd1.vdi zu simulieren. Dann das System runterfahren.
b) Das sdd1.vdi wieder wie oben angeführt als Massenspeicher an die richtige Stelle eingestellt.
c) Neustart. Das System bootet (wieder mit 2 Platten), es bootet auch durch, allerdings weisen etliche Fehlermeldungen schon darauf hin das wohl massiv was nicht richtig ist.
Klar: auf der sdd2 (also /dev/sdb1) ist ja nun ein neuer, unterschiedlicher Datenzustand. Wie kriegen wir das wieder synchron ohne die "neuen" Daten zu verlieren?
Wenn man die auf die Konsole einpoppenden Meldungen und das journalctl -f mal etwas verfolgt sieht man:
a) Unterschiede werden stark angemeckert
b) gleichzeitig werden im Hintergrund auch schon Dateien/Inhalt nach sda1 (die ja weg war) synchronisiert. Also eine der Stärken von btrfs, auch als Raid sinnvoll zu arbeiten und Konsistenz zu erreichen.
Trotzdem ist/wäre es wohl sinnvoll, gezielt dieses "Weg-mit-der-Platte-rein-mit-der-Platte " aufzulösen. fsck.btrfs fällt raus, da unser Problemvolume vol_root ja in Gebrauch gemountet ist.
Ein scrub-Lauf zum Wiederherstelle der Synchronität ist nach Doku wohl auch nicht das ware, also habe ich:
btrfs balance start /
angestossen. Im journal (journalctl -f) sieht man die Meldungen was "balanciert" wird, und
btrfs balance status /
zeigt den Fortgang und wieviel/was am Ende repariert wurde (also Content von sdb1 nach sda1). Das lief hier ohne Nichtwiederherstellbares durch. Danach habe ich sicherheitshalber noch einen scrub-Lauf für / gemacht.
Fazit: das Raid von vol_root ist wieder intakt und synchron, das Dateisystem ist auch konsistent (die zuvor kopierten Dateien in /root sind weiterhin ja. Patient lebt wieder.
Jetzt habe ich keine Lust mehr zu schreiben... ;-)
Aber das wäre ein Setup in virtualbox um das Ganze prinipiell zu testen, Vertrauen zu fassen.
Knackpunkt das es nicht schon beim ersten Bootversuch mit nur einer Platte für vol_root klappte war das "As of November 2014 there seems to be a bug in systemd or mkinitcpio causing the following error..." für die open_ctree emecency cell. Durch die degraded Optionen in fstab und Kernelparameter kann man das auch umschiffen (Die andere(n) Möglichkeiten beim verlinkten BTRFS-Wiki zum Problem, also "As of August 2016,..." habe ich bisher nicht getestet.
Was du aus meinem Geschreibsel/Tests jetzt für dich konkret rausziehst mußt du selbst wissen, v.a. da du bei deinem Setup/Versuchen doch bei mdadm für sperate /boot tendierst.
Obiges Setup in Virtualbox ist ja weitgehend an deine Hardware angelegt - wenn du also auf (U)EFI verzichten würdest/könntest, dann wäre das nahezu 1:1 adoptierbar. Evtl. inspiriert es dich ja dazu es genauso mal in Virtualbox auszuprobieren, das Aufsetzen/Testen dauert auf jedenfall weniger Zeit als die, die ich zunm Einmeiseln dieses Postings gebraucht habe ;-)
PPS: Da du ja in den ctree-Fehler mit mdadm und /boot->vfat reinkommst: Der Kernelbootparameter in grub.cfg "rootflags=degraded" könnte auch da greifen. Vielleicht teste ich dieses Setup (UEFI) auch mal in virtualbox aus...
Schluß.....