ZFS unter Ubuntu/Kubuntu 6.10 (»Edgy Eft«)

Sun Microsystems hat der OpenSource Community ein neues Power-Tool geschenkt: Das Zettabyte Filesystem, kurz ZFS genannt. Dieses Filesystem räumt mit der gängigen Zuordnung »eine Partition – ein Dateisystem« gründlich auf und abstrahiert die Filesystem-Ebene komplett von der darunterliegenden Speicherinfrastruktur. Wer mehr zu den Grundlagen von ZFS lesen möchte, kann dies hier tun.

Zunächst war ZFS lediglich für Suns Betriebssystem Solaris verfügbar. Inzwischen laufen Portierungsprojekte auf verschiedene BSD-Derivate, MacOS und Linux. Gerade die Linux-Variante ist wohl für viele Anwender interessant. Diese wird von Ricardo Correira implementiert und baut auf FUSE auf, da die Integration der unter Suns CDDL freigegebenen Sourcen in den unter der GPL stehenden Linux-Kernel aus lizenzrechtlichen Gründen problematisch ist.

In diesem Blogpost möchte ich kurz beschreiben, wie man ZFS unter einem aktuellen Kubuntu 6.10 (»Edgy Eft«) kompiliert und zum Laufen bringt.

The shoulders of Giants

Auch andere haben sich natürlich schon dieses Themas angenommen, darunter Machine Check Exception und Chris Samuel.

Source Code besorgen

Es gibt grundsätzlich zwei Möglichkeiten, sich den Source-Code zu besorgen: per Download oder über das Mercurial-Repository von
Ricardo Correia. Letztere Möglichkeit ist insbesondere für Anwender/Entwickler, die immer auf dem letzten Stand sein wollen – birgt aber auch die Gefahr, dass der Code nicht gar so rock stable ist wie eine releaste Version.

Die letzte releaste Version 0.4.0_alpha1 (Stand: 31.12.2006) kann unter

https://developer.berlios.de/project/showfiles.php?group_id=6836

bezogen werden.

Das von dort heruntergeladene Source-Code-Archiv wird dann per

$ tar xfj zfs-fuse-0.4.0_alpha1.tar.bz2

entpackt.

Die Abenteurer unter uns können sich Mercurial installieren (falls nicht ohnehin schon vorhanden) und sich dann den Source Code direkt aus Ricardos Repository ziehen. Die erste der beiden Codezeilen checkt die letzte releaste Version aus der Serie 0.4 aus, die zweite besorgt die cutting edge Version (Hinweis: use at your own risk):

$ hg clone http://www.wizy.org/mercurial/zfs-fuse/0.4.x
$ hg clone http://www.wizy.org/mercurial/zfs-fuse/trunk

Dependencies installieren

Damit sich ZFS unter Ubuntu/Kubuntu kompilieren und installieren lässt, müssen wir uns zunächst eine Build-Umgebung schaffen und die Dependencies (die Sourcen von FUSE) installieren:

$ sudo apt-get install build-essential scons
$ sudo apt-get install libfuse-dev

MAKE

Wir wechseln nun in das Verzeichnis mit den Sourcen. Der genaue Pfad hängt davon ab, welche der oben vorgestellten Möglichkeiten zur Beschaffung des Source Codes gewählt wurde:

$ cd zfs-fuse-0.4.0_alpha1/src # nach Download
$ cd 0.4.x/src # Mercurial-Checkout aktuelle Serie
$ cd trunk/src # für Wagemutige

Der Build der Sourcen wird über ein im Source-Paket enthaltenes Skript für scons gesteuert. Für uns bedeutet das, dass wir es nun sehr einfach haben:

$ scons

Installation

Die Installation ist ebenfalls extrem einfach gehalten und wird auch über scons gesteuert:

$ sudo scons install

Fertig! :-D

Arbeiten mit ZFS

Hier möchte ich nun keine komplette Übersicht über die Möglichkeiten von ZFS bieten – dazu gibt es (vielleicht) mal einen weiteren Artikel. Interessant wäre aber schon, ob das gerade übersetzte und installierte ZFS überhaupt funktioniert …

Damit wir mit ZFS unter Linux arbeiten können, müssen wir zunächst den ZFS-Daemon starten. Ein Skript dafür ist in den Sourcen im Verzeichnis src/zfs-fuse enthalten:

$ cd src/zfs-fuse; ./run.sh

Wir benötigen nun noch mindestens ein, möglichst aber mehrere Block-Devices, um die Möglichkeiten von ZFS zu demonstrieren. In meinem Fall habe ich unter EVMS einfach zwei neue Devices /dev/evms/zfs0 und /dev/evms/zfs1 auf verschiedenen Festplatten angelegt. Man kann aber auch Dateien als Pseudo-Blockdevices verwenden.

$ dd if=/dev/zero of=~/zfs0 bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 22.3667 seconds, 48.0 MB/s
$ dd if=/dev/zero of=~/zfs1 bs=1M count=512
512+0 records in
512+0 records out
536870912 bytes (537 MB) copied, 1.42299 seconds, 377 MB/s
$ dd if=/dev/zero of=~/zfs2 bs=1M count=1536
1536+0 records in
1536+0 records out
1610612736 bytes (1.6 GB) copied, 21.063 seconds, 76.5 MB/s

Dies legt null-gefüllte Dateien zfs{0|1|2} mit einer Größe von 1G, 0.5G und 1.5G im Heimatverzeichnis des aktuellen Benutzers an.

Der ZFS Pool kann dann mit

$ sudo zpool create test ~/zfs0

angelegt werden. Wir können nun mit ZFS-Tools ein paar Informationen über den soeben angelegten ZPool sammeln:

$ sudo zpool list
NAME                    SIZE    USED   AVAIL    CAP  HEALTH     ALTROOT
test                   1016M     88K   1016M     0%  ONLINE     -
$ sudo zpool status test
  pool: test
 state: ONLINE
 scrub: none requested
config:
 
        NAME                  STATE     READ WRITE CKSUM
        test                  ONLINE       0     0     0
          /home/mneisen/zfs0  ONLINE       0     0     0
 
errors: No known data errors

Super: Noch keine Fehler … :-D

Zeit für das erste Dateisystem; Dateisysteme in ZFS sind hierarchisch, d.h., Dateisysteme können ihrerseits wiederum Dateisysteme enthalten. Properties (wie etwa Quotas, Kompression, Reservierung, ...) werden dabei von oben nach unten vererbt.

$ sudo zfs create test/users
$ sudo zfs list
NAME         USED  AVAIL  REFER  MOUNTPOINT
test         114K   984M  25.5K  /test
test/users  24.5K   984M  24.5K  /test/users

Dann wollen mit mal ein paar Dateisysteme für unsere beiden Benutzer Alice und Bob anlegen:

$ sudo zfs create test/users/alice
$ sudo zfs create test/users/bob
$ sudo zfs list
NAME               USED  AVAIL  REFER  MOUNTPOINT
test               178K   984M  25.5K  /test
test/users        76.5K   984M  27.5K  /test/users
test/users/alice  24.5K   984M  24.5K  /test/users/alice
test/users/bob    24.5K   984M  24.5K  /test/users/bob

Alice und Bob sollen jeweils maximal 1G Speicher verbrauchen können.

$ sudo zfs set quota=1G test/users/alice
$ sudo zfs set quota=1G test/users/bob

Zusammen sollen Alice und Bob maximal 1.5G Platz in unserem ZPool belegen.

$ sudo zfs set quota=1536M test/users

Für Bob sollen allerdings mindestens 640M reserviert werden.

$ sudo zfs set reservation=640M test/users/bob
$ sudo zfs list
NAME               USED  AVAIL  REFER  MOUNTPOINT
test               640M   344M  25.5K  /test
test/users         640M   344M  27.5K  /test/users
test/users/alice  24.5K   344M  24.5K  /test/users/alice
test/users/bob    24.5K   984M  24.5K  /test/users/bob

Oops, was ist denn jetzt passiert? Alice kann nur noch 344M belegen? Ja. Das sind die Auswirkungen der Reservierung von 640M Platz für Bob. Damit dieser garantiert 640M belegen kann, müssen andere Nutzer in ihrem Platzbedarf eingeschränkt werden. Das ist ein wirklich schönes Feature von ZFS, dass es so zwar auch in anderen Dateisystemen oder Add-On-Produkten gibt. Hier ist aber Kernbestandteil des Dateisystems und kann auch auf ganze Teilbäume im hierarchischen Baum der Dateisysteme in ZFS angewendet werden. Mit

$ sudo zfs set reservation=1.5G test/users
cannot set property for 'test/users': size is greater than available space

kann z.B. festgelegt werden, dass für die Benutzer mindestes 1.5G Platz zur Verfügung steht – wäre da nicht die ominöse Fehlermeldung, die uns darauf aufmerksam macht, dass für eine solche Reservierung nicht mehr genügend Speicherplatz in unserem Pool zur Verfügung steht. Da wir aber noch zwei weitere Devices (zfs1 und zfs2, unsere Pseudo-Blockdevices in normalen Files) zur Verfügung haben, können wir diese zu unserem ZPool hinzufügen und damit Platz schaffen:

$ sudo zpool add test ~/zfs1
$ sudo zpool add test ~/zfs2
$ sudo zpool list
NAME                    SIZE    USED   AVAIL    CAP  HEALTH     ALTROOT
test                   2.98G    194K   2.98G     0%  ONLINE     -

Nun können wir auch die Reservierung von 1.5G Platz für die Gesamtheit aller Dateisysteme unter test/users durchsetzen:

$ sudo zfs set reservation=1.5G test/users
$ sudo zfs list
NAME               USED  AVAIL  REFER  MOUNTPOINT
test              1.50G  1.43G  25.5K  /test
test/users         640M   896M  27.5K  /test/users
test/users/alice  24.5K   896M  24.5K  /test/users/alice
test/users/bob    24.5K  1024M  24.5K  /test/users/bob
 

Voìla! Wie man sieht, hat Bob nun maximal 1G zur Verfügung. Da er 640M fest zugesichert bekommt und für die Dateisysteme unter test/users maximal 1.5G eingeplant sind, bleiben für Alice 896M übrig. Sie wird Ihre maximal zugewiesenen 1G also nicht nutzen können – außer wir verändern die Obergrenze auf test/users. In unserem ZPool test haben wir insgesamt rund 3G Platz – 1.5G davon sind inzwischen aber verbraucht, da wir den Nutzern soviel Speicherplatz fest zugesagt haben.

Damit Alice, die keine 1G Platz beanspruchen kann, aber dennoch viel in ihrem Verzeichnis unterbringt, schalten wir (nur für ihren Verzeichnisbaum) Kompression an:

 
$ zfs set compression=on test/users/alice

Dies komprimiert alle neu hinzukommenden Daten in Alice’ Verzeichnis, vollkommen transparent für den Anwender. Wir testen die Auswirkungen:

$ cd ~; wget http://www2.kernel.org/pub/linux/kernel/v2.6/linux-2.6.19.1.tar.bz2
$ tar xj ~/linux-2.6.19.1.tar.bz2
$ du -sh linux-2.6.19.1
269M    linux-2.6.19.1
$ sudo rsync -aS ~/linux-2.6.19.1 /test/users/alice
[...]
sent 230975825 bytes  received 468146 bytes  1624168.22 bytes/sec
total size is 229629549  speedup is 0.99
$ sudo zfs list
NAME               USED  AVAIL  REFER  MOUNTPOINT
test              1.50G  1.43G  25.5K  /test
test/users         775M   761M  27.5K  /test/users
test/users/alice   135M   761M   135M  /test/users/alice
test/users/bob    24.5K  1024M  24.5K  /test/users/bob
 

Obwohl die Sourcen des Linux Kernel 2.6.19.1 etwa 269M umfassen, belegen sie in Alice’ komprimiertem Verzeichnis lediglich 135M. Wenn Alice also hauptsächlich mit gut komprimierbaren Daten arbeitet (Source Code, LaTeX-Dokumente, XML-Dateien, ...), dann wird sie aller Voraussicht nach sogar mehr als 1G Daten in ihrem Verzeichnis unterbringen können.

Fazit

Die ZFS-Portierung von Solaris nach Linux&FUSE ist zwar noch nicht ganz abgeschlossen, es wird auch auf die noch fehlende Optimierung und potentielle Bugs hingewiesen. In meinen Tests bin ich allerdings noch auf keinen solchen Fehler gestoßen, die Performance ist (wenn tatsächlich Disks und keine Dateien auf einem anderen Dateisystem) schon recht ordentlich. Für Systemadministratoren ist ZFS das Ende vieler Konfigurations-Alpträume und sollte Alternativen wie LVM und EVMS starke Konkurrenz machen.

Selbst professionelle, kommerzielle Lösungen können typischerweise auch nicht mehr als ZFS (z.B. Snapshots, Clones, ...). Wenn ich wetten müsste, welcher Volume Manager in 5 Jahren den Markt aufgerollt hat, würde ich auf ZFS tippen.

Für die kommende Zeit plane ich ein paar Performance-Messungen, über die ich dann hier berichten werde. Eventuell schreibe ich auch noch ein kleines Tutorial – mal sehen, wieviel Zeit ich haben werde … :-D

Ähnliche Artikel in diesem Blog:

Tags: , , , , ,

14 Reaktionen zu “ZFS unter Ubuntu/Kubuntu 6.10 (»Edgy Eft«)”

  1. pbergmann

    Interessanter Artikel! Vielleicht werde ich ZFS auf meinem System auch einmal testen. Ich würde mich über weitere Details zur Performance freuen – schließlich ist das ein Aspekt, der für ein FS ziemlich wichtig ist.

  2. Martin Eisenhardt

    Ich bin gerade dabei, ZFS/FUSE auf einer etwas größeren Maschine unter Gentoo zu installieren und werde da dann einige Performance-Messungen mit unterschiedlichen ZFS-ZPool-Konfigurationen und im Vergleich zu LVM2 mit XFS machen. Stay tuned … oder so … :-D

  3. Dogmatica

    For those who want to try this howto:

    dd if=/dev/zero of=~/zfs0 of=1M count=1024

    should be:

    dd if=/dev/zero of=~/zfs0 bs=1M count=1024

  4. Martin Eisenhardt

    Thanks for your correction, Dogmatica. You are completely right, the original version of that line in my post is complete non-sense. I have corrected the posting by now, though.

  5. brainwashed

    Sehr interessanter Artikel! Werde mir ZFS bei Zeiten mal genauer ansehen.

  6. Xaseron

    $ sudo apt-get install build-essentials scons
    es muss doch so heißen:
    $ sudo apt-get install build-essential scons

  7. Martin Eisenhardt

    Hi Xaseron,

    Du hast natürlich völlig recht. Die Stelle im Post korrigiere ich dann mal … :-D Vielen Dank für den Hinweis!

  8. C.

    s/Zettabyte/Zetabyte/ – please ;)

  9. Martin Eisenhardt

    Hi C.,

    I do not think that your hint for substitution is correct. When searching for »zettabyte« on Google, I get 171,000 hits, compared to only 17,000 for »zetabyte«. When searching for »zetabyte«, Google asks: »Did you mean: zettabyte?«

    Even Wikipedia seems to think that »zettabyte« is the correct spelling.

    Moreover, ZFS is attributed as »Zettabyte File System« nearly everywhere – even on Sun Microsystem’s own web site, f.e. in the data sheet for ZFS.

    No offense meant: I guess I just leave it as it is … :-D

    (P.S.: Since you seem to come from a network assigned to Sun Microsystems: Is there any inside information about this thing – did you rename ZFS?)

  10. paulistano

    Hi! Danke für die Zusammenfassung! War sehr hilfreich für ein paar Experimente mit ZFS (0.4.0 beta1) unter Kubuntu 7.10. Ein Problem hab ich jedoch mit ZFS-Fuse.

    Der ZFS-Daemon friert die Konsole ein.

    Soweit kein Problem, da ich das Konsolen-Fenster schließen kann und der Daemon läuft weiter. Wollte dann ZFS-Fuse per init-script beim booten starten lassen mit dem Ergebnis, daß der Bootvorgang beim script ebenfalls einfriert. Irgendeine Vermutung woran das liegen könnte? Grüße, paulistano!

  11. Martin Eisenhardt

    Hallo paulistano: Nein, dafür weiß ich leider keine Lösung, inzwischen ist das bei mir schon mal passiert. Ärgerlich, ...

  12. Francis Hemingway

    Hi,
    First of all, thanks for the blog post – I’m finding it really useful in my efforts to get zfs-fuse working on Ubuntu 7.10 (alternate install). Second, sorry for not writing in German, but I thought I’d post anyway in case my comment is of use to anyone. I got an error saying I was missing zlib.h when trying to compile zfs-fuse (i.e. I ran scons). I fixed it by installing two packages
    sudo apt-get install zlib1g-dev libssl-dev
    hope this helps someone!

  13. Francis Hemingway

    Actually, on second thoughts, maybe only zlib1g-dev is needed…

  14. Florian Schmölz

    Um die aktuenne beta1 mit gcc 4.2 zu kompilieren braucht man noch einen patch, den man sich von gentoo holen kann:

    http://bugs.gentoo.org/show_bug.cgi?id=213440

Einen Kommentar schreiben

Dieses Blog verwendet Textile für Textauszeichnungen. HTML wird nicht unterstützt.