Bitte denken Sie daran: Sie dürfen zwar die Online-Version ausdrucken, aber diesen Druck nicht fotokopieren oder verkaufen.
Wünschen Sie mehr Informationen zu der gedruckten Version des Buches "Linux: Wegweiser durch das Netzwerk" dann klicken Sie hier.
NFS, das »Network File System«, ist wahrscheinlich der bekannteste auf RPC basierende Netzwerkdienst. Er erlaubt Ihnen, auf Dateien von entfernten Hosts so zuzugreifen, wie Sie es mit lokalen Dateien tun. Dies wird durch eine Mischung aus Kernel-Funktionalität auf der Client-Seite und einem NFS-Server auf der Server-Seite realisiert. Der Dateizugriff ist für den Client völlig transparent und funktioniert für eine Reihe von Server- und Host-Architekturen.
NFS bietet eine Reihe nützlicher Features:
Es ist nicht besonders schwer, die grundlegenden NFS-Funktionen für den Client und den Server einzurichten. Dieses Kapitel beschreibt, wie es geht.
Sehen wir uns an, wie NFS arbeitet. Ein Client versucht, ein Verzeichnis von einem entfernten Host an sein lokales Verzeichnis zu mounten, genau wie er dies mit einem physikalischen Gerät machen würde. Allerdings ist die für ein entferntes Verzeichnis zu verwendende Syntax anders. Soll zum Beispiel das Verzeichnis /home vom Host vlager an /users auf vale gemountet werden, führt der Administrator auf vale den folgenden Befehl ein:(2)
Greift jemand über NFS auf eine Datei zu, setzt der Kernel einen RPC-Aufruf an nfsd (den NFS-Dämon) auf der Server-Maschine ab. Dieser Aufruf enthält den Datei-Handle, den Namen der gewünschten Datei und den Benutzer- und Gruppen-ID als Parameter. Diese werden verwendet, um die Zugriffsrechte auf die angegebene Datei zu ermitteln. Um das Lesen und Modifizieren von Dateien durch nicht-autorisierte Benutzer zu verhindern, müssen die Benutzer- und Gruppen-IDs auf beiden Hosts identisch sein.
Bei den meisten UNIX-Implementierungen wird die NFS-Funktionalität sowohl für Clients als auch für Server durch Dämonen realisiert, die auf Kernel-Ebene angesiedelt sind und während der Bootphase vom Benutzerspeicher aus gestartet werden. Dies ist auf dem Serverhost der NFS-Dämon (nfsd) und auf dem Client-Host der Block I/O Dämon (biod). Um den Durchsatz zu verbessern, arbeitet biod mit asynchroner Ein-/Ausgabe unter Gebrauch von Read-Ahead und Write-Behind. Häufig werden auch mehrere nfsd-Dämonen gleichzeitig verwendet.
Die NFS-Implementierung von Linux ist von daher etwas anders, als daß der Client-Kode eng mit dem VFS-Layer (»Virtual File System«) des Kernels verbunden ist und daher keine zusätzliche Kontrolle durch biod benötigt. Auf der anderen Seite läuft der Server vollständig im Benutzerspeicher, d. h. es ist aufgrund der damit verbundenen Synchronisations-Fragen nahezu unmöglich, mehrere Kopien des Servers zur selben Zeit laufen zu lassen. Momentan kennt Linux-NFS auch kein Read-Ahead und Write-Behind, Rick Sladkey plant aber, es eines Tages hinzuzufügen.(3)
Das größte Problem mit dem Linux-NFS-Kode ist, daß bei der Version 1.0 des Linux-Kernel nur Speicherblöcke von maximal 4 K genutzt werden können. Die Konsequenz daraus ist, daß der Netzwerk-Kode nur Datagramme übertragen kann, deren Größe auf ungefähr 3500 Byte beschränkt ist, nachdem man die Header etc. abgezogen hat. Das bedeutet, daß Übertragungen von und zu NFS-Dämonen, die auf Systemen laufen, die per Voreinstellung größere UDP-Datagramme übertragen (z. B. 8 K bei SunOS), künstlich heruntergeschraubt werden müssen. Das hat unter Umständen schmerzliche Auswirkungen auf die Performance.(4) Diese Einschränkung ist in den späten Linux-1.1-Kerneln aufgehoben worden. Der Client-Kode ist entsprechend modifiziert worden, um von diesem Vorteil Gebrauch zu machen.
Bevor Sie NFS benutzen können, sei es nur als Client oder als Server, müssen Sie zuerst sicherstellen, daß die entsprechende NFS-Unterstützung in den Kernel integriert (kompiliert) ist. Neuere Kernel haben dazu ein einfaches Interface im Dateisystem proc, nämlich die Datei /proc/filesystems, die Sie einfach mit cat ausgeben können:
Bei älteren Kerneln vor Linux 1.1 ist die einfachste Möglichkeit, um herauszufinden, ob der Kernel NFS unterstützt oder nicht, einfach auszuprobieren, ob sich ein NFS-Dateisystem mounten läßt oder nicht. Dazu können Sie ein Testverzeichnis unter /tmp erzeugen und versuchen, ein Verzeichnis vom NFS-Server (z. B. /home) zu mounten, das dieser an Ihre Maschine exportiert:
NFS-Volumes(5) werden fast genauso gemountet wie die normalen Dateisysteme auch. Sie verwenden dabei für mount die folgende Syntax:
Eine ganze Reihe zusätzlicher Optionen kann beim Mounten eines NFS-Volumes angegeben werden. Diese können entweder auf die Option -o in der Kommandozeile folgen, oder im Optionsfeld von /etc/fstab für dieses Volume stehen. In beiden Fällen werden mehrere Optionen durch Kommata voneinander getrennt. In der Kommandozeile angegebene Optionen überschreiben immer die in fstabstehenden Werte.
Nachfolgend ein Beispiel-Eintrag aus /etc/fstab:
Mit Ausnahme von Per Voreinstellung gibt ein Client bei einem schwerwiegenden Timeout eine Fehlermeldung auf der Console aus und versucht es erneut. Dabei wird das ursprüngliche Timeout-Intervall verdoppelt. Theoretisch könnte dies immer so weitergehen. Volumes, die eine Operation störrisch wiederholen, bis der Server wieder verfügbar ist, werden als fest gemountet (hard-mounted) bezeichnet. Die andere Variante wird als weich gemountet (soft-mounted) bezeichnet und generiert einen I/O-Fehler für den rufenden Prozeß, wenn ein schwerwiegender Fehler auftritt.
Ob Sie ein Volume fest mounten oder nicht, ist teilweise von Ihrem Geschmack, teilweise aber auch von der Art der Informationen abhängig, auf die Sie über dieses Volume zugreifen wollen. Wenn Sie etwa Ihre X-Programme über NFS mounten, wollen Sie wahrscheinlich nicht, daß Ihre X-Session verrückt spielt, nur weil jemand das Netzwerk zum Erliegen gebracht hat, indem er sieben Kopien von xv gleichzeitig benutzt, oder weil er kurz den Ethernet-Stecker gezogen hat. Indem Sie diese Programme fest mounten, stellen Sie sicher, daß der Computer so lange wartet, bis die Verbindung mit dem NFS-Server wiederhergestellt ist. Auf der
anderen Seite brauchen unkritische Daten wie NFS-gemountete News-Partitionen oder FTP-Archive nicht fest gemountet zu sein. Ist die entfernte Maschine zeitweise nicht erreichbar oder heruntergefahren, hängt sich Ihre Session nicht auf. Ist Ihre Netzwerk-Verbindung etwas instabil, oder läuft sie über einen überlasteten Router, können Sie den anfänglichen Timeout mit Hilfe der Option Der mountd-Dämon hält normalerweiße auf die eine oder andere Art fest, welche Verzeichnisse von welchen Hosts gemountet wurden. Diese Information kann mit dem Programm showmount ausgegeben werden, die ebenfalls Teil des NFS-Serverpakets ist. Linux-mountd dagegen kennt diese Möglichkeit noch nicht.
In manchen Fällen stimmen sie aber nicht überein. Statt nun die UIDs und GIDs der Clients mit denen auf dem Server abzugleichen, können Sie auf dem Client den ugidd-Dämon einsetzen, um dieses Problem zu umgehen. Mit der nachfolgend erläuterten Option ugidd ist ein RPC-basierter Server, der, ebenso wie nfsd und mountd, aus rc.inet2 heraus gestartet wird.
Per Voreinstellung erlaubt mount niemandem, Verzeichnisse des lokalen Hosts über NFS zu mounten, was eine sehr vernünftige Einstellung ist. Um einem oder mehreren Hosts den NFS-Zugriff auf ein Verzeichnis zu erlauben, müssen Sie es exportieren, d. h. in der Datei export eintragen. Eine Beispieldatei könnte so aussehen:
Bei der Prüfung eines Client-Host gegen die exports-Datei ermittelt mountd den Hostnamen des Client mit Hilfe eines gethostbyaddr-Aufrufs. Unter DNS liefert dieser Aufruf den kanonischen Hostnamen des Client zurück, d. h. Sie dürfen keine Aliases in exports verwenden. Ohne DNS wird der erste Hostname aus hosts zurückgeliefert, bei dem die Adresse des Client übereinstimmt.
Dem Host-Namen kann eine Liste mit durch Kommata getrennten Optionen folgen, die in eckigen Klammern eingeschlossen sind. Diese Optionen können die folgenden Werte annehmen:
Fehler beim Lesen der exports-Datei wird an syslogds Beachten Sie, daß Hostnamen aus den IP-Adressen des Client durch »Reverse Mapping« ermittelt werden, d. h. der Resolver muß korrekt konfiguriert sein. Wenn Sie mit BIND arbeiten und sicherheitsbewußt sind, sollten Sie den Spoof-Schutz in Ihrer host.conf aktivieren.
Manchmal wäre es Verschwendung, alle NFS-Volumes zu mounten, auf die ein Benutzer möglicherweise zugreifen möchte, sei es wegen der reinen Menge an Volumes, die gemountet werden müßten, sei es wegen der Zeit, die beim Start benötigt würde. Eine gute Alternative hierzu ist ein sogenannter Auto-Mounter. Dabei handelt es sich um einen Dämon, der jedes NFS-Volume automatisch und völlig transparent mountet und nach einer gewissen Zeit wieder unmountet, wenn es nicht verwendet wurde. Einer der besonders kleveren Züge bei einem Auto-Mounter
ist seine Fähigkeit, ein bestimmtes Volume von alternativen Servern zu mounten. Sie können beispielsweise Kopien Ihrer X-Programme und Support-Dateien auf zwei oder drei Hosts verteilt haben, die alle anderen Hosts über NFS mounten. Mit dem Auto-Mounter können Sie nun für diese drei angeben, daß sie auf /usr/X386 gemountet werden sollen. Der Auto-Mounter wird dann versuchen, jeden der drei zu mounten, so lange, bis ein Versuch erfolgreich war.
Der unter Linux am häufigsten verwendete Auto-Mounter ist amd. Er wurde ursprünglich von Jan-Simon Pendry geschrieben und von Mitch D'Souza auf Linux portiert. Die aktuelle Version ist amd-5.3.
Die Beschreibung von amd geht über den Rahmen dieses Kapitels hinaus. Für ein gutes Handbuch sei auf die Quellen verwiesen; sie enthalten eine Texinfo-Datei mit sehr detaillierten Informationen.
Linux-NFS ist größtenteils die Arbeit von Rick Sladkey,(1) der den NFS-Kernel und große Teile des NFS-Servers geschrieben hat. Letzterer wurde vom unfsd-NFS-Server, ursprünglich entwickelt von Mark Shand, und vom hnfs-Harris-NFS-Server, geschrieben von Donald Becker, abgeleitet.
# mount -t nfs vlager:/home /users
mount versucht, über RPC eine Verbindung mit dem Mount-Dämon (mountd) auf vlager herzustellen. Der Server überprüft, ob vale die Erlaubnis besitzt, das fragliche Verzeichnis zu mounten; wenn ja, liefert er einen Datei-Handle zurück. Dieser Handle wird bei allen weiteren Anfragen nach Dateien unter /users verwendet.
NFS vorbereiten
$ cat /proc/file systems
minix
ext2
msdos
nodev proc
nodev nfs
Fehlt nfs in dieser Liste, müssen Sie den Kernel neu kompilieren und dabei NFS mit einbinden. Die Konfiguration der Netzwerk-Optionen des Kernel wird im Abschnitt
»Kernel-Konfiguration«
in Kapitel 3 beschrieben.
# mkdir /tmp/test
# mount server:/home /tmp/test
Schlägt dieser Versuch mit der Meldung »fs type nfs not supported by kernel,« fehl, müssen Sie den Kernel mit eingebundenem NFS neu kompilieren.
Ein NFS-Volume mounten
# mount -t nfs nfs_volume local_dir options
nfs_volume is given as remote_host:remote_dir. Weil diese Notation nur bei NFS-Dateisystemen gilt, können Sie die Option -t nfs weglassen.
# Volume Mountpunkt Typ Optionen
news:/usr/spool/news /usr/spool/news nfs timeo=14,intr
Dieses Volume kann mit dem folgenden Befehl gemountet werden:
# mount news:/usr/spool/news
Fehlt ein solcher fstab-Eintrag, sehen NFS-mounts wesentlich unangenehmer aus. Nehmen wir zum Beispiel an, daß Sie die Home-Verzeichnisse der Benutzer von einer Maschine namens moonshot aus mounten. Um eine Blockgröße von 4 K für Schreib/Lese-Operationen zu verwenden, benutzen Sie den folgenden Befehl:
# mount moonshot:/home /home -o rsize=4096,wsize=4096
Eine vollständige Liste aller gültigen Optionen ist in der nfs(5)-Manpage beschrieben, die bei Rick Sladkeys NFS-fähigem mount-Tool enthalten ist. (Sie finden es in Rik Faiths util-linux-Paket.) Nachfolgend ein Teil der Optionen, die Sie möglicherweise verwenden möchten:
rsize und wsize wirken sich all diese Optionen auf das Verhalten des Client aus, wenn der Server kurzfristig nicht erreichbar sein sollte. Sie spielen auf folgende Weise zusammen: Sendet der Client eine Anforderung an den NFS-Server, erwartet er, daß die Operation innerhalb einer bestimmten Zeit abgeschlossen ist. Diese Zeit kann mit der Option timeout festgelegt werden. Wird innerhalb dieser Zeit keine Bestätigung empfangen, kommt es zu einem sogenannten kleinen Timeout. Die Operation wird nun wiederholt, wobei das Timeout-Intervall verdoppelt wird. Wird der maximale Timeout von 60 Sekunden erreicht, tritt ein großer Timeout auf.
timeo erhöhen oder die Volumes fest mounten. Dabei sollten Sie es aber ermöglichen, daß Signale die NFS-Aufrufe unterbrechen dürfen, damit Sie einen hängenden Dateizugriff unterbrechen können.
Die NFS-Dämonen
Wenn Sie anderen Hosts NFS-Dienste anbieten wollen, müssen die nfsd- und mountd-Dämonen auf Ihrer Maschine laufen. Als RPC-basierte Programme werden sie nicht von inetd verwaltet, sondern werden während der Bootphase gestartet und registrieren sich selbst beim Portmapper. Daher müssen Sie sicherstellen, daß die Programme erst gestartet werden, wenn rpc.portmap schon läuft. Normalerweise fügen Sie die folgenden Zeilen in Ihr rc.inet2-Script ein:
if [ -x /usr/sbin/rpc.mountd ]; then
/usr/sbin/rpc.mountd; echo -n " mountd"
fi
if [ -x /usr/sbin/rpc.nfsd ]; then
/usr/sbin/rpc.nfsd; echo -n " nfsd"
fi
Die Besitzinformationen über Dateien, die ein NFS-Dämon an seine Clients liefert, bestehen üblicherweise nur aus den numerischen Benutzer- und Gruppen-IDs. Wenn der Client und der Server dieselben Benutzer- und Gruppennamen mit diesen numerischen IDs verbinden, spricht man von einem gemeinsamen UID/GID-Raum. Dies ist beispielsweise der Fall, wenn Sie NIS einsetzen, um die passwd-Informationen an alle Hosts in Ihrem LAN weiterzugeben.
map_daemon können Sie nfsd anweisen, mit Hilfe von ugidd den UID/GID-Raum des Servers auf den UID/GID-Raum des Client abzubilden.
if [ -x /usr/sbin/rpc.ugidd ]; then
/usr/sbin/rpc.ugidd; echo -n " ugidd"
fi
Die exports-Datei
Für jeden Client werden die Zugriffsmöglichkeiten bestimmt, über die auf die Dateien auf dem Server zugegriffen werden kann. Dieser Zugriff wird in der Datei /etc/exports festgelegt, die die gemeinsam genutzten Dateien enthält.
# exports-Datei für vlager
/home vale(rw) vstout(rw) vlight(rw)
/usr/X386 vale(ro) vstout(ro) vlight(ro)
/usr/TeX vale(ro) vstout(ro) vlight(ro)
/ vale(rw,no_root_squash)
/home/ftp (ro)
Jede Zeile definiert ein Verzeichnis und die Hosts, die es mounten dürfen. Ein Hostname ist üblicherweise ein voll qualifizierter Domainname, kann zusätzlich aber auch die Platzhalter * und ? enthalten, die auf dieselbe Weise funktionieren wie bei der Bourne-Shell. Beispielsweise wird bei lab*.foo.com sowohl lab01.foo.com als auch laber.foo.com akzeptiert. Wird wie im obigen Beispiel beim /home/ftp-Verzeichnis kein Hostname angegeben, darf jeder Host dieses Verzeichnis mounten.
../. Der String wird so oft vorangestellt, wie es dauert, von dem Verzeichnis, das den Link enthält, bis zum Root-Verzeichnis zu gelangen. Diese Option macht nur Sinn, wenn das gesamte Dateisystem des Host gemountet ist. Anderenfalls könnten einige Links ins Nirgendwo zeigen, oder, noch schlimmer, auf Dateien, auf die niemals gezeigt werden sollte. Diese Option ist per Voreinstellung aktiviert.
map_identity weist den Server an, gleiche UIDs und GIDs für Clients und Server zu erwarten. Diese Option ist per Voreinstellung aktiv.
daemon-Einrichtung auf der Ebene notice weitergegeben, wenn nfsd oder mountd hochfährt.
Der Linux-Auto-Mounter
Fußnoten
Kapitel 10
Kapitel 12