Portierungen ] [ Debian GNU/Hurd ] [ Neues ] [ Konfiguration ] [ Hurd-CDs ] [ Dokumentation ] [ Entwicklung ] [ Kontakt ]

Debian GNU/Hurd

Übersetzer

Das Konzept

Bevor wir uns Übersetzer näher ansehen, sollte wir erst einen Blick auf gewöhnliche Dateisysteme werfen. Ein Dateisystem ist ein Speicher für einen hierarchischen Baum von Verzeichnissen und Dateien. Der Zugriff auf diese Verzeichnisse und Dateien erfolgt über eine spezielle Zeichenkette, den Pfad. Darüber hinaus gibt es symbolische Links, die an mehreren Stellen im Baum auf eine bestimmte Datei verweisen, und harte Links, welche ein und derselben Datei mehrere Namen geben. Außerdem gibt es spezielle Gerätedateien für die Kommunikation mit den im Kernel enthaltenen Gerätetreibern für die Hardware, und es gibt Einhängepunkte zum Einbinden anderer Speicher in den Verzeichnisbaum. Des Weiteren gibt es obskure Objekte wie zum Beispiel FIFOs.

All diese Objekte unterscheiden sich sehr, aber dennoch weisen sie einige gemeinsame Eigenschaften auf, beispielsweise sind allen ein Besitzer und eine Gruppe und auch Zugriffsrechte (Berechtigungen) beigefügt. Diese Informationen stehen in Inodes. Hierbei handelt es sich um eine weitere Gemeinsamkeit: Jedes Objekt ist mit genau einer Inode verknüpft (harte Links sind hier etwas ungewöhnlich, da sie sich ein und dieselbe Inode teilen). Manchmal ist in der Inode auch noch zusätzliche Information gespeichert. Zum Beispiel kann eine Inode das Ziel eines symbolischen Links enthalten.

Diese Gemeinsamkeiten werden jedoch gewöhnlich nicht in den Implementierungen ausgeschöpft, obgleich ihnen eine gemeinsame Programmierschnittstelle zu Eigen ist. Auf alle Inodes kann über die Standard-POSIX-Aufrufe wie zum Beispiel read() und write() zugegriffen werden. Wenn man nun also einen neuen Objekttyp (beispielsweise einen neuen Link-Typ) dem gewöhnlich monolithischen Unix-Kernel hinzufügen möchte, so ist es notwendig, den Programm-Code für jedes Dateisystem einzeln abzuändern.

Beim Hurd läuft einiges anders. Obwohl im Hurd ein spezieller Dateisystemserver die speziellen Eigenschaften von Standard-Objekttypen wie Links nutzen kann (zum Beispiel mittels schnellen Links im Ext2-Dateisystem), weist der Hurd eine allgemein gehaltene Schnittstelle auf, über welche solche Fähigkeiten hinzugefügt werden können, ohne dass existierender Programm-Code verändert werden muss.

Der Trick liegt darin, einem Programm zu erlauben, sich zwischen den eigentlichen Inhalt einer Datei und den zugreifenden Benutzer einzufügen. Solch ein Programm wird Übersetzer genannt, denn es ist in der Lage, die eingehenden Anfragen auf viele unterschiedliche Arten zu verarbeiten. In anderen Worten gesagt ist ein Übersetzer ein Hurd-Server, der die grundlegende Schnittstelle zu Dateisystemen bereitstellt.

Übersetzer haben sehr interessante Eigenschaften. Aus Sicht des Kernels sind sie bloß ein weiterer Benutzerprozess. Das bedeutet, dass jeder Benutzer Übersetzer laufen lassen kann. Es werden keine Administratorrechte benötigt, um einen Übersetzer zu installieren oder zu verändern, man braucht nur die Zugriffsrechte zur unterliegenden Inode, an welche der Übersetzer angehängt ist. Für die Funktion vieler Übersetzer ist keine Datei erforderlich, sie können Informationen auf ihre eigenen Art und Weise liefern. Aus diesem Grund werden die Informationen über Übersetzer in der Inode gespeichert.

Übersetzer sind dafür verantwortlich, alle Dateisystemoperationen bereit zu stellen, die mit der Inode zusammenhängen, an welche sie angehängt sind. Da sie nicht auf den üblichen Satz von Objekten (Gerätedatei, Link, etc.) beschränkt sind, steht es ihnen frei, alles zurückzugeben, was dem entsprechenden Programmierer sinnvoll erscheint. Man stelle sich einen Übersetzer vor, der sich wie ein Verzeichnis verhält, wenn er über cd oder ls zugegriffen wird, und wie eine Datei, wenn der Zugriff über cat erfolgt.

Beispiele

Einhängepunkte

Ein Einhängepunkt kann als eine Inode angesehen werden, an welche ein spezieller Übersetzer angehängt wurde. Sein Zweck wäre es, Dateisystemoperationen am Einhängepunkt in Dateisystemoperationen auf einem anderen Speicher, sagen wir einer anderen Partition, zu übersetzen.

Und wirklich sind Dateisysteme genau so im Hurd implementiert. Ein Dateisystem ist ein Übersetzer. Dieser Übersetzer nimmt einen Speicher als Parameter und ist in der Lage, alle Dateisystemoperationen transparent bereit zu stellen.

Gerätedateien

Es gibt viele verschiedene Gerätedateien, und in Systemen mit einem monolithischen Kernel werden sie alle vom Kernel selbst bereit gestellt. Im Hurd werden alle Gerätedateien von Übersetzern bereit gestellt. Ein Übersetzer kann die Unterstützung für viele ähnliche Gerätedateien, beispielsweise alle Festplattenpartitionen, bereit stellen. Auf diese Weise ist die Anzahl der insgesamt wirklich benötigten Übersetzer recht gering. Dennoch sollte man bedenken, dass für jede zugegriffene Gerätedatei ein separater Übersetzerprozess gestartet wird. Da der Hurd jedoch ausgesprochen multi-threaded arbeitet (es laufen viele Fäden von Programmen gleichzeitig), ist dies nicht sonderlich aufwändig.

Wenn Hardware im Spiel ist, dann beginnt ein Übersetzer für gewöhnlich mit dem Kernel zu kommunizieren, um Daten von der Hardware zu erhalten. Wenn jedoch kein Hardwarezugriff notwendig ist, dann braucht der Kernel nicht beteiligt zu werden. Zum Beispiel erfordert /dev/zero keinen Hardwarezugriff und kann somit komplett im normalen Benutzerkontext eingerichtet werden.

Symbolische Links

Ein symbolischer Link kann als Übersetzer angesehen werden. Beim Zugriff auf den symbolischen Link wird ein Übersetzer gestartet, welcher die Anfrage weiterleitet an das Dateisystem, welches die im Link referenzierte Datei beinhaltet.

Um jedoch bessere Leistung zu erzielen, können Dateisysteme, die symbolische Links nativ unterstützen, dieses Merkmal zu ihrem Vorteil nutzen und symbolische Links auf unterschiedliche Art einrichten. Intern würde der Zugriff auf einen symbolischen Link keinen neuen Übersetzerprozess starten. Für den Benutzer würde es jedoch immer noch so aussehen, als sei ein passiver Übersetzer involviert (siehe unten betreffend eine Erklärung von passiven Übersetzern).

Da der Hurd einen Übersetzer für symbolische Links mitliefert, hat jeder Dateisystemserver mit Unterstützung für Übersetzer auch automatisch Unterstützung für symbolische Links (und harte Links, und Gerätedateien, etc.)! Das bedeutet, dass man sehr schnell ein funktionierendes Dateisystem erhalten und native Unterstützung für symbolische Links und andere Merkmale später hinzufügen kann.

Passive Übersetzer, Aktive Übersetzer

Es gibt zwei Typen von Übersetzern, passive und aktive. Sie sind wirklich komplett unterschiedlich, man vermische die Begriffe also besser nicht, aber sie stehen in naher Relation zu einander.

Aktive Übersetzer

Ein aktiver Übersetzer ist ein laufender Übersetzerprozess wie oben eingeführt. Man kann aktive Übersetzer einrichten und entfernen mit dem Befehl settrans -a. Die Option -a teilt settrans mit, dass der aktive Übersetzer verändert werden soll.

Der Befehl settrans akzeptiert drei Arten von Parametern. Als erstes kann man Optionen für den Befehl settrans selbst setzen, wie -a zum Verändern des aktiven Übersetzers. Dann gibt man die Inode an, die man verändern möchte. Bedenke, dass ein Übersetzer immer mit einer Inode in der Verzeichnishierarchie verknüpft ist. Man kann nur eine Inode auf einmal verändern. Wenn man keine weiteren Parameter angibt, dann wird settrans das Entfernen eines existierenden Übersetzers versuchen. Wie intensiv dieses Entfernen versucht wird, hängt davon ab, welche Optionen zum Forcieren des Vorgangs gesetzt werden (wenn ein Übersetzer noch durch irgendeinen Prozess in Benutzung ist, dann erhält man die Fehlermeldung Gerät oder Ressource beschäftigt (device or resource busy), es sei denn, man zwingt ihn zum Beenden).

Wenn man hingegen weitere Parameter angibt, dann werden diese als eine Kommandozeile zum Starten des Übersetzers interpretiert. Das bedeutet, der nächste Parameter ist der Dateiname der ausführbaren Datei des Übersetzers. Weitere Parameter sind dann Optionen für den Übersetzer und nicht für den Befehl settrans.

Um zum Beispiel eine Ext2fs-Partition einzuhängen, kann man settrans -a -c /mnt /hurd/ext2fs /dev/hd2s5 aufrufen. Die Option -c wird einen Einhängepunkt einrichten, sofern er noch nicht existieren sollte. Dies muss übrigens nicht notwendigerweise ein Verzeichnis sein. Zum Aushängen nutzt man dann settrans -a /mnt.

Passive Übersetzer

Ein passiver Übersetzer wird eingerichtet und verändert mit derselben Syntax wie ein aktiver Übersetzer (nur die Option -a wird weg gelassen), somit gilt das oben Erwähnte auch für passive Übersetzer. Ein Unterschied besteht jedoch: passive Übersetzer sind noch nicht gestartet.

Dies ist sinnvoll, denn dies ist was man gewöhnlich möchte. Man will eine Partitionen nicht eingehängt haben, es sei denn, man greift auch wirklich darauf zu. Man will die Netzwerkfunktionalität nicht laden bevor nicht Netzwerkverkehr herrscht, und so weiter.

Das erste Mal, wenn auf einen passiven Übersetzer zugegriffen wird, wird stattdessen die Inode ausgelesen und ein aktiver Übersetzer wird ihr angehängt unter Benutzung der Kommandozeile, die in die Inode gespeichert wurde. Dies ähnelt der Funktionalität zum automatischen Einhängen unter Linux (automounter). Es stellt jedoch keinen zusätzlichen Bonus dar, den man erst manuell einrichten muss, sondern ist ein integraler Bestandteil des Systems. Das Einrichten eines passiven Übersetzers verzögert also das Starten des Übersetzerprozesses, bis man ihn auch wirklich benötigt. Übrigens, wenn der aktive Übersetzer aus irgendwelchen Gründen sterben sollte, so wird er einfach beim nächsten Zugriff auf die Inode neu gestartet.

Es gibt einen weiteren Unterschied: aktive Übersetzer können sterben oder verloren gehen. Sobald der Prozess eines aktiven Übersetzers getötet wurde (zum Beispiel aufgrund eines Neustarts des Rechners), ist er für immer verloren. Passive Übersetzer sind nicht vergänglich und bleiben über einen Neustart hinweg in der Inode, bis man sie mittels des Befehls settrans verändert oder die Inode löscht, an welche sie angehängt sind. Das bedeutet, dass man keine Konfigurationsdatei zu den Einhängepunkten führen muss.

Ein letzter Punkt: Selbst wenn schon ein passiver Übersetzer eingerichtet ist, kann man immer noch einen anderen aktiven Übersetzer einrichten. Nur wenn der Übersetzer automatisch gestartet wurde, weil zum Zeitpunkt des Zugriffs auf die Inode kein aktiver Übersetzer existierte, nur dann wird der passive Übersetzer berücksichtigt.

Verwalten von Übersetzern

Wie oben erwähnt kann man settrans nutzen zum Einrichten und Verändern von passiven und aktiven Übersetzern. Es gibt eine Vielzahl von Optionen, mit denen man das Verhalten von settrans im Fehlerfall und zur Beeinflussung von Aktionen anpassen kann. Hier ein paar übliche Nutzanwendungen:

Man kann den Befehl showtrans nutzen um nachzusehen, ob ein Übersetzer an eine Inode angehängt ist. Dies wird jedoch nur den passiven Übersetzer anzeigen.

Man kann die Optionen eines aktiven (Dateisystem-)Übersetzers mittels fsysopts verändern, ohne ihn dabei neu starten zu müssen. Das ist sehr praktisch. Zum Beispiel kann man das, was unter Linux eine Partition nur-lesend neu Einhängen (remounting a partition read-only) genannt wird, mit einem schlichten fsysopts /mntpoint --readonly erledigen. Der laufende aktive Übersetzer wird sein Verhalten soweit wie irgend möglich entsprechend der Anfrage anpassen. fsysopts /mntpoint ohne Parameter zeigt die aktuellen Einstellungen.

Beispiele

Am Anfang ist es empfehlenswert, sich den Befehl /bin/mount durchzulesen, es ist nur ein kleines Skript. Da das Einrichten eines Dateisystemübersetzers dem Einhängen von Partitionen ähnelt, lässt sich das Konzept auf diese Art schnell verstehen. Erstellen Sie ein Dateisystem-Image mittels dd if=/dev/zero of=dummy.fs bs=1024k count=8; mke2fs dummy.fs und versuchen Sie, es mit settrans -c dummy /hurd/ext2fs `pwd`/dummy.fs einzuhängen. Man beachte, dass der Übersetzer noch nicht gestartet wird, es läuft kein neuer Ext2fs-Prozess (was man mit ps Aux überprüfen kann). Überprüfen Sie alles auf Korrektheit mit showtrans.

Nun geben Sie ls dummy ein und Sie werden eine kurze Verzögerung wegen des Startens des Übersetzers bemerken. Danach werden beim Zugriff auf dummy keine weiteren Verzögerungen mehr auftreten. Unter Linux würde man sagen, man habe ein lokales Loop-Dateisystem automatisch eingehängt (automounted a loop file system). Überprüfen Sie mit ps Aux, ob ein Prozess ext2fs dummy gerade läuft. Nun übertragen sie ein paar Dateien in das neue Verzeichnis. Versuchen Sie, das Dateisystem mit fsysopts auf nur-lesend zu setzen. Man beachte, wie daraufhin weitere Schreibversuche scheitern werden. Versuchen Sie, den aktiven Übersetzer mit settrans -g zu entfernen.

Sie dürften nun ein gewisses Verständnis dafür haben, was dabei passiert. Nun erinnere man sich aber daran, dass dies nur ein spezieller Server war, der Hurd Ext2fs-Server. Es gibt viele weitere Server im Verzeichnis hurd. Manche von ihnen sind für Dateisysteme. Manche werden für Dateisystemeigenarten wie Links benötigt. Manche braucht man für Gerätedateien. Manche sind nützlich für Netzwerke. Stellen Sie sich vor, einen FTP-Server mit settrans einzuhängen und Dateien einfach mit dem Standard-Befehl cp herunterzuladen. Oder das Bearbeiten Ihrer Webpräsenz mit emacs /ftp/homepage.my.server.org/index.html!