Diskless Media Center mit XBMC

Diskless Media Center (XBMC) mit iSCSI und PXE

xbmc
XBMC ist eine Anwendung, die unter anderem auf Linux läuft und sämtliche Medienformate über sämtliche Netzwerkprotokolle abspielen kann. Da es ein reiner Player sein soll und sämtliche Daten auf dem Fileserver liegen, braucht die Kiste auch keine Festplatte. Hier erkläre ich kurz die Schritte, die ich benötigt und zusammengesucht habe, um die XBMC-Installation über iSCSI auf den Fileserver zu legen und über das Netzwerk zu booten.

Ausgangslage

  • Fileserver
    • OS: Ubuntu 10.04.3 LTS
    • Name: marvin.home
    • Stellt bereit: TFTP, iSCSI
  • XBMC-PC
    • OS: XBMC Live 10.1 (basiert auf Ubuntu 10.04.2 LTS)
    • Name: htpc.home
  • Fritzbox
    • FW: Freetz
    • Stellt bereit: DHCP

iSCSI Target einrichten

iSCSI hat gewöhnungsbedürftige Name: der iSCSI-Initiator ist der Client und das iSCSI-Target der Server.
Zunächst habe ich das iSCSI-Target eingerichtet:

Danach muss es noch aktiviert werden, indem man in der Datei /etc/default/iscsitarget den Wert ISCSITARGET_ENABLE auf true ändert:

Danach muss ein Volume erzeugt werden, das als Festplatte über iSCSI freigegeben wird. Das kann eine Platte, eine Partition, ein Logical Volume oder einfach nur eine Datei sein. Ich habe mich für letzteres entschieden und ein Sparse File angelegt (Speicherplatz wird erst bei Bedarf belegt, nicht beim Erstellen).

Da es ein Sparse File ist, habe ich ihm ganze 10GB gegönnt – XBMC kann Cover herunterladen und benötigt dafür etwas Platz. Mindestanforderung für XBMC-Live ist 2GB.
Die Datei wird jetzt als iSCSI-LUN freigegeben:

Der Target-Name setzt sich nach RFC wie folgt zusammen: iqn.<yyyy-mm>.<reversed domain name>:<disk name>
Man kann das ganze auch noch mit User und Passwort absichern, das habe ich mir hier im Heimnetz aber gespart.
Jetzt beschränken wir den Zugriff noch auf die IP des XBMC-Rechners:

Nicht vergessen, dass der ALL ALL Eintrag auskommentiert werden muss.

Das wars dann auch schon – jetzt können wir den iSCSI-Daemon starten:

Quelle: http://www.howtoforge.com/using-iscsi-on-ubuntu-10.04-initiator-and-target

XBMC Installieren

Die XBMC-Installation hätte man auch direkt per Netzwerk mit PXE starten können. Da ich aber grad einen USB-Stick vor mir liegen hatte, war das dann doch die einfachere Variante.
Man lädt sich das XBMC-Live ISO von http://xbmc.org/download/ und lässt dieses mit unetbootin auf den USB-Stick schreiben. Unetbootin gibt es sowohl für Windows, als auch für Linux.

Danach startet man den XBMC-PC von dem USB-Stick und sollte in der Ubuntu-Installation landen. Hier „klickt“ man sich wie gewohnt durch, bis zu dem Punkt mit den Festplatten – dort sollte so etwas wie „iSCSI Targets konfigurieren“ stehen. Mit dem Menüpunkt verbindet man sich zur oben eingerichteten iSCSI-Disk. Diese taucht dann in der Liste auf und kann für die Partitionierung ausgewählt werden. Danach läuft die Installation weiter wie bisher. Beim reboot wird das Ubuntu nicht starten können, d.h. man kann den XBMC-PC erstmal wieder ausschalten.

XBMC für iSCSI-Boot anpassen

Jetzt haben wir zwar das frische XBMC-Ubuntu per iSCSI in unser Image installiert, es ist aber nicht in der Lage per iSCSI zu booten (ich finde das ist eine Lücke in der Installationsroutine – das muss dort eigentlich mit erledigt werden, sonst macht der iSCSI-Punkt keinen Sinn ..).
Hier profitieren wir direkt von dem Vorteil, dass die komplette Disk auf einem laufenden Linux-System liegt. Von daher führen wir die folgenden Befehle alle auf dem Server aus. Hier können wir die Partition mounten, die initrd anpassen und den iSCSI-Initiator installieren.
Zunächst installieren wir uns kpartx – ein Tool um ein Devicemapping aus Partitionstabellen zu erstellen.

Jetzt machen wir aus dem Disk-Image ein Device:

Und lesen die Partitionstabelle ein:

Jetzt hat der Devicemapper Einträge zu den Partitionen und wir können das root-Filesystem mounten:

Dann wechseln wir in unser neu aufgesetztes XBMC-Ubuntu:

Nun müssen folgende zwei Dateien erstellt werden:

Eigentlich müssten wir jetzt eine neue initrd erzeugen – das macht die Installationsroutine vom iSCSI-Initiator aber auch nochmal, deswegen können wir uns das hier sparen. Den Initiator installieren wir mit:

Hier tauchen Fehler auf, dass einige Sachen unter /proc nicht gefunden werden können, etc – die können ignoriert werden.
Nun verlassen wir die chroot-Umgebung wieder.

Da wir den Kernel und die Initrd noch für den PXEBoot benötigen, lassen wir den mount noch bestehen.

Quelle: http://apfelboymchen.homeunix.net/gnu/notes/booting%20ubuntu%20iscsi.html

PXE und TFTP-Server einrichten

Der Bootvorgang läuft so ab, dass die Netzwerkkarte vom DHCP-Server die IP zu einem TFTP-Server und einen Dateinamen mitgeteilt bekommt. Diese Datei wird per TFTP geladen und ausgeführt. Wir benutzen hier die Datei pxelinux.0 aus dem Syslinux-Paket. Dazu installieren wir zunächst syslinux und den TFTPD auf unserem Server:

Per default greift der TFTP-Server auf das Verzeichnis /var/lib/tftpboot zu. Hier legen wir pxelinux.0, den Kernel und die Initrd ab. Das pxelinux lädt dann beim Booten per TFTP den Kernel und die Initrd und führt diese aus.

Die beiden Symlinks sind ganz hilfreich, wenn man später auf andere Versionen schwenken will. Außerdem muss man dann beim Tippen der Konfigurationsdatei nicht den kompletten Namen wissen 😀
Der Ordner pxelinux.cfg ist für die Konfigurationsdateien, die pxelinux.0 benutzt. Hier kann z.B. eine Datei mit dem Namen default angelegt werden, die immer verwendet wird, wenn keine spezielle Konfiguration vorhanden ist. Da aber nur der eine spezielle XBMC-PC mit dem Kernel starten soll, legen wir eine spezielle Konfiguration an – diese wird anhand der MAC-Adresse identifiziert:

Das war schon der ganze Zauber mit PXE und TFTP – jetzt können wir das Image wieder aushängen.

DHCP einrichten

Das Problem an der Fritzbox ist, dass man keine DHCP-Optionen setzen kann. Deswegen habe ich schon direkt nach Kauf die alternative Firmware freetz aufgespielt.
Man ruft dann das Freetz-Webinterface (Port 81) auf und geht zu Dnsmasq→Einstellungen. Dort trägt man unter DHCP-Boot folgendes ein:

Wenn man einen eigenen Dnsmasq laufen hat, reicht folgende Zeile in der Konfiguration:

Beim DHCPD sind das folgende Konfigurationseinträge:

Das war’s – jetzt sollte der XBMC-PC über Netzwerk booten.

Alternative: gPXE/etherboot

Bei diesem Projekt bin ich auf gPXE/etherboot gestoßen. gPXE ist ein erweiterter PXE-Loader, der direkt das Booten per iSCSI, HTTP, NFS, .. unterstützt. Damit hätte man sich das Bereitstellen des Kernels und der Initrd sparen können und wäre mit dem Betriebssystem noch unabhängiger gewesen (updates des Kernels usw.). Das Problem ist nur, dass gPXE erstmal irgendwie geladen werden muss – das geht durch Flashen der Netzwerkkarte/BIOS, chainload vom originalen PXE oder nachgelagert als „Kernel“ der von pxelinux geladen wird. Ersteres kam für mich nicht in Frage, da mir das zu aufwendig ist, außerdem setze ich PXE ganz gerne auch für andere Rechner und Zwecke ein und müsste dann alle Rechner flashen. Die anderen beiden Varianten sind da schon umgänglicher, die habe ich beide auch getestet, das Problem dabei ist aber, dass der gPXE den Pfad zu seiner Konfiguration vom DHCP-Server erwartet – das heißt wiederum, dass im DHCP-Server if-Abfragen dafür sorgen, dass beim ersten Request pxelinux.0 ausgeliefert wird und beim zweiten Request die gPXE-Konfiguration. Dann hätte ich den Dnsmasq ersetzen müssen, da er sowas (vermutlich) nicht kann.
Und dann noch der dritte Grund: Ich hatte erhofft, das Anpassen der initrd zu vermeiden mit dem direkten Booten per gPXE – da sich aber herausgestellt hat, dass Ubuntu die initrd bei der Installation nicht passend vorbereitet hat, musste sie eh angepasst werden.
Ich hoffe, dass gPXE den schmalen PXEloader auf Dauer ersetzen wird, dann eröffnen sich doch einige neue Spielereien, die man testen könnte 😉