Als ich meinen neuen FreeBSD-Server installieren sollte, wollte ich ihn nun komplett mit ZFS einrichten. Im Internet existieren genügend Anleitungen, die beschreiben, wie man dies bewerkstelligt. Doch sie gingen alle nicht den allerletzten Schritt, um auch das Swap ins ZFS zu legen. Hier also die Anleitung, wie man ein echtes ZFS-only System einrichtet.
Zunächst einmal ein paar Daten. Ich habe 5 SATA-Festplatten im Rechner, die nach dem Booten von FreeBSD 8.1-RELEASE als ad4, ad6, ad8, ad10 und ad12 erkannt wurden. Die Installation ist nichts für schwache Nerven. Es gibt keine Menüs, alles wird von der Kommandozeile erledigt und Tippfehler werden mit einem kaputten System bestraft.
Ich habe den Rechner mit der Installations-DVD gestartet. Anstatt die übliche Installation zu starten, bin ich jedoch gleich in die Rettungskonsole (Fixit) gegangen. Hier habe ich nochmal mit dmesg
nachgeprüft, daß auch wirklich alle Platten korrekt erkannt wurden und mir die Gerätenamen notiert.
Als erstes habe ich die Festplatten mit GPT partitioniert.
gpart create -s gpt ad4
gpart create -s gpt ad6
gpart create -s gpt ad8
gpart create -s gpt ad10
gpart create -s gpt ad12
So vorbereitet habe ich dann die Partitionen auf den Festplatten angelegt. Zuerst die Bootpartition.
gpart add -b 34 -s 128 -t freebsd-boot ad4
gpart add -b 34 -s 128 -t freebsd-boot ad6
gpart add -b 34 -s 128 -t freebsd-boot ad8
gpart add -b 34 -s 128 -t freebsd-boot ad10
gpart add -b 34 -s 128 -t freebsd-boot ad12
Anders als in den oben erwähnten Anleitungen, habe ich keine separate Swap-Partition angelegt. Den verbliebenen Platz auf den Platten habe ich vollständig für das ZFS verwendet.
gpart add -t freebsd-zfs -l disk0 ad4
gpart add -t freebsd-zfs -l disk1 ad6
gpart add -t freebsd-zfs -l disk2 ad8
gpart add -t freebsd-zfs -l disk3 ad10
gpart add -t freebsd-zfs -l disk4 ad12
Natürlich gehört der Boot-Code auf alle Festplatten. Man weiß ja nie, welche Festplatte ausfällt, in dem Fall möchte ich natürlich auch von den verbliebenen Platten booten können.
gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 ad4
gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 ad6
gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 ad8
gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 ad10
gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 ad12
Um das ZFS anzulegen, habe ich die ZFS-Kernelmodule geladen.
kldload /mnt2/boot/kernel/opensolaris.ko
kldload /mnt2/boot/kernel/zfs.ko
Das Dateisystem habe ich dann mit diesen Befehlen angelegt. (Die ersten beiden Zeilen gehören zusammen und sind hier nur wegen der Breite umgebrochen)
zpool create zroot raidz2 /dev/gpt/disk0 /dev/gpt/disk1 /dev/gpt/disk2 \
/dev/gpt/disk3 /dev/gpt/disk4
zpool set bootfs=zroot zroot
An dieser Stelle mußte ich dann nochmal von den Anleitungen abweichen, um Swap einzurichten. Die Idee dazu stammt von hier.
zfs create -V 2G zroot/swap
zfs set org.freebsd:swap=on zroot/swap
zfs set checksum=off zroot/swap
Hier kehrte ich dann zu den vorhandenen Anleitungen zurück. Es ist nicht zwingend notwendig, all diese Dateisysteme anzulegen, aber wenn man schon ein Dateisystem wie ZFS hat, sollte man seine Stärken richtig ausspielen.
zfs set checksum=fletcher4 zroot
zfs create -o compression=on -o exec=on -o setuid=on zroot/tmp
chmod 1777 /zroot/tmp
zfs create zroot/usr
zfs create zroot/usr/home
cd /zroot ; ln -s /usr/home home
zfs create -o compression=lzjb -o setuid=off zroot/usr/ports
zfs create -o compression=off -o exec=off -o setuid=off zroot/usr/ports/distfiles
zfs create -o compression=off -o exec=off -o setuid=off zroot/usr/ports/packages
zfs create zroot/var
zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/var/crash
zfs create -o exec=off -o setuid=off zroot/var/db
zfs create -o compression=lzjb -o exec=on -o setuid=off zroot/var/db/pkg
zfs create -o exec=off -o setuid=off zroot/var/empty
zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/var/log
zfs create -o compression=gzip -o exec=off -o setuid=off zroot/var/mail
zfs create -o exec=off -o setuid=off zroot/var/run
zfs create -o compression=lzjb -o exec=on -o setuid=off zroot/var/tmp
chmod 1777 /zroot/var/tmp
Damit habe ich alle Dateisysteme angelegt und kann mit der eigentlichen Installation beginnen. Auch das muß von der Kommandozeile geschehen.
cd /dist/8.1-RELEASE
export DESTDIR=/zroot
for dir in base manpages ports ; do (cd $dir ; ./install.sh) ; done
cd src ; ./install.sh all
cd ../kernels ; ./install.sh generic
cd /zroot/boot ; cp -Rlp GENERIC/* /zroot/boot/kernel/
Nachdem alle Dateien installiert sind, kann /var/empty read-only geschaltet werden.
zfs set readonly=on zroot/var/empty
Nun konnte ich in das frisch installierte System chrooten, um noch wichtige Einstellungen am System vorzunehmen.
chroot /zroot
Damit alle ZFS-Dateisysteme beim booten gemountet werden.
echo 'zfs_enable="YES"' > /etc/rc.conf
Der Bootloader soll natürlich auch wissen, wovon er booten soll.
echo 'vfs.root.mountfrom="zfs:zroot"' > /boot/loader.conf
echo 'zfs_load="YES"' >> /boot/loader.conf
Folgende Zeile ist nur bei Systemen mit 1GB RAM oder weniger nötig.
echo 'vfs.zfs.prefetch_disable="1"' >> /boot/loader.conf
Sollte ich je auf die Idee kommen, mit make buildworld
mein System upzudaten, will ich auch wieder einen Bootloader mit ZFS-Support haben. Dies ist nicht notwendig, um das System zum laufen zubekommen. Es verhindert nur, daß ich mir zukünftig ins Knie schieße.
echo 'LOADER_ZFS_SUPPORT=YES' > /etc/src.conf
Damit das System nach dem Booten auch lauffähig und benutzbar ist, fehlen noch einige Einstellungen wie root-Passwort, Zeitzone und Mail-Aliase für Sendmail.
passwd root
tzsetup
cd /etc/mail ; make aliases
Das System wird am Ende komplett aus dem ZFS laufen und benötigt eigentlich keine /etc/fstab mehr. Allerdings geht FreeBSD beim Booten davon aus, daß diese Datei existiert. Es fährt zwar auch ohne hoch, spuckt jedoch beim Hochfahren unschöne Fehlermeldungen aus. Um dem vorzubeugen, habe ich eine leere /etc/fstab angelegt.
touch /etc/fstab
Dies war nur das allernötigste. Die restlichen Einstellungen wie Netzwerk, Dienste, Tastaturlayout kann ich nach dem ersten Booten mit sysinstall vornehmen. Ich war an dieser Stelle fertig und konnte die chroot-Umgebung verlassen.
exit
Damit das System beim Booten die Dateisysteme wiederfindet, braucht es den zpool.cache. Dieser wird erst beim Exportieren des ZFS erzeugt. Ich habe also kurz das Dateisystem exportiert und gleich wieder importiert, um die Cache-Datei zu erzeugen und dann ins System zu kopieren.
mkdir /boot/zfs
cd /boot/zfs
zpool export zroot && zpool import zroot
cp /boot/zfs/zpool.cache /zroot/boot/zfs/zpool.cache
Und zuletzt habe ich die Mountpunkte den einzelnen Dateisystemen zugewiesen.
export LD_LIBRARY_PATH=/mnt2/lib
zfs unmount -a
zfs set mountpoint=legacy zroot
zfs set mountpoint=/tmp zroot/tmp
zfs set mountpoint=/usr zroot/usr
zfs set mountpoint=/var zroot/var
Damit war die Installation abgeschlossen. Ich habe die Rettungskonsole verlassen. Der FreeBSD-Installer erschien wieder und ich wählte unten den Punkt zum Beenden des Installers. Der Rechner startete neu und startete danach das frisch installierte System vom ZFS.
Wie vorhin erwähnt mußte ich nach dem ersten Login noch das Netzwerk, SSH und Tastatur einrichten. Danach war das System voll betriebsbereit.
One response to “Ein echtes ZFS-only FreeBSD-System”
Hier noch ein paar Hinweise, wenn man alte Festplatten verwenden möchte.
Sollte beim Partitionieren der Festplatten eine Meldung wie “ad4 is busy” erscheinen, dann befindet sich wahrscheinlich noch eine alte MBR-Partitionstabelle auf der Platte. Es reicht aus, diese Partitionstabelle mit
dd if=/dev/zero of=/dev/ad4 bs=512 count=1
zu löschen.Eine GPT-Partitionstabelle kann man mit
gpart destroy ad4
löschen.