Festplatten sind teuer und gehen regelmäßig kaputt. Deswegen haben Rechner mit Daten bei mir zumeist ein RAID Setup und werden regelmäßig gesichert. Alle schützenswerten Daten liegen auf meinem FreeNAS Storage, ebenso die Musik- und Filmsammlung sowie die Backups der anderen Rechner werden hier verewigt. Die wirklich wichtigen Daten werden zu einem off-site Backup synchronisiert. Doch Festplatten mit weniger wichtigem Inhalt gehen natürlich auch kaputt, dabei entsteht dann in der Regel kein Schaden, unbequem ist das dennoch (und natürlich teuer). So gehören zum Beispiel meine beiden MediaCenter Rechner (Wohnzimmer und Schlafzimmer) in die Kategorie jeder, die kein RAID spendiert bekommen haben und bei denen es sich ebenso nicht lohnt regelmäßig, Backups zu erstellen, da hier außer ein bisschen Konfigurationsdateien nichts Wichtiges liegt. Alles, was dort abgespielt wird, kommt ohnehin vom Netzlaufwerk. Trotzdem habe ich in letzter Zeit beobachtet, dass sich die S.M.A.R.T.-Werte der Systemfestplatte des Wohnzimmerrechners zusehends verschlechterten. Ein Ausfall könnte sich also (mehr oder weniger) bald ereignen. Dann natürlich – frei nach Murphy – kurz vor dem nächsten Filmabend, nur um mir dann von meiner Fraun anhören zu müssen, dass ja das ganze Haus voll mit Technik ist und nichts so funktioniert, wie es soll . Diese MediaCenter brauchen eigentlich nicht viel: auf der Systemfestplatte sind nur 5,2GB belegt und exorbitant viel Performance wird von dieser ebenfalls nicht abverlangt, lediglich beim Booten und Starten des XBMC wird diese ein wenig gefordert. Das brachte mich auf die Idee, einfach auf dem Storage ein kleines ZVOL für jeden Rechner zu erstellen und davon zu booten. 25GB sollten reichen: 512MB für /boot, 1GB als SWAP (wenn überhaupt nötig) und der Rest fürs System, mit ein bisschen Luft um in Zukunft xbmc für das pvr Projekt auch aus den Quellen kompilieren zu können.

Exportieren wollte ich das – im Gegensatz zu dem geteilten Daten (smb, nfs, ftp + upnp) – via iSCSI, da sich dies nach dem Einbinden wie eine ganz normale lokale Festplatte verhält. Dumm nur, dass ein handelsüblicher PC von Haus aus nicht von solchen Netzwerk-Blockdevices booten kann und iSCSI HBAs (Host Bus Adaptor) sündhaft teuer sind und ein wenig den finanziellen Rahmen sprengen würden.

Rechner netboot-fähig machen

Hier kommt die Software iPXE ins Spiel (vormals als gpxe und etherboot bekannt). Das ist eine Open-Source Software, die eine freie PXE Implementierung darstellt, die gegenüber der proprietären in Standard-Netzwerkkarten noch weitere Protokolle beherrscht: HTTP iSCSI DNS TFTP AoE FCoE etc.

iPXE kann von CD/USB-Stick gestartet, in das ROM einer Netzwerkkarte gebrannt, bzw. bei Onboard-NICs in das BIOS des Rechners integriert werden (etwas riskant) oder aber vom PXE-BIOS der Netzwerkkarte nachgeladen werden, was mir am Sinnvollsten erschien, da dies keine Manipulation an den Client-Rechnern erfordert und so mit nahezu allen Rechnern out-of-the-box funktioniert. Dazu verwendet das undionly.kpxe Image den Netzwerkcode der Netzwerkkarte weiter und startet nur die eigentliche Software in dessen Kontext. Um iPXE via PXE Boot nachzuladen, muss der autoritative DHCP-Server die Option next-server und filename zusätzlich zu den üblichen IP-Einstellungen übergeben. Beim pfsense gibt es diese Optionen unter Services -> DHCP Server im ausklappbaren Enable network booting Bereich.

Jetzt allerdings gibt es ein Problem, sobald iPXE gestartet ist, macht die Software erneut einen frischen DHCP Request, bei dem wiederum neben IP-Settings das iPXE Image ausgeliefert wird. Man ist also in einer Endlosschleife gefangen. Mit dem ISC dhcpd kann man das recht einfach umgehen:

if exists user-class and option user-class = "iPXE" {
     filename "";
     option root−path "iscsi:iscsi.example.com::::iqn.1992−01.com.example.iscsi:target";
 } else {
     filename "undionly.kpxe";
 }

Für den Microsoft DHCP Server gibt es auch eine Möglichkeit.

Hier gabs aber ein Problem mit dem pfsense, man kann zwar einen Root-String übergeben ob allein oder zusätzlich zum Filename, aber man kann weder die user-class abfragen noch mehr bei den statischen Host-Definitionen einstellen als den filename. Wenn man die generierte Config des pfsense bearbeitet, wird diese beim nächsten Restart und bei jeder Änderung wieder überschrieben. Es ist aber auch möglich, iPXE zu scripten und dort dynamische Variablen zu verwenden. Dieses muss in iPXE mit einkompiliert werden.

#!ipxe
dhcp
set username {username}
set password {password}
sanboot iscsi:iscsi.example.com::::iqn.1992−01.com.example.iscsi:${hostname}

Dieses einfache Skript wird nach dem checkout aus dem GIT Repository im Rootverzeichnis (ipxe/src/) abgelegt und via EMBED Parameter mit einkompiliert:

$ git clone git://git.ipxe.org/ipxe.git
$ cd ipxe/src
$ make bin/undionly.kpxe EMBED=mc.ipxe

Das erzeugte Image habe ich auf den TFTP Server gelegt und in der DHCP-Host Definitionen der MediaCenter Rechner angegeben. Die Variable ${hostname} wird dabei durch den via DHCP vergebenen Hostnamen ersetzt, sodass jeder Rechner sein eigenes Image booten kann. Hier eine Liste weiterer verwendbarer Variablen.

Linux Mint installieren

Ich habe Linux Mint 12 als Basis auserkoren, da es praktisch alle nötigen (auch proprietären) Videocodecs mitbringt, wartungsarm auf aktuellem Stand gehalten werden kann und XBMC als ppa verfügbar ist. Linux Mint basiert auf Ubuntu, dieses wiederum auf Debian, die hier beschriebenen Anpassungen sollten also 1:1 auf diese Systeme übertragbar sein.

Linux Mint kann ganz wie gewohnt von DVD oder USB-Stick gestartet werden, jetzt muss aber erst das iSCSI Laufwerk eingebunden werden, bevor der Installer gestartet wird, dazu ein Terminal öffnen:

$ sudo su -
$ aptitude install open−iscsi lsscsi
$ iscsiadm −m discovery −t st −p {SAN−IP}
$ iscsiadm −m node −p {SAN−IP} −T iqn.1992−01.com.example.iscsi:target −l

Der 3. Befehl listet alle vorhanden Targets, das Gewünscht muss im 4. Befehl eingetragen werden. Wenn das Target eine Authentifizierung benötigt, wird dies fehlschlagen. Es wird aber für jedes Target eine Config-Datei unter /var/lib/iscsi/send_targets/{san-ip}/default angelegt, in die die benötigten Authentifizierungsinformationen mit einem Texteditor eingetragen werden können:

node.session.auth.username = {username}
node.session.auth.password = {password}

Jetzt kann das login-Kommando (Nummer 4) erneut ausgeführt werden und sollte erfolgreich durchlaufen, was mit lsscsi oder dmesg überprüft werden kann:

$ lsscsi
[0:0:0:0] cd/dvd HL−DT−ST DVDRAM GSA−H42N RL00 /dev/sr0
[4:0:0:0] disk Generic Flash HS−CF 4.55 /dev/sda
[4:0:0:1] disk Generic Flash HS−MS/SD 4.55 /dev/sdb
[4:0:0:2] disk Generic Flash HS−SM 4.55 /dev/sdc
[5:0:0:0] disk FreeBSD iSCSI Disk 0123 /dev/sdd

Jetzt kann man ganz normal den Installer durchlaufen lassen. Auch die Installation von GRUB in den MBR der iscsi Targets stellt kein Problem dar, aber am Ende nicht den Computer neu starten, sondern das live-System weiter verwenden und in das gerade Installierte System rein chroot’en:

$ mkdir /mnt/sdd3
$ mount /dev/sdd3 /mnt/sdd3
$ mount /dev/sdd1 /mnt/sdd3/boot/
$ chroot /mnt/sdd3
$ mount −t proc none /proc

initramfs-Image anpassen

Wir müssen zum Glück nicht alle Informationen zum iscsi Target erneut (und statisch) in die initramdisk einimpfen, da iPXE die Informationen zum Target in die ibft – die “iSCSI Boot Firmware Table” – zur weiteren Verwendung schreibt. Allerdings kann die Ubuntu Standard-initrd diese nicht auswerten, daher müssen wir sie um 2 Skripte erweitern. Dazu erstellen wir die folgenden Dateien in den dazugehörigen Pfaden:

/etc/initramfs-tools/hooks/iscsihooks-iscsi

/etc/initramfs-tools/scripts/local-top/iscsilocal-top-iscsi

Nun muss sichergestellt werden, dass der Networkmanager unsere Netzverbindung nicht neu konfiguriert, in der Datei /etc/network/interfaces:

# The primary network interface
#auto eth0
iface eth0 inet manual

Als letzten Schritt die Dateirechte anpassen, iSCSI tools im Zielsystem installieren und initramfs aktualisieren:

$ chmod +x /etc/initramfs−tools/hooks/iscsi
$ chmod +x /etc/initramfs−tools/scripts/local−top/iscsi
$ aptitude install open−iscsi open−iscsi−utils
$ update−initramfs −u

Jetzt sind wir fertig, können den Rechner neu starten und das System sollte erfolgreich vom Netzwerk starten – ganz ohne jeden Massenspeicher. Nach dem Restart wird Linux Mint vermutlich erst einmal einen großen Batzen Updates installieren wollen, womöglich mit Kernel Updates, die eine Aktualisierung der initrd nötig machen. Das ist kein Problem, da die Anpassungen an den Skripten nun bei jeder Aktualisierung Anwendung finden. Das XBMC MediaCenter habe ich ganz normal als ppa – wie unter ubuntu – installiert.