ZFS auf root mit FreeBSD 9.1

-Nuke-

Well-Known Member
Heyho.

Ich habe mich mal damit beschäftigt FreeBSD 9.1 so zu installieren, das man ein ZFS-Only System hat. Gründe warum jetzt ZFS und nicht UFS etc. pp. seien jetzt mal nicht von belangen.

Da es recht viele Anleitungen gibt, wo eine älter als die andere ist, habe ich mal ein paar ausprobiert und bin an einem funktionierenden Stand angelangt, der mit FreeBSD 9.1 funktioniert... zumindest in VirtualBox.

Das will ich 1.) nicht für mich behalten und 2.) vllt. noch weitere Kommentare dazu hören ob es hier und da vllt. noch Probleme geben kann oder weitere Vorschläge.

Ich habe in VirtualBox also 2 virtuelle Laufwerke angelegt und von der Installations-CD gestartet (musste da noch die Controller auf die ICH6/9-Varianten umstellen und die CD an einen virtuellen SATA-Controller hängen, sonst klappte das nicht).

Dann beim Menü die Live-CD ausgewählt und mich als root eingeloggt.

Dann habe ich mit "sh" folgendes Skript ausgeführt:

editiert mit den Änderungen von unten:

Swap im ZFS:
Code:
#boot from install cd and choose "Live CD"
#add devices and install bootloader
gpart create -s gpt ada0
gpart create -s gpt ada1
gpart add -a 4k -s 128k -t freebsd-boot ada0
gpart add -a 4k -s 128k -t freebsd-boot ada1
gpart add -a 4k -t freebsd-zfs -l disk0 ada0
gpart add -a 4k -t freebsd-zfs -l disk1 ada1
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1

#create pool
gnop create -S 4096 /dev/gpt/disk0
gnop create -S 4096 /dev/gpt/disk1
zpool create -o altroot=/mnt -o cachefile=/var/tmp/zpool.cache zroot mirror /dev/gpt/disk0.nop /dev/gpt/disk1.nop
zpool export zroot
gnop destroy /dev/gpt/disk0.nop
gnop destroy /dev/gpt/disk1.nop
zpool import -o altroot=/mnt -o cachefile=/var/tmp/zpool.cache zroot

#setup pool
zpool set bootfs=zroot zroot
zfs set checksum=fletcher4 zroot

zfs create zroot/usr
zfs create zroot/usr/home
zfs create zroot/var
zfs create -o compression=on -o exec=on -o setuid=off zroot/tmp
zfs create -o compression=gzip -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 -o compression=gzip -o exec=off -o setuid=off zroot/usr/src
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

#create swap
zfs create -V 4G zroot/swap
zfs set org.freebsd:swap=on zroot/swap
zfs set checksum=off zroot/swap

#fix permissions
chmod 1777 /mnt/tmp
cd /mnt ; ln -s usr/home home
chmod 1777 /mnt/var/tmp

#install FreeBSD
cd /usr/freebsd-dist
export DESTDIR=/mnt
for file in base.txz kernel.txz doc.txz src.txz; #ports.txz lib32.txz
do (cat $file | tar --unlink -xpJf - -C ${DESTDIR:-/}); done

#final configuration
cp /var/tmp/zpool.cache /mnt/boot/zfs/zpool.cache
echo 'zfs_enable="YES"' >> /mnt/etc/rc.conf
echo 'zfs_load="YES"' >> /mnt/boot/loader.conf
echo 'vfs.root.mountfrom="zfs:zroot"' >> /mnt/boot/loader.conf
echo 'LOADER_ZFS_SUPPORT=YES' > /mnt/etc/src.conf
touch /mnt/etc/fstab

zfs set readonly=on zroot/var/empty

#reboot into the new system
#passwd root
#tzsetup
#cd /etc/mail ; make aliases
#echo WITH_PKGNG=yes >> /etc/make.conf
#echo 'WRKDIRPREFIX=/usr/obj' >> /mnt/etc/make.conf
#...edit rc.conf

Swap mit gmirror
Code:
#boot from install cd and choose "Live CD"
#add devices and install bootloader
gpart create -s gpt ada0
gpart create -s gpt ada1
gpart add -a 4k -s 512k -t freebsd-boot ada0
gpart add -a 4k -s 512k -t freebsd-boot ada1

##gmirror-swap##
gpart add -a 4k -s 4G -t freebsd-swap -l swap0 ada0
gpart add -a 4k -s 4G -t freebsd-swap -l swap1 ada1
##gmirror-swap##

gpart add -a 4k -t freebsd-zfs -l disk0 ada0
gpart add -a 4k -t freebsd-zfs -l disk1 ada1
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1

#create pool
gnop create -S 4096 /dev/gpt/disk0
gnop create -S 4096 /dev/gpt/disk1
zpool create -o altroot=/mnt -o cachefile=/var/tmp/zpool.cache zroot mirror /dev/gpt/disk0.nop /dev/gpt/disk1.nop
zpool export zroot
gnop destroy /dev/gpt/disk0.nop
gnop destroy /dev/gpt/disk1.nop
zpool import -o altroot=/mnt -o cachefile=/var/tmp/zpool.cache zroot

#setup pool
zpool set bootfs=zroot zroot
zfs set checksum=fletcher4 zroot

zfs create zroot/usr
zfs create zroot/usr/home
zfs create zroot/var
zfs create -o compression=on -o exec=on -o setuid=off zroot/tmp
zfs create -o compression=gzip-9 -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 -o compression=gzip-9 -o exec=off -o setuid=off zroot/usr/src
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

#create swap
#zfs create -V 4G zroot/swap
#zfs set org.freebsd:swap=on zroot/swap
#zfs set checksum=off zroot/swap

##gmirror-swap##
gmirror label -b prefer swap gpt/swap0 gpt/swap1
##gmirror-swap##

#fix permissions
chmod 1777 /mnt/tmp
cd /mnt ; ln -s usr/home home
chmod 1777 /mnt/var/tmp

#install FreeBSD
cd /usr/freebsd-dist
export DESTDIR=/mnt
for file in base.txz kernel.txz doc.txz src.txz; #ports.txz lib32.txz
do (cat $file | tar --unlink -xpJf - -C ${DESTDIR:-/}); done

#final configuration
cp /var/tmp/zpool.cache /mnt/boot/zfs/zpool.cache
echo 'zfs_enable="YES"' >> /mnt/etc/rc.conf
echo 'zfs_load="YES"' >> /mnt/boot/loader.conf
echo 'vfs.root.mountfrom="zfs:zroot"' >> /mnt/boot/loader.conf
echo 'LOADER_ZFS_SUPPORT=YES' > /mnt/etc/src.conf
echo 'WRKDIRPREFIX=/usr/obj' >> /mnt/etc/make.conf
touch /mnt/etc/fstab

##gmirror-swap##
echo '/dev/mirror/swap none swap sw 0 0' >> /mnt/etc/fstab
echo 'geom_mirror_load="YES"' >> /mnt/boot/loader.conf
##gmirror-swap##

zfs set readonly=on zroot/var/empty

#reboot into the new system
#passwd root
#tzsetup
#cd /etc/mail ; make aliases
#echo 'WITH_PKGNG=yes' >> /etc/make.conf
#...edit rc.conf
#in login.conf eintragen:
##:charset=UTF-8:\
##:lang=de_DE.UTF-8:\
#cap_mkdb /etc/login.conf
Nach einem reboot funktionierte hier alles bestens. Das will ich dann beim finalen Release von 9.1 dann auch auf meinem Server machen, den ich neu aufsetzen möchte. Natürlich würde ich da die Device-Namen anpassen, wenn nötig...

Bedenken oder Anregungen, dazu?
 
Zuletzt bearbeitet:
Ich würde beadm einsetzen. Eine passende Installationsanleitung dazu gibt es hier. Hauptunterschied zu Deiner Variante ist das Root-Volume.
 
/usr/src und /usr/ports kann man auch gern mit "gzip" komprimieren. Das bringt etwas mehr Platzeinsparung, bei vernachlässigbaren Geschwindigkeitseinbußen. Allerdings sollte man sich dann mit "WRKDIRPREFIX=/usr/obj" in der /etc/make.conf das Arbeitsverzeichnis der Ports umbiegen. Zum Beispiel nach /usr/obj.
 
Das "Partition Alignment" bitte beachten und SWAP würde ich nicht ins ZFS packen. Lieber mit "gpart add -t freebsd-swap" eine extra Partition einrichten.

http://www.thomas-krenn.com/de/wiki/Partition_Alignment

Also sollte ich die Zeilen:

gpart add -b 34 -s 128 -t freebsd-boot ada*
gpart add -t freebsd-zfs -l disk* ada*

auf:

gpart add -s 128k -t freebsd-boot ada1
gpart add -t freebsd-zfs -l disk* -b 1M ada0*

ändern? Hab dazu mal mehr gegoogelt, deswegen der Vorschlag.

Und Swap außerhalb von ZFS will ich eigentlich vermeiden, da man dann ja wieder manuell sich darum kümmern muss, dass der in einem Mirror läuft. Weil wäre ja blöd, wenn bei Swap-Nutzung, plötzlich die Swap-Platte kaputt geht.
 
kamikaze schrieb:
Ist das ein Feature von zfs oder gibt es dafür eine allgemeine Lösung, so was wie ein tarfs?
Das ist ein ZFS-Feature: "zfs set compression=gzip ..." Normalerweise nutzt ZFS dort den "lzjb"-Algorithmus, der zwar sehr schnell ist, aber auch nur ca. 1:2 komprimiert. gzip als Synonym für Deflate ist etwas langsamer, kommt allerdings auf ca. 1:3. In höheren Leveln kann man auch noch 1:4 erreichen, aber das ist vom Performance-Standpunkt definitiv nicht mehr zu empfehlen.
 
OK, also:

gpart add -a 4k -s 128k -t freebsd-boot ada*
gpart add -a 4k -t freebsd-zfs -l disk* ada*

und dann beim erzeugen von ZFS, dann noch das mit dem gnob...
 
Und Swap außerhalb von ZFS will ich eigentlich vermeiden, da man dann ja wieder manuell sich darum kümmern muss, dass der in einem Mirror läuft. Weil wäre ja blöd, wenn bei Swap-Nutzung, plötzlich die Swap-Platte kaputt geht.

Hallo,

wenn du swap mit auf ZFS nutzt kackt dir die Kiste jedes mal ab wenn RAM knapp wird und der Kernel versucht zu swapen, das ist mir letztens passiert als ich swap auf ZFS genutzt habe. Jedes mal wenn ich rsync genutzt habe um ein Backup zu machen ist die Kiste mit einer Panic stehen geblieben, nun habe ich wieder komplett umgestellt auf gmirror anstatt ZFS fürs OS zu nehmen.

Gruß ré
 
kira12: Damit erzeugst du das Problem. UFS und ZFS haben ihre eignen Buffercaches die miteinander konkurieren. ZFS in FreeBSD >= 9.0 soll das Problem durch Backpressurealgortihmen gelöst haben.
 
Mal so OT:

Was spricht eigentlich dagegen das 4K layout jetzt default zu machen, außer dass bei 512b Platten ein paar lächerliche Bytes verschwendet werden?
 
kira12: Damit erzeugst du das Problem. UFS und ZFS haben ihre eignen Buffercaches die miteinander konkurieren. ZFS in FreeBSD >= 9.0 soll das Problem durch Backpressurealgortihmen gelöst haben.

Das war auch mein Informationsstand. Die Frage ist halt, mit welcher Version von FreeBSD das getestet wurde. Immer wenn ich lese "crash mit swap auf zvol" ist das immer schon ein paar Jahre alt und aktuellere Artikel sagen davon nichts mehr.

Habe auch mal einen Artikel gelesen mit ZFS auf Root und die Swap dann mit gmirror. Aber beißt sich hier nicht, dass beide Systeme Daten ans Ende der Festplatte schreiben? Oder wie ist das gelöst, wenn es denn gelöst ist?
 
Das ist eine gute Frage. Windows und die meisten Linuxe richten auf volle Megabyte aus und schlagen damit das Problem global tot. FreeBSD hat übrigens schon seit 9.0 eine auf den Herstellerbezeichnungen basierende Magie, um 4k-Platten zu erkennen. Leider integriert das nicht mit den Dateisystemen. Letztens flogen auf freebsd-fs@ Patches rum, die das zumindest für ZFS einbauen und den "gnop-Trick" damit überflüssig machen.
 
Das Problem bei UFS gemischt mit ZFS ist, wie Crest sagte, dass beide ihre eigenen Cache-Mechanismen haben und gegeneinander arbeiten. Allerdings ist das Problem seit dem Beginn der ZFS-Ära viel besser geworden. Spätestens seit 8.3 und 9.0 ist ZFS allerdings so rücksichtsvoll, dass es in der Praxis eigentlich keine negativen Auswirkungen mehr hat, beide Dateisysteme zu mischen. Allerdings stellt sich die Frage, weshalb man das eigentlich möchte. Wer ZFS hat, hat eigentlich keinen Grund noch mit UFS rumzuhampeln.

Bei der Swap liegt das Problem darin, dass ein Schreiben in den Zpool zu einem Schreiben in den ARC führt, was RAM kostet. Wenn man nun die Swap auf einem Zvol hat, will der Kernel sie nutzen, wenn ihm der RAM ausgeht. Aber durch das Nutzen wird noch mehr RAM verbraten, etc. Früher führte dies zwangsläufig zum Teufelskreis mit Crash am Ende, heute erkennt ZFS die Speicherknappheit und gibt einen Teil seines ARC frei. Allerdings klappt das nur bis zu einem bestimmten Punkt. Ich würde daher die Swap weiterhin in eine richtige Partition legen. Das tut nun wirklich niemandem weh.

In 9-STABLE, hat es leider nicht in 9.1 geschafft, unterstützt top auf Systemen mit ZFS übrigens die Anzeige der aktuellen ARC-Nutzung. Taucht als weitere Zeile im Kopf auf. Das ist sehr praktisch, wenn man mal schauen möchte, was ZFS eigentlich treibt.
 
-Nuke-: Du kannst selbstverständlich ZFS und gmirror auf unterschiedlichen Partitionen betreiben. Mit UFS würde man das ja genauso machen. Sobald man massiv swappen muss ist es eh vorbei mit dem Durchsatz.
 
Hi,

Ich bin gerade auf diesen Thread gestossen... Ich selber verwende ZFS auch - da ich (noch) mit Solaris 11 arbeite... Von daher eine gute Idee, eine funktionierende Installation hier anzubieten :-)

Das einzige echte "Manko" unter ZFS ist, dass per default alles geloggt wird (man denke an ZIL)... Das macht das ganze z.B. per NFS *EXTREM* langsam, besonders wenn es z.B. um das Löschen vieler kleiner Dateien geht... Da ist ein Performance Unterschied zwischen remote und local löschen locker Faktor 100 und mehr... Das Netzwerk ist hier nicht entscheidend - es läuft ja bei eiem rm Befehlt fast nix übers netz... Die Lösung ist dann entweder das ZIL auszuschalten (was nicht empfohlen wird) oder dafür entsprechende SSD Platten oder Karten einzubauen... Soviel dazu. Ansonsten ist ZFS schon sehr komfortabel...

Viele Grüße, Norbert
 
makenoob: Es macht keinen Sinn ZFS in auf einem gmirror Provider zu betreiben. Möchte man ZFS mit einem RAID1 betreiben so sollte man dies durch ein Mirror VDEV abbilden. Verwendet man stattdessen gmirror so verliert man die selbstheilenden Eigenschafen eines VDEVs.
 
makenoob: Es macht keinen Sinn ZFS in auf einem gmirror Provider zu betreiben. Möchte man ZFS mit einem RAID1 betreiben so sollte man dies durch ein Mirror VDEV abbilden. Verwendet man stattdessen gmirror so verliert man die selbstheilenden Eigenschafen eines VDEVs.

Ich habe auch nicht gesagt, dass es sinnvoll ist sondern nur, dass es geht ;)
 
makenoob: Es macht keinen Sinn ZFS in auf einem gmirror Provider zu betreiben. Möchte man ZFS mit einem RAID1 betreiben so sollte man dies durch ein Mirror VDEV abbilden. Verwendet man stattdessen gmirror so verliert man die selbstheilenden Eigenschafen eines VDEVs.
Wie meinst du das genau? Kannst du mir das erklären? Wie würdest du eine Config erstellen?
 
Ich habe übrigens mal ein (bei mir in VirtualBox funktionierendes) Skript im Eingangspost hinzugefügt, wo das Swap auf einer extra-Partition mit gmirror ist.
 
Zurück
Oben