30.3. NFS – Network File System

Reorganisiert und erweitert von Tom Rhodes. Geschrieben von Bill Swingle.

Eines der vielen von FreeBSD unterstützten Dateisysteme ist das Netzwerkdateisystem, das auch als NFS bekannt ist. NFS ermöglicht es einem System, Dateien und Verzeichnisse über ein Netzwerk mit anderen zu teilen. Über NFS können Benutzer und Programme auf Daten entfernter Systeme zugreifen, und zwar genauso, wie wenn es sich um lokale Daten handeln würde.

Einige der wichtigsten Vorteile von NFS sind:

30.3.1. Wie funktioniert NFS?

NFS besteht aus zwei Hauptteilen: Einem Server und einem oder mehreren Clients. Der Client greift über das Netzwerk auf die Daten zu, die auf dem Server gespeichert sind. Damit dies korrekt funktioniert, müssen einige Prozesse konfiguriert und gestartet werden:

Der Server benötigt folgende Daemonen:

Daemon Beschreibung
nfsd Der NFS-Daemon. Er bearbeitet Anfragen der NFS-Clients.
mountd Der NFS-Mount-Daemon. Er bearbeitet die Anfragen, die nfsd(8) an ihn weitergibt.
rpcbind Der Portmapper-Daemon. Durch ihn erkennen die NFS-Clients, welchen Port der NFS-Server verwendet.

Der Client kann ebenfalls einen Daemon aufrufen, und zwar den nfsiod-Daemon. Der nfsiod-Daemon bearbeitet Anfragen vom NFS-Server. Er ist optional und verbessert die Leistung des Netzwerks. Für eine normale und korrekte Arbeit ist er allerdings nicht erforderlich. Mehr erfahren Sie in der Hilfeseite nfsiod(8).

30.3.2. NFS einrichten

NFS lässt sich leicht einrichten. Die nötigen Prozesse werden durch einige Änderungen in /etc/rc.conf bei jedem Systemstart gestartet.

Stellen Sie sicher, dass auf dem NFS-Server folgende Optionen in der Datei /etc/rc.conf gesetzt sind:

rpcbind_enable="YES"
nfs_server_enable="YES"
mountd_flags="-r"

mountd läuft automatisch, wenn der NFS-Server aktiviert ist.

Auf dem Client muss in /etc/rc.conf folgende Option gesetzt sein:

nfs_client_enable="YES"

/etc/exports legt fest, welche Dateisysteme NFS exportieren (manchmal auch als “teilen” bezeichnet) soll. Jede Zeile in /etc/exports legt ein Dateisystem sowie die Arbeitsstationen, die darauf Zugriff haben, fest. Außerdem ist es möglich, Zugriffsoptionen festzulegen. Es gibt viele verschiedene Optionen, allerdings werden hier nur einige von ihnen erwähnt. Wenn Sie Informationen zu weiteren Optionen benötigen, lesen Sie exports(5).

Nun folgen einige Beispieleinträge für /etc/exports:

Die folgenden Beispiele geben Ihnen Anhaltspunkte zum Exportieren von Dateisystemen, obwohl diese Einstellungen natürlich von Ihrer Arbeitsumgebung und Ihrer Netzwerkkonfiguration abhängen. Das nächste Beispiel exportiert das Verzeichnis /cdrom für drei Rechner, die sich in derselben Domäne wie der Server befinden oder für die entsprechende Einträge in /etc/hosts existieren. Die Option -ro kennzeichnet das exportierte Dateisystem als schreibgeschützt. Durch dieses Flag ist das entfernte System nicht in der Lage, das exportierte Dateisystem zu verändern.

/cdrom -ro host1 host2 host3

Die nächste Zeile exportiert /home auf drei durch IP-Adressen bestimmte Rechner. Diese Einstellung ist nützlich, wenn Sie über ein privates Netzwerk ohne DNS-Server verfügen. Optional könnten interne Rechnernamen auch in /etc/hosts konfiguriert werden. Benötigen Sie hierzu weitere Informationen, lesen Sie bitte hosts(5). Durch das Flag -alldirs wird es möglich, auch Unterverzeichnisse als Mountpunkte festzulegen. Dies bedeutet aber nicht, dass alle Unterverzeichnisse eingehängt werden, vielmehr wird es dem Client ermöglicht, nur diejenigen Verzeichnisse einzuhängen, die auch benötigt werden.

/home  -alldirs  10.0.0.2 10.0.0.3 10.0.0.4

Die nächste Zeile exportiert /a, damit Clients von verschiedenen Domänen auf das Dateisystem zugreifen können. Das -maproot=root-Flag erlaubt es dem Benutzer root des entfernten Systems, als root auf das exportierte Dateisystem zu schreiben. Wenn dieses Flag nicht gesetzt ist, kann selbst root nicht auf das exportierte Dateisystem schreiben.

/a  -maproot=root  host.example.com box.example.org

Damit ein Client auf ein exportiertes Dateisystem zugreifen kann, muss ihm dies explizit gestattet werden. Stellen Sie also sicher, dass der Client in /etc/exports aufgeführt wird.

Jede Zeile in /etc/exports entspricht der Exportinformation für ein Dateisystem auf einen Rechner. Ein entfernter Rechner kann für jedes Dateisystem nur einmal festgelegt werden, und kann auch nur einen Standardeintrag haben. Nehmen wir an, dass /usr ein einziges Dateisystem ist. Dann wären folgende Zeilen ungültig:

#Nicht erlaubt, wenn /usr ein einziges Dateisystem ist
/usr/src   client
/usr/ports client

Das Dateisystem /usr wird hier zweimal auf den selben Rechner (client) exportiert. Dies ist aber nicht zulässig. Der korrekte Eintrag sieht daher so aus:

/usr/src /usr/ports  client

Die Eigenschaften eines auf einen anderen Rechner exportierten Dateisystems müssen alle in einer Zeile stehen. Zeilen, in denen kein Rechner festgelegt wird, werden als einzelner Rechner behandelt. Dies schränkt die Möglichkeiten zum Export von Dateisystemen ein, für die meisten Anwender ist dies aber kein Problem.

Eine gültige Exportliste, in der /usr und /exports lokale Dateisysteme sind, sieht so aus:

# Export src and ports to client01 and client02, but only
# client01 has root privileges on it
/usr/src /usr/ports -maproot=root    client01
/usr/src /usr/ports                  client02
# The client machines have root and can mount anywhere
# on /exports. Anyone in the world can mount /exports/obj read-only
/exports -alldirs -maproot=root      client01 client02
/exports/obj -ro

Der Daemon mountd muss die Datei /etc/exports nach jeder Änderung neu einlesen, damit die Änderungen wirksam werden. Dies kann durch das Senden des HUP-Signals an den mountd-Prozess erfolgen:

# kill -HUP `cat /var/run/mountd.pid`

Alternativ können Sie das mountd-rc(8)-Skript auch mit dem passenden Parameter aufrufen:

# /etc/rc.d/mountd onereload

Lesen Sie bitte Abschnitt 12.7 des Handbuchs für Informationen zum Einsatz der rc-Skripte.

Eine weitere Möglichkeit, diese Änderungen zu übernehmen, wäre der Neustart des Systems. Dies ist allerdings nicht nötig. Wenn Sie die folgenden Befehle als root ausführen, sollte alles korrekt gestartet werden.

Auf dem NFS-Server:

# rpcbind
# nfsd -u -t -n 4
# mountd -r

Auf dem NFS-Client:

# nfsiod -n 4

Nun sollte alles bereit sein, um ein entferntes Dateisystem einhängen zu können. In unseren Beispielen nennen wir den Server server, den Client client. Wenn Sie ein entferntes Dateisystem nur zeitweise einhängen wollen, oder nur Ihre Konfiguration testen möchten, führen Sie auf dem Client als root einen Befehl ähnlich dem folgenden aus:

# mount server:/home /mnt

Dadurch wird das Verzeichnis /home des Servers auf dem Client unter /mnt eingehängt. Wenn alles korrekt konfiguriert wurde, sehen Sie auf dem Client im Verzeichnis /mnt alle Dateien des Servers.

Wenn Sie ein entferntes Dateisystem nach jedem Systemstart automatisch einhängen wollen, fügen Sie das Dateisystem in /etc/fstab ein. Dazu ein Beispiel:

server:/home	/mnt	nfs	rw	0	0

Eine Beschreibung aller Optionen enthält die Hilfeseite fstab(5).

30.3.3. Dateien sperren (Locking)

Einige Anwendungen (beispielsweise mutt) erfordern die Sperrung von Dateien, damit sie korrekt arbeiten. Verwenden Sie NFS, so können Sie für die Sperrung von Dateien rpc.lockd einsetzen. Um diesen Daemon zu aktivieren, müssen Sie in /etc/rc.conf (sowohl auf Client- als auch auf Serverseite) folgende Zeilen aufnehmen (wobei vorausgesetzt wird, dasss NFS auf beiden Systemen bereits konfiguriert ist):

rpc_lockd_enable="YES"
rpc_statd_enable="YES"

Danach starten Sie die Anwendung zur Verwaltung der Dateisperren durch folgenden Befehl:

# /etc/rc.d/lockd start
# /etc/rc.d/statd start

Benötigen Sie keine echten Dateisperren zwischen den NFS-Clients und dem NFS-Server, können Sie den NFS-Client durch die Übergabe der Option -L an mount_nfs(8) zu einer lokalen Sperrung von Dateien zwingen. Lesen Sie dazu auch die Manualpage mount_nfs(8).

30.3.4. Praktische Anwendungen

NFS ist in vielen Situationen nützlich. Einige Anwendungsbereiche finden Sie in der folgenden Liste:

30.3.5. AMD

Beigetragen von Wylie Stilwell. Überarbeitet von Chern Lee.

amd(8) (Automatic Mounter Daemon) hängt ein entferntes Dateisystem automatisch ein, wenn auf eine Datei oder ein Verzeichnis in diesem Dateisystem zugegriffen wird. Dateisysteme, die über einen gewissen Zeitraum inaktiv sind, werden von amd automatisch abgehängt. amd ist eine einfache Alternative zum dauerhaften Einhängen von Dateisystemen in /etc/fstab.

In der Voreinstellung stellt amd die Verzeichnisse /host und /net als NFS-Server bereit. Wenn auf eine Datei in diesen Verzeichnissen zugegriffen wird, sucht amd den entsprechenden Mountpunkt und hängt das Dateisystem automatisch ein. /net wird zum Einhängen von exportierten Dateisystemen von einer IP-Adresse verwendet, während /host zum Einhängen von exportierten Dateisystemen eines durch seinen Namen festgelegten Rechners dient.

Ein Zugriff auf eine Datei in /host/foobar/usr würde amd veranlassen, das von foobar exportierte Dateisystem /usr einzuhängen.

Beispiel 30-2. Ein exportiertes Dateisystem mit amd in den Verzeichnisbaum einhängen

Sie können sich die verfügbaren Mountpunkte eines entfernten Rechners mit showmount ansehen. Wollen Sie sich die Mountpunkte des Rechners foobar ansehen, so verwenden Sie:

% showmount -e foobar
Exports list on foobar:
/usr                               10.10.10.0
/a                                 10.10.10.0
% cd /host/foobar/usr

Wie Sie an diesem Beispiel erkennen können, zeigt showmount /usr als exportiertes Dateisystem an. Wenn man in das Verzeichnis /host/foobar/usr wechselt, versucht amd den Rechnernamen foobar aufzulösen und den gewünschten Export in den Verzeichnisbaum einzuhängen.

amd kann durch das Einfügen der folgenden Zeile in /etc/rc.conf automatisch gestartet werden:

amd_enable="YES"

Mit der Option amd_flags kann amd angepasst werden. Die Voreinstellung für amd_flags sieht so aus:

amd_flags="-a /.amd_mnt -l syslog /host /etc/amd.map /net /etc/amd.map"

/etc/amd.map legt die Standardoptionen fest, mit denen exportierte Dateisysteme in den Verzeichnisbaum eingehängt werden. /etc/amd.conf hingegen legt einige der erweiterten Optionen von amd fest.

Weitere Informationen finden Sie in den Hilfeseiten amd(8) und amd.conf(5).

30.3.6. Integrationsprobleme mit anderen Systemen

Beigetragen von John Lind.

Bestimmte ISA-Ethernetadapter haben Beschränkungen, die zu ernsthaften Netzwerkproblemen, insbesondere mit NFS führen können. Es handelt sich dabei nicht um ein FreeBSD-spezifisches Problem, aber FreeBSD-Systeme sind davon ebenfalls betroffen.

Das Problem tritt fast ausschließlich dann auf, wenn (FreeBSD)-PC-Systeme mit Hochleistungsrechnern verbunden werden, wie Systemen von Silicon Graphics, Inc. oder Sun Microsystems, Inc. Das Einhängen via NFS funktioniert problemlos, auch einige Dateioperationen können erfolgreich sein. Plötzlich aber wird der Server nicht mehr auf den Client reagieren, obwohl Anfragen von anderen Rechnern weiterhin bearbeitet werden. Dieses Problem betrifft stets den Client, egal ob es sich beim Client um das FreeBSD-System oder den Hochleistungsrechner handelt. Auf vielen Systemen gibt es keine Möglichkeit mehr, den Client ordnungsgemäß zu beenden. Die einzige Lösung ist es oft, den Rechner neu zu starten, da dieses NFS-Problem nicht mehr behoben werden kann.

Die “korrekte” Lösung für dieses Problem ist es, sich eine schnellere Ethernetkarte für FreeBSD zu kaufen. Allerdings gibt es auch eine einfache und meist zufriedenstellende Lösung, um dieses Problem zu umgehen. Wenn es sich beim FreeBSD-System um den Server handelt, verwenden Sie beim Einhängen in den Verzeichnisbaum auf der Clientseite zusätzlich die Option -w=1024 . Wenn es sich beim FreeBSD-System um den Client handelt, dann hängen Sie das NFS-Dateisystem mit der zusätzlichen Option -r=1024 ein. Diese Optionen können auf der Clientseite auch durch das vierte Feld der Einträge in /etc/fstab festgelegt werden, damit die Dateisysteme automatisch eingehängt werden. Um die Dateisysteme manuell einzuhängen, verwendet man bei mount(8) zusätzlich die Option -o.

Es gibt ein anderes Problem, das oft mit diesem verwechselt wird. Dieses andere Problem tritt auf, wenn sich über NFS verbundene Server und Clients in verschiedenen Netzwerken befinden. Wenn dies der Fall ist, stellen Sie sicher, dass Ihre Router die nötigen UDP-Informationen weiterleiten, oder Sie werden nirgends hingelangen, egal was Sie machen.

In den folgenden Beispielen ist fastws der Name des Hochleistungsrechners (bzw. dessen Schnittstelle), freebox hingegen ist der Name des FreeBSD-Systems, das über eine Netzkarte mit geringer Leistung verfügt. /sharedfs ist das exportierte NFS -Dateisystem (lesen Sie dazu auch exports(5)). Bei /project handelt es sich um den Mountpunkt, an dem das exportierte Dateisystem auf der Clientseite eingehängt wird. In allen Fällen können zusätzliche Optionen, wie z.B. hard, soft oder bg wünschenswert sein.

FreeBSD als Client (eingetragen in /etc/fstab auf freebox):

fastws:/sharedfs /project nfs rw,-r=1024 0 0

Manuelles Einhängen auf freebox:

# mount -t nfs -o -r=1024 fastws:/sharedfs /project

FreeBSD als Server (eingetragen in /etc/fstab auf fastws):

freebox:/sharedfs /project nfs rw,-w=1024 0 0

Manuelles Einhängen auf fastws:

# mount -t nfs -o -w=1024 freebox:/sharedfs /project

Nahezu alle 16-bit Ethernetadapter erlauben Operationen ohne obengenannte Einschränkungen auf die Lese- oder Schreibgröße.

Für alle technisch Interessierten wird nun beschrieben, was passiert, wenn dieser Fehler auftritt, und warum er irreversibel ist. NFS arbeitet üblicherweise mit einer “Blockgröße” von 8 kByte (obwohl es kleinere Fragmente zulassen würde). Da die maximale Rahmengröße von Ethernet 1500 Bytes beträgt, wird der NFS-“Block” in einzelne Ethernetrahmen aufgeteilt, obwohl es sich nach wie vor um eine Einheit handelt, die auch als Einheit empfangen, verarbeitet und bestätigt werden muss. Der Hochleistungsrechner verschickt die Pakete, aus denen der NFS-Block besteht, so eng hintereinander, wie es der Standard erlaubt. Auf der anderen Seite (auf der sich die langsamere Netzkarte befindet), überschreiben die späteren Pakete ihre Vorgänger, bevor diese vom System verarbeitet werden (Überlauf!). Dies hat zur Folge, dass der NFS-Block nicht mehr rekonstruiert und bestätigt werden kann. Als Folge davon glaubt der Hochleistungsrechner, dass der andere Rechner nicht erreichbar ist (Timeout!) und versucht die Sendung zu wiederholen. Allerdings wird wiederum der komplette NFS-Block verschickt, so dass sich der ganze Vorgang wiederholt, und zwar immer wieder (oder bis zum Systemneustart).

Indem wir die Einheitengröße unter der maximalen Größe der Ethernetpakete halten, können wir sicherstellen, dass jedes vollständig erhaltene Ethernetpaket individuell angesprochen werden kann und vermeiden die Blockierung des Systems.

Überläufe können zwar nach wie vor auftreten, wenn ein Hochleistungsrechner Daten auf ein PC-System transferiert. Durch die besseren (und schnelleren) Netzkarten treten solche Überläufe allerdings nicht mehr zwingend auf, wenn NFS-“Einheiten” übertragen werden. Tritt nun ein Überlauf auf, wird die betroffene Einheit erneut verschickt, und es besteht eine gute Chance, dass sie nun erhalten, verarbeitet und bestätigt werden kann.

Wenn Sie Fragen zu FreeBSD haben, schicken Sie eine E-Mail an <[email protected]>.
Wenn Sie Fragen zu dieser Dokumentation haben, schicken Sie eine E-Mail an <[email protected]>.