Mit Unterstützung durch Saxonia Systems    
Druckversion
 
   Anfang
   Inhalt
   Einleitung
   Erste Schritte
   Die Bash
   Das Dateisystem
   Nutzerkommandos
   Installation
   Shells
   Unix-Werkzeuge
   System-Administration
     Bootvorgang
     Datensicherung
     Dateisysteme
     Gruppenverwaltung
     Hardware
     Software
     Loginverwaltung
     Nutzerverwaltung
     Protokollierung
     Systemsicherheit
     X konfigurieren
     Zeit und Steuerung
     Zugriffsrechte
   X Window System
   Der Kernel
   Netzwerk Grundlagen
   Netzwerk Clients
   Netzwerk Server
   Netzwerk Sicherheit
   Anhang
   Register

Dateisysteme

Übersicht

Jede Computeranwendung wird irgendwelche Informationen speichern wollen, seien es permanente Daten, die ein Programm als Ausgabe liefert oder aber temporäre Dateien, die nicht komplett in den Adressraum eines Prozesses passen. Beim erneuten Start des Programms wird dieses seine abgespeicherten Informationen schnell wiederfinden wollen. Damit haben wir nur zwei wesentliche Aspekte eines Dateisystems tangiert...

Dateisystemimplementierungen gibt es zuhauf und Linux kennt die meisten. Wie das möglich ist, ist u.a. Gegenstand des Abschnitts.

Dateisysteme müssen vor ihrer Verwendung angelegt werden. Fehler beim Speichern, z.B. durch Rechnerabsturz, bleiben nicht aus. Also gehören auch Kommandos zur Überprüfung und Reparatur von Dateisystemen zum Umfang eines jeden Betriebssystems.

Das virtuelle Dateisystem

So ziemlich jedes neue Betriebssystem, das jemals jemand in die Welt gesetzt hatte, brachte eigene Vorstellungen vom Aussehen seines Dateisystems mit. Gemeinsam ist ihnen die Absicht, eine große Menge an Informationen permanent speichern zu können, so dass auch noch mehrere Prozesse gleichzeitig auf diese zugreifen können. Dateien sind die Container, in denen die Informationen abgelegt sind und Festplatten, Disketten, ... sind das Medium der dauerhaften Speicherung.

Aber damit hören die Gemeinsamkeiten der Dateisysteme auch schon auf.

Aus Sicht des Benutzers unterscheiden sich vor allem:

  • die Möglichkeiten zur Benennung von Dateinamen; man denke nur an die 8.3-Regel bei MSDOS
  • der Schutz der Daten (Attribute, Zugriffsrechte...)
  • die maximal mögliche Dateigröße
  • definierte Operationen (Öffnen, Schließen, Erzeugen, ..., Wahlfreier Zugriff)

Aus Sicht des Betriebssystems kommen noch die Details der Implementierung hinzu:

  • Wie wird freier Speicher verwaltet?
  • Welche Blockgröße wird verwendet?

Die meisten Betriebssysteme umgehen das Problem mit dem Vogel-Strauß-Algorithmus: sie unterstützen neben ihrem eigenen Dateisystem bestenfalls marktstrategisch wichtige Fremdsysteme.

Nicht so Linux, das so ziemlich mit jedem Dateisystem zu Rande kommt, und selbst den Zugriff auf Partitionen von Windows-Systemen ermöglicht.

Wie wurde das realisiert?

Indem eine Schnittstelle zwischen Betriebssystem und den unterschiedlichen Dateisystemen geschaffen wurden. Es liegt nun in der Verantwortung dieses Virtuellen Dateisystems, wie es die Systemrufe des Kernels in die spezifischen Aktionen eines konkreten Dateisystems umsetzt.

Prinzip des Virtuellen Dateisystems

Abbildung 1: Prinzip des Virtuellen Dateisystems

Unterstützte Dateisysteme

Die Unterstützung der Dateisysteme ist Aufgabe des Kernels, d.h. jedes Dateisystem, auf das Ihr System zugreifen soll, muss in den Kernel einkompiliert oder als Modul realisiert sein. Um schnell zu entscheiden, wie die momentane Unterstützung ausschaut, können Sie einen Blick in die Datei »/proc/filesystems« werfen:

user@sonne> cat /proc/filesystems
nodev   sockfs
nodev   tmpfs
nodev   shm
nodev   pipefs
nodev   proc
        ext2
        vfat
        iso9660
nodev   nfs
nodev   devpts
        reiserfs

Liegt der Treiber für ein Dateisystem als Modul vor, so erscheint es erst in obiger Datei, wenn sein Modul geladen wurde. Sehen Sie im Verzeichnis »/lib/modules/<kernel_version>/kernel/fs« nach, welche Dateisystemtreiber durch Module realisiert sind (seit Kernel 2.4.0 sind die Module jedes Dateisystems in einem eigenen Unterverzeichnis enthalten; bei älteren Kerneln sind alle Module in einem Verzeichnis »/lib/modules/<kernel_version>/fs« organisiert):

user@sonne> ls /lib/modules/2.4.16/kernel/fs/
adfs binfmt_aout.o coda hpfs nls reiserfs udf
affs binfmt_coff.o cramfs jffs ntfs romfs ufs
autofs binfmt_misc.o efs ncpfs qnx4 smbfs umsdos
autofs4 binfmt_xout.o hfs nfsd ramfs sysv

Beim Zugriff auf ein solches Dateisystem sollte der Kernel (exakt: der kerneld [Kernel 2.0.x] bzw. kmod [Kernel >= 2.2]) das entsprechende Modul automatisch laden. Näheres zum Kernel und Modulen erfahren Sie im Kapitel Kernel.

Einige der interessanteren Dateisysteme fasst die folgende Tabelle zusammen:

bfs
         UnixWare Boot Filesystem
devfs
         Device File System; virtuelles Dateisystem zur Verwaltung der Geräte, das die (noch) üblichen Gerätedateien des Verzeichnisses /dev ersetzen wird.
ext
         Der Vorgänger des ext2, kaum mehr in Gebrauch
ext2
         Das Standarddateisystem von Linux
ext3
         Weiterentwicklung von ext2 mit zusätzlichen Funktionen eines Journaling File Systems
iso9660
         Alle CD-ROMs speichern ihre Daten unter diesem Format
hpfs
         OS-2 (nur lesend)
loopback
         Mounten einer einzelnen Datei als Dateisystem
minix
         Minix ist der eigentliche Vorgänger von Linux, sein Dateisystem wird gern noch für (Installations-) Disketten eingesetzt
msdos
         DOS, wichtig für den Zugriff auf DOS-formatierte Disketten
ncpfs
         Novell Netware
nfs
         Network File System
ntfs
         WindowsNT (2000, XP), schreiben ist auf dieses Dateisystem zwar möglich, jedoch kann dies leicht zu irreparablen Schäden führen
ramdisk
         Mounten eines Bereichs des Hauptspeichers als Dateisystem
SMB
         (Server Message Block) NT, Windows für Workgroups; zum Zugriff auf von einem Windows-Rechner freigegebene Verzeichnisse
swap
         Swap-Partitionen oder -Dateien
SystemV
         Verschiedene Unixe
proc
         Prozessverwaltung
reiserfs
         Eines der ersten Journaling File Systeme für Linux
umsdos
         DOS-Dateisystem unter Linux verwenden, hier wird vor allem ein Mapping der unterschiedlichen Dateinamensformate und -rechte vorgenommen
vfat
         Windows95, sowohl in der 16 bit als auch 32 bit Variante

Auf jedes Dateisystem im Detail einzugehen, würde Bände füllen, weswegen wir nur das Linux-Dateisystem ext2, die beiden Vertreter der Journaling Filesysteme ReiserFS und ext3 sowie das Device-Dateisystem devfs genauer vorstellen möchten. Im Kapitel Kernel erfahren Sie Einzelheiten zum Prozessdateisystem.

Das Extended File System Version 2 (ext2)

ext2 galt über Jahre hinweg als das Standard-Dateisystem für Linux. Erst mit Aufkommen der Journaling Dateisysteme etablierten sich ernsthafte Alternativen. Doch erforderten Unzulänglichkeiten in Kernelversionen der 2.2er Serie und im Bootmanager Lilo < Version 21.6, dass zumindest der Kernel selbst und die Dateien des Lilo-Bootmanagers zwingend auf einem ext2-Dateisystem platziert wurden. Aktuellen Kernel- und Lilo-Versionen sind derartige Einschränkungen fremd.

Dass das ext2 gegenüber anderen Implementierungen zahlreiche Vorteile mit sich bringt, werden Sie in diesem Abschnitt kennen lernen.

ext2 hält sich in seinem Aufbau stark an die bewährte Architektur, die allen UNIX-Dateisystemen gemein ist. Beginnen wir deshalb mit dem Allgemeinen.

Das Prinzip des Inodes ist allen Unix-Dateisystemen gleich

Generell werden die Verwaltungsinformationen von den eigentlichen Daten getrennt gespeichert. Die Verwaltungsdaten einer Datei, also alle Merkmale wie Rechte, Zugriffszeiten, Größe usw., werden in so genannten Inodes gehalten. Die einzige wichtige Information, die nicht im Inode steht, ist der Name der Datei. Der selbst steht in einem Verzeichnis und verweist auf den zugehörigen Inode. Ein Verzeichnis wiederum ist auch nur eine Datei. Es wird durch einen Inode repräsentiert und die Daten der Verzeichnisdatei sind die enthaltenen Verzeichniseinträge.

Speicherung einer Datei

Abbildung 2: Speicherung einer Datei im Inode

Genau 60 Bytes stünden im Inode zur Speicherung von Daten zur Verfügung. Allerdings werden einzig die Daten symbolischer Links direkt im Inode gehalten, für alle anderen Dateitypen gelten die letzten 15 Einträge im Inode als 32-Bit Zeiger und verweisen auf Datenblöcke, die nun die eigentlichen Daten aufnehmen. Wie viele Zeigereinträge gültig sind, wird anhand der im Inode gespeicherten Anzahl belegter Datenblöcke berechnet.

12 direkte Zeiger auf Datenblöcke sind in einem Inode vorgesehen. Genügt der Speicherplatz für eine Datei noch immer nicht aus, referenziert der nächste Eintrag im Inode einen Datenblock, dessen Inhalt nun als Zeiger auf die eigentlichen Datenblöcke betrachtet wird; man spricht von einem einfach indirekten Zeiger. Ist die Datei weiterhin unersättlich, kommt der nächste Eintrag ins Spiel. Er verweist auf einen Datenblock, dessen Inhalt Zeiger auf Datenblöcke sind, deren Inhalte letztlich Zeiger auf die Daten der Datei sind. Alles klar? Es handelt sich um einen zweifach indirekten Zeiger. Und manche Dateien können einfach nicht genug Speicherplatz bekommen, also ist der nächste (und letzte) Eintrag im Inode ein Zeiger auf... [ich erspare mir die Ausführungen]. Es ist ein dreifach indirekter Zeiger.

Während die Größe eines Inodes im Falle des ext2 konstant 128 Byte beträgt, kann die Datenblockgröße beim Einrichten des Dateisystems festgelegt werden. Zulässig sind 1k, 2k und 4k (wird meist bevorzugt; höhere Blockgrößen sind (derzeit) nicht zulässig, da die Pagegröße 4k beträgt).

Der Einfluss der Datenblockgröße auf die Speicherkapazität

Eine einfache Berechnung soll zeigen, wie die Größe eines Datenblocks die maximal mögliche Größe einer Datei beschränkt.

Unsere Blockgröße sei »1024 Bytes«, dann lassen sich mit den 12 direkten Zeigern des Inodes maximal »12*1024 Bytes» (12k) Daten speichern. Der einfach indirekte Zeiger verweist auf einen Datenblock, der maximal »1024/4« Zeiger (ein Zeiger belegt 4 Bytes) aufnehmen kann, also erreicht dieser »1024*256 Bytes« (256k) Daten. Mit derselben Überlegung erhält man für den zweifach indirekten Zeiger »1024*256*256 Bytes« (65536k) Daten und der dreifache schafft gar »1024*256*256*256 Bytes« (16GByte) Daten.

Um die machbare Dateigröße zu erhalten, sind die vier Werte zu addieren. Die nachfolgende Tabelle enthält die (theoretischen) Werte für die verschiedenen Datenblockgrößen:

Blockgröße (kByte) Maximale Dateigröße (GByte)
1 16
2 256
4 4100

Wie so oft klafft zwischen Theorie und Praxis ein riesiges Loch, so dass tatsächlich nur Daten bis zu einer Größe von 2 GByte (Linux Kernel 2.2.x) gehandhabt werden können. Diese Beschränkung liegt in der Handhabung der Dateigröße durch den Kernel begründet, der diese nur mit 32 Bit speichert, wobei das höchstwertige Bit auch noch als Vorzeichen betrachtet wird. Im 2.4er Kernel wird mit 64 Bit gearbeitet, so dass er den »Schwarzen Peter der Begrenzung« den Dateisystemimplementierungen in die Schuhe schiebt. Um das »ext2« für diese Dateigröße einsetzen zu können, wird ab Kernel 2.4 ein bislang nicht verwendeter Eintrag im Inode zusätzlich zur Speicherung der Dateigröße verwendet, so dass die notwendigen 64 Bit - bei Wahrung der bisherigen Strukturen - zur Verfügung stehen.

Der Datenblock ist im Sinne der Dateiverwaltung die kleinste zu adressierende Einheit. Als Konsequenz ist der physische Speicherplatzverbrauch einer Datei im Mittel größer ist als ihr tatsächlicher Bedarf. Ist eine Datei bspw. 1500 Bytes groß, so benötigt sie bei einer 1k Blockgröße 2k Speicherplatz, bei 2k Blockgröße 2k Speicherplatz, bei 4k Blockgröße belegt sie jedoch 4k Speicherplatz, d.h. im letzten von einer Datei belegten Block geht im Mittel die Hälfte des Speicherplatzes als »Verschnitt« verloren. Die Logik legt nahe, dass die 1k-Blockgröße die beste Wahl sei.

Die Vermutung kann man bestätigen, für den Fall, dass man überwiegend sehr kleine Dateien speichern will. Bei großen Dateien jedoch beschleunigt die 4k-Blockgröße den Lesezugriff enorm, da sicher gestellt ist, dass umfangreiche Teile der Datei hintereinander auf der Festplatte liegen und der Schreib-Lese-Kopf diese »in einem Ritt« besuchen kann. Hohe Blockgrößen minimieren den Effekt der Fragmentierung.

Welcher Inode oder Block ist frei?

Wird eine neue Datei erzeugt, so muss ein freier Inode für sie gefunden und reserviert werden. Ebenso reserviert ext2 eine Reihe möglichst zusammen hängender Blocknummern, um die Daten aufnehmen zu können. Vermutlich werden viel zu viele Blöcke als belegt markiert. Aber solange die Datei nicht geschlossen wurde, ist ihr tatsächlicher Speicherbedarf ungewiss. Wird die Bearbeitung einer neuen Datei beendet, gibt ext2 die nicht benötigten Blöcke wieder frei, verbraucht die Datei alle Einheiten, liegen diese nun in einem Stück auf der Platte. Dieselbe »vorausschauende« Markierung von Blöcken kommt beim Anfügen von Daten an eine existierende Datei zur Anwendung, so dass der Grad der Fragmentierung einer Datei von Haus aus in akzeptablen Grenzen gehalten wird.

Um einen freien Inode oder Block aufzuspüren, könnte sich ext2 durch die Inodes bzw. Blöcke »durchhangeln«, bis endlich ein unbelegter Eintrag gefunden wurde. Jedoch wäre diese Art der Suche furchtbar ineffizient. ext2 verwendet deshalb Bitmaps, die bitweise kodieren, welche Blöcke bzw. Inodes frei und welche belegt sind. Es existieren jeweils eine Bitmap für Blöcke und eine für die Inodes. Eine »0« des Bits x kennzeichnet den Block (Inode) mit der Nummer x als frei, eine »1« steht für einen verwendeten Block (Inode).

Eine solche Bitmap belegt genau einen Block, d.h. bei 1k Blöcken verwaltet eine Bitmap 8192 Inodes bzw. Datenblöcke. Mit 4k Blockgröße können 32768 Einheiten angesprochen werden, was wiederum die mögliche Größe einer Datei auf 128 MByte beschränken würde.

Das Konzept der Gruppen

ext2 organisiert das Dateisystem in Gruppen. Jede Gruppe beinhaltet eine Kopie des Superblocks, eine Liste aller Gruppendeskriptoren, die Bitmaps für die enthaltenen Inodes und Datenblöcke und die Listen derselbigen.

Aufbau eines ext2-Gruppe

Abbildung 3: Aufbau eines ext2-Gruppe

Der Superblock einer jeden Gruppe ist die exakte Kopie des Superblocks des Dateisystems und beinhaltet Informationen zur Blockgröße, der Anzahl der Inodes und Datenblöcke, den Status des Dateisystems, Anzahl der Mountvorgänge seit der letzten Überprüfung usw. Alle Informationen lassen sich mit dem Kommando dumpe2fs gewinnen:

root@sonne> dumpe2fs /dev/hda4
Filesystem volume name:   <none>
Last mounted on:          /mnt/boot
Filesystem UUID:          99c0ce4a-9e7d-11d3-86d7-b832bfd4e1f7
Filesystem magic number:  0xEF53
Filesystem revision #:    0 (original)
Filesystem features:     (none)
Filesystem state:         not clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              8016
Block count:              16033
Reserved block count:     801
Free blocks:              13365
Free inodes:              7983
First block:              1
Block size:               1024
Fragment size:            1024
Blocks per group:         8192
Fragments per group:      8192
Inodes per group:         4008
Inode blocks per group:   501
Last mount time:          Mon Jul  3 07:07:46 2000
Last write time:          Mon Jul  3 07:07:51 2000
Mount count:              17
Maximum mount count:      100
Last checked:             Fri Jun  9 07:06:36 2000
Check interval:           15552000 (6 months)
Next check after:         Wed Dec  6 06:06:36 2000
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)


Group 0: (Blocks 1 -- 8192)
  Block bitmap at 3 (+2), Inode bitmap at 4 (+3)
  Inode table at 5 (+4)
  6044 free blocks, 3981 free inodes, 2 directories
  Free blocks: 519-525, 1410-1416, 1826-1834, 2155-2158, 2174-2178, 2181-8192
  Free inodes: 20, 29-4008
Group 1: (Blocks 8193 -- 16032)
  Block bitmap at 8195 (+2), Inode bitmap at 8196 (+3)
  Inode table at 8197 (+4)
  7321 free blocks, 4002 free inodes, 1 directories
  Free blocks: 8712-16032
  Free inodes: 4015-8016

Gruppendeskriptoren beinhalten Informationen zur relativen Lage der Bitmaps und der Inode-Tabelle innerhalb einer Gruppe. Da die Deskriptoren aller Gruppen in jeder Gruppe gespeichert sind, kann bei Beschädigung einer Gruppe diese anhand der Informationen restauriert werden (zumindest solange kein mechanischer Defekt des Speicherbereichs vorliegt).

Die Nummerierung der Inodes und Blöcke ist innerhalb eines Dateisystems eindeutig. Ist der letzte Inode der Gruppe x der Inode Nr. y, so ist der erste Inode der Gruppe x+1 der Inode Nr. y+1.

Und der Sinn der Gruppe? Durch die gewählte Struktur wird sicher gestellt, dass sich die Daten einer Datei nahe bei ihrem Inode befinden und die Dateien eines Verzeichnisses nahe der Verwaltungsstruktur des Verzeichnisses liegen. Letztlich verhilft die Anordnung zu einem schnelleren Zugriff auf die Festplatte.

Die äußere Struktur des ext2

Aufbau des ext2

Abbildung 4: Aufbau des ext2

Das Dateisystem ext2 stellt sich als eine Aneinanderreihung gleich großer Gruppen dar, denen der in jedem Dateisystem vorhandene und im Aufbau standardisierte Bootsektor voransteht. Die Anzahl der Gruppen wird dabei durch die Faktoren der Partitionsgröße einerseits und durch die gewählte Blockgröße und Inode-Anzahl andererseits bestimmt.

Da die Speicherkapazität einer einzelnen Gruppe auf maximal 128 MByte begrenzt ist, werden die Daten sehr großer Dateien auf mehrere Gruppen verteilt.

Journaling Dateisysteme

Die Idee

In regelmäßigen Abständen, und prinzipiell zum ungünstigsten Zeitpunkt (weil man gerade mal wieder unter Zeitdruck steht), wartet Linux mit einem verzögerten Systemstart auf:

/dev/hda1 has reached maximal mount count, check forced...

Das Linuxdateisystem ext2 hält es mal wieder für angebracht, seinen Inhalt einer gewissenhaften Überprüfung zu unterziehen. Je nach Größe der Partition und Leistungsfähigkeit des Prozessors kann die Revision wenige Minuten bis hin zu einigen Stunden konsumieren. Solch geplanter Aktivität lässt sich mit kleineren Manipulationen zuvor kommen. Was aber nach einem Absturz oder einem hängen gebliebenen »not clean - Filesystem state«, nur weil Sie den Ausschalter zwei Sekunden zu früh bemühten? Jetzt hilft nur Geduld ...irgendwann wird der Test schon fertig werden...

Für den privaten Rechner ist das Verhalten zwar lästig, aber ohne Folgen. Was aber, wenn die Datenbank des Servers für einige Zeit ausfällt, nur weil dieser nach einem Absturz die Platten scannt? Hunderte Clients warten vergebens auf die angeforderten Daten? Hier sollte die Überführung des Dateisystems in einen konsistenten Zustand höchstens ein paar Sekündchen dauern.

Journal - Protokollierung des Dateizugriffs

ext2 ist ziemlich faul, was die Buchführung seiner Aktivitäten betrifft. Wird ein ext2-Dateisystem »gemountet«, vermerkt es nur, dass es in Benutzung ist. »Not clean« lautet der Status des Systems. Folgt später dann ein »umount«, wechselt der Status zurück auf »clean«. Wenn das saubere Abhängen - aus welchem Grund auch immer - scheiterte, muss ext2 beim folgenden Systemstart alle Dateien überprüfen, um eventuellen Ungereimtheiten auf die Schliche zu kommen.

Hier setzt die Idee des Journal Dateisystems an. In ihm werden alle momentan bearbeiteten Dateien protokolliert, so dass im Falle eines Systemcrashs beim Wiederanlauf einzig diese Dateien auf Inkonsistenzen hin zu überprüfen sind. Eine weitere Maßnahme ist die Einführung eines transaktionsbasierten Modells, wonach eine Datei solange ihre Gültigkeit behält, bis die Bearbeitung einer neueren Version vollständig abgeschlossen wurde. Somit wird die fehlerträchtige Zeitspanne auf den Moment des Abspeicherns reduziert.

Die verschiedenen Implementierungen

Journaling Dateisysteme bewähren sich schon seit einigen Jahren im praktischen Einsatz. Nur eine Implementierung unter Linux ließ lange auf sich warten. Derzeit existieren vier Implementierungen:

  • ext3 (Nachfolger des ext2)
  • ReiserFS
  • jfs (IBM)
  • xfs (SGI)

Dem Umstand, ersteres einsatzbereites System mit einem Journal gewesen zu sein, hat das ReiserFS seine weite Verbreitung unter Linux zu verdanken. Dieses Dateisystem und die Erweiterung des ext2, das ext3 werden Sie im weiteren Text kennen lernen.

Die Entwicklungen von IBM und SGI sind zwar unterdessen ebenso verfügbar, werden aber (derzeit) kaum eingesetzt. Über die folgenden Sätze zu den maximal zulässigen Dateigrößen der einzelnen Journaling Dateisysteme hinaus, werden Sie keinen weiteren Hinweise zu diesen beiden Vertretern im Buch finden.

ext3, das sich an den Maßgaben des ext2 orientiert und den selben Beschränkungen unterliegt, ermöglicht somit maximal 4 TByte große Dateien. Gar mit stolzen 4 Petabytes (4*1015 Bytes) für einen einzelne Datei wartet IMB's jfs auf. Noch ganz andere Dimensionen schwebten den Entwicklern bei SGI vor. Ihr xfs soll immerhin 9 Exabytes (9*1018 Bytes) in eine Datei stopfen können. Und ReiserFS wird in zukünftigen Versionen 1025 Bytes handhaben können! Inwiefern die Angaben einen praktischen Nutzen haben, sei dahingestellt...

Das ReiserFS

Das Prinzip des ReiserFS

Das ReiserFS speichert die Daten in einem B-Baum (ein »Balanced«-Baum ist eine Verallgemeinerung der bekannten Binärbäume). Ein Element des Baumes wird als Knoten bezeichnet. Ein Knoten ist dabei als Wurzel ausgezeichnet, von dem aus alle weiteren Knoten erreichbar sind. Alle Knoten unterhalb eines bestimmten Knotens bilden einen Teilbaum und die maximale Anzahl von Knoten, die zu einem Blatt (unterster Knoten) führen, bezeichnet man als die Höhe des Teilbaums. Unterscheidet sich die minimale Anzahl von Knoten auf dem Weg von der Wurzel eines jeden Teilbaums hin zu einem Blatt von der maximalen Anzahl auf einem beliebigen anderen Weg höchstens um 1, so spricht man von einem balancierten Baum.

Die Baumstruktur eines ReiserFS

Abbildung 5: Die Baumstruktur eines ReiserFS

Ein Knoten des Baumes enthält nun die Suchschlüssel. Im Falle des ReiserFS werden die Dateinamen als Schlüssel verwandt. Innerhalb eines Knotens sind die enthaltenen Schlüssel aufsteigend sortiert und für jeden Schlüsselwert gilt, dass im Teilbaum, der durch den linken Zeiger referenziert wird, nur Schlüsselwerte gespeichert sind, die kleiner als dieser sind und im rechts angeordneten Zweig sind alle Schlüssel gleich oder größer.

Im Jargon des ReiserFS werden drei Typen von Knoten unterschieden:

  • Der unformatierte Knoten enthält letztlich die Daten zu einer Datei und korrespondiert mit dem Datenblock im ext2 (der Typ ist in der Abbildung nicht dargestellt)
  • Der Blattknoten (»formatierter Knoten«) enthält die Einträge. Ein Eintrag kann ein »direkter Eintrag«, ein »indirekter Eintrag«, ein »Verzeichniseintrag« oder ein »Statuseintrag sein« (in der Abbildung ist der Typ in der untersten Reihe dargestellt)
  • Der interne Knoten dient letztlich zum schnellen Auffinden eines Eintrags und enthält die geordneten Schlüssel (Zur Veranschaulichung wurden in der Abbildung 5 die Zeiger auf die Teilbäume direkt neben den Schlüsselwerten dargestellt. Tatsächlich speichert das ReiserFS zunächst eine Liste der (n) Schlüssel und nachfolgend die Liste der (n+1) Zeiger.)

Beispiel: Um die Datei hosts.deny aufzufinden, geht der Suchalgorithmus wie folgt vor: Die gesuchte Datei wird mit dem ersten Schlüsselwert aus dem Wurzelknoten verglichen. Ist er kleiner, wird im Baum, der über den links stehenden Zeiger referenziert wird, weiter gesucht. Ist der Wert gleich, so wird jeweils dem rechten Zeiger gefolgt. Ist er größer, so wird, falls vorhanden, der nächste Schlüssel im Knoten betrachtet und das Verfahren wiederholt sich. Im obigen Beispiel ist der Schlüsselwert »hosts.deny« kleiner als »lilo.conf«, also wird im linken Teilbaum gesucht. Der erste Wert dort »hosts« ist kleiner, also wird, da kein weiterer Wert im Knoten enthalten ist, rechts weiter gegangen. Im letzten Level der internen Knoten tritt beim zweiten Vergleich eine Übereinstimmung ein. Über den korrespondierenden Zeiger kann auf die Informationen der Datei zugegriffen werden.

Das Einfügen und Entfernen von Schlüsseln ist eine komplexe Angelegenheit und Gegenstand der theoretischen Informatik. Dennoch möchte ich versuchen, das Prinzip knapp zu präsentieren.

Beginnen wir mit dem Anlegen einer neuen Datei (ein Verzeichnis ist auch nur eine Datei...). Der Algorithmus beginnt wieder mit dem Vergleich (Kriterium ist der neue Dateiname) in der Wurzel und folgt den Zeigern bis zu der Position im untersten internen Knoten, der die neue Datei aufnehmen müsste. Ist im Knoten noch genügend Speicherplatz zur Aufnahme des neuen Schlüssels vorhanden, so wird dieser hier eingefügt. Dabei wird die alphabetische Anordnung beibehalten (durch Verschieben größerer Schlüssel nach rechts). Jetzt wird es irgendwann geschehen, dass der Belegungsgrad eines Knotens einen bestimmten Wert übersteigt (der Faktor hängt von der Konfiguration ab). Jetzt wird der Knoten zweigeteilt, wobei jede Hälfte die gleiche Anzahl Schlüssel erhält. Der neue »linke« Knoten (mit den kleineren Schlüsselwerten) ist schon im übergeordneten Knoten enthalten, nur der erste Schlüsselwert des neuen »rechten« Knotens muss noch im »Vater« aufgenommen werden. Also wiederholt sich dort das Spielchen, eventuell muss auch der Vaterknoten gesplittet werden. Sollte gar der Wurzelknoten überlaufen, so wird auch er geteilt und eine neue Wurzel erzeugt.

Der umgekehrte Weg wird beim Löschen eines Eintrages gegangen. Wird im untersten Knoten der Eintrag entfernt, muss zunächst überprüft werden, ob der Schlüssel nicht in den übergeordneten Knoten verwendet wird. Falls dem so ist, ist der dortige Schlüssel durch einen geeigneten anderen zu ersetzen. Weiterhin wird der Grad der Belegung mit den benachbarten Knoten verglichen und ggf. eine Vereinigung dieser veranlasst. Dies zieht weite Kreise, da nun im übergeordneten Knoten ein Schlüssel zu viel enthalten ist und dieses korrigiert werden muss.

Die Speicherung der Informationen zu Dateien und Verzeichnissen findet in den Blattknoten statt. In der aktuellen Konfiguration existiert der Statuseintrag nicht eigenständig, sondern ist dem Datei- bzw. Verzeichniseintrag zugeordnet.
Ein Verzeichniseintrag beinhaltet neben den Statusinformationen alle Schlüssel zu den enthaltenen Dateien. In einem indirekten Eintrag stehen Zeiger auf unformatierte Knoten, die die Daten zu einer Datei beinhalten. Im Unterschied zum ext2 sind diese Blöcke immer voll belegt, da das Ende einer Datei in einem direkten Eintrag gespeichert ist (es sei denn, die Datei endet exakt auf einer Blockgrenze).

Mapping der Einträge

Dem ReiserFS voran steht ein Informationsblock, der die notwendigen Angaben zum Auffinden des Journals und des Rootknotens enthält. Wenn ein Zugriff auf eine Datei erfolgt, wird diese zunächst in einer Hashtabelle gesucht. Ist die Blocknummer zu dieser Datei dort nicht enthalten, beginnt die Suche immer im Rootblock des Dateisystems. dumpreiserfs bringt die Strukturen des Dateisystems ans Licht:

root@sonne> dumpreiserfs /dev/hda3

<-----------DUMPREISERFS, 2000----------->
ReiserFS version 3.5.23
0x3:0x7's super block in block 16
======================
Reiserfs version 0
Block count 787176
Blocksize 4096
Free blocks 454227
Busy blocks (skipped 16, bitmaps - 25, journal blocks - 8193
1 super blocks, 324714 data blocks
Root block 11598
Journal block (first?) 18
Journal dev 0
Journal orig size 8192
Filesystem state ERROR
Tree height 4

Das Ext3-Dateisystem

Bei der enormen Verbreitung des ext2-Dateisystems war es nur eine logische Konsequenz, dieses um die modernen Fähigkeiten eines Journaling Dateisystems nachzurüsten. Mit ext3, das ab Version 2.4.16 offiziell in den Kernel Einzug hielt, steht ein Dateisystem zur Verfügung, das zu 100% kompatibel mit allen Werkzeugen rund um das Dateisystem ext2 ist. Jedes ext2-Dateisystem kann ohne Risiko in ein ext3-System konvertiert werden (und umgekehrt), sodass Sie selbst bestehenden Dateisysteme ohne Neuinstallation die Journaling-Fähigkeit verleihen können.

Das Prinzip

Journaling meint im Allgemeinen die Protokollierung der Änderungen im Dateisystem. Im Speziellen können jedoch Änderungen an den Metadaten (Informationen zu einer Datei) und den Dateien (Inhalt der Dateien) gesondert behandelt werden. Das ext3-Dateisystem unterstützt deshalb gleich drei Journaling-Modi, die sich aus den Kombinationen dieser Handhabungen ergeben:

journal
         Änderungen an Metadaten und Dateien werden protokolliert. Dies ist die sicherste aber auch langsamte Journaling-Methode des ext3.
ordered
         Änderungen an Metadaten werden protokolliert. Geänderte Dateien, deren Metadaten dies betrifft, werden zuvor gesichert (flush). Dies ist die Voreinstellung des ext3. Im Unterschied zu »journal« schließt dieser Modus den Verlust von Änderungen in Datei nicht aus, garantiert jedoch zu jedem Zeitpunkt die Konsistenz des Dateisystems.
writeback
         Nur die Änderungen an Metadaten werden protokolliert. Änderungen an zugehörigen Dateien werden nur mit den Standard-Verfahren auf die Platte geschrieben (also normalerweise aller 30 Sekunden). Ist ist durchaus ein inkonsistender Zustand möglich. Falls bspw. eine Datei neue Datenblö:cke anfordert, werden diese in den Metadaten unverzüglich vermerkt. Die Blöcke selbst werden jedoch erst beim folgenden Sync-Zyklus mit sinnvollen Werten beschrieben.

Wenn Sie sich Vorteile davon versprechen, einen anderen als den Default-Journaling-Modus zu verwenden, dann müssen Sie nur beim Mounten des Dateisystems den gewünschten Modus angeben:

root@sonne> mount -t ext3 -o data=writeback /dev/hdb9 /mnt

 

Spezielle Dateisysteme

Logical Volume Manager

Wie oft haben Sie Linux bereits neu installiert und im Nachhinein dennoch fest gestellt, dass die von Ihnen gewählte Plattenpartitionierung doch nicht so optimal war? Sprengen die Daten nun die eine Partition?

Mit ein paar Handgriffen könnten Sie die Daten via Links auf andere Partitionen auslagern oder aber Sie könnten die Platte umpartitionieren. Eine Neuinstallation ist Dank geeigneter Programme nicht zwangsläufig notwendig.

Aber was, wenn diese Maßnahmen Ihren öffentlichen Webserver betreffen? Können Sie die notwendigen Wartungs- und Stillstandzeiten den Besuchern Ihrer Webseite zumuten?

Verschlüsselte Dateisysteme

RAM-Dateisysteme

Das Device-Dateisystem

Einrichten eines Dateisystems

Bevor ein Speichermedium Daten aufnehmen kann, muss dieses dafür eingerichtet werden (Ausnahme ist die Verwendung von Programmen wie tar, die auf unformatierte Medien schreiben können). Während Linux nahezu jedes Dateisystem einbinden kann, stehen zum Formatieren nur Hilfsmittel für bestimmte Dateisysteme zur Verfügung. Zu jeder Standardinstallation gehören Werkzeuge zum Anlegen von ext2/ext3-, SCO-, bfs-, Minix- und FAT-Dateisystemen. Darüber hinaus liegt dem Paket des ReiserFS ein eigenes Werkzeug bei. Auch das Einrichten einer Swap-Partition und -Datei soll in diesem Zusammenhang diskutiert werden.

Zum Erzeugen eines Dateisystems dient das Kommando mkfs, dem der konkrete Typ als Argument -t Dateisystemtyp mitzuteilen ist. Fehlt die Angabe, wird immer ext2 angelegt. mkfs ist nur ein Frontend und ruft seinerseits die dateisystemspezifischen Kommandos (z.B. mkfs.ext2) auf. In den Beispielen werden wir nur diese verwenden. Auch spezifizieren wir das zu formatierende Dateisystem über seine Gerätedatei (Device).

Anlegen eines ext2-Dateisystems

Aufruf:   mke2fs [OPTIONEN] DEVICE [BLÖCKE]

DEVICE ist das zu formatierende Gerät (aus /dev/) und BLÖCKE ist nur anzugegeben, wenn die Kapazität des Mediums nicht erkannt werden kann oder falls Sie - aus welchem Grund auch immer - weniger Blöcke als möglich sind anzulegen gedenken.

Schon wichtiger sind die Optionen -c zum vorherigen Überprüfen des Speichermediums und -l Datei zur Angabe einer Datei, die die Nummern fehlerhafter Blöcke enthält (siehe auch unter Prüfen eines Dateisystems).

Sowohl Inode-Anzahl als auch die Blockgröße versucht mke2fs automatisch anhand der Kapazität zu kalkulieren. Interessant ist hierbei die Verwendung der Option -T Verwendungszweck, die dem Kommando weitere Informationen über die Art der vornehmlich zu speichernden Daten liefert. Derzeit wird einzig »news« unterstützt (Newsartikel haben die Eigenschaft sehr kurz zu sein (< 1k), so dass eine kleine Blockgröße bei einer hohen Inodedichte angebracht erscheint). Ihnen Anwender steht selbstverständlich frei, sämtliche Parameter selbst zu bestimmen. So setzt -N Anzahl die Anzahl der Inodes, -b Blockgröße die Größe der einzelnen Datenblöcke (1024, 2048 oder 4096) und -i Anzahl weist »mke2fs« an, auf einem x Bytes großen Medium x/Anzahl Inodes zu erzeugen.

Von den zahlreichen Optionen benötigen Sie in der Praxis am ehestens noch -n, das die Formatierung nur simuliert, das Medium selbst aber unbehelligt lässt. Weiterhin unterdrückt ein -q sämtliche Ausgaben (wichtig in Skripten); -m Prozent setzt die prozentuale Größe an reserviertem Speicherplatz, der nur von Root verwendet werden kann (Schutzmaßnahme vor Überlauf des Dateisystems!) und -S schreibt letztlich nur Superblock und die Gruppendeskriptoren neu.

Als Beispiel formatieren wir eine Diskette mit dem ext2, wobei die Reservierung für den Administrator abgeschaltet wird. Da wir weniger als 100 Dateien zu speichern gedenken, beschränken wir die Inode-Anzahl diesbezüglich:

root@sonne> mke2fs -N 100 -m 0 /dev/fd0
mke2fs 1.26 (3-Feb-2002)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
104 inodes, 1440 blocks
0 blocks (0.00%) reserved for the super user
First data block=1
1 block group
8192 blocks per group, 8192 fragments per group
104 inodes per group

Writing inode tables: done
Writing superblocks and filesystem accounting information: done

Anlegen eines ext3-Dateisystems

Da ext3 eine Erweiterung zum ext2-Dateisystem darstellt, fügten die Entwickler einfach zum Kommando »mke2fs« einige neue Optionen hinzu anstatt ein eigenständiges Programm zu schreiben. Die unter »Anlegen eines ext2-Dateisystems« beschriebenen Parameter von »mke2fs« stehen somit auch für das ext3-System zur Verfügung.

Verwenden Sie für »mke2fs« die Option -j, so wird automatisch ein ext3-Dateisystem mit Journal und Voreinstellungen (Journalgröße in Abhängigkeit von der Dateisystemgröße) generiert:

root@sonne> mke2fs -j /dev/ram0
mke2fs 1.26 (3-Feb-2002) Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
16000 inodes, 64000 blocks
3200 blocks (5.00%) reserved for the super user
First data block=1
8 block groups
8192 blocks per group, 8192 fragments per group
2000 inodes per group
Superblock backups stored on blocks:
        8193, 24577, 40961, 57345

Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 21 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.

Konvertierung ext2 ext3

Existieren auf Ihrem System ext2-Dateisysteme, so können Sie diesen ohne Probleme die Fähigkeiten des Journaling beibringen und in ein ext3 wandeln.

Voraussetzungen sind, das zum Einen der Kernel ext3 unterstützt und zum Anderen noch »ausreichend« Speicherplatz zum Anlegen des Journals zur Verfügung steht.

Der für das Journal mindestens erforderliche Speicherplatz richtet sich nach der verwendeten Blockgröße. Das Minimum liegt bei 1024 und das Maximum bei 102400 Blöcken. Im Falle von 1k-Blöcke benötigen Sie also mindesten 1MByte freie Kapazität; bei 4k-Blöcken sind es schon 4MByte.

Folgender Aufruf konvertiert ein ext2-Dateisystem (auf /dev/hda1) nach ext3 bei Verwendung der Standardoptionen:

root@sonne> tune2fs -j /dev/hda1
tune2fs 1.28 (31-Aug-2002)
Creating journal inode: done
This filesystem will be automatically checked every 100 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.

Die tatsächliche Größe des Journals richtet sich neben der Blockgröße nach dem bei der Konvertierung vorhandenem Speicherplatz. Beabsichtigen Sie dessen Größe selbst festzulegen, müssen Sie auf anstatt »-j« die Option »-J size=Gröszlig;e« verwenden.

Für den Fall, dass der Speicherplatz auf der zu konvertierenden Partition nicht mehr ausreicht, können Sie für das Journal eine eigene Partition verwenden. Diese Partition muss zuvor als Journal eingerichtet worden sein. Ihre Blockgröße muss der der zu konvertierenden Partition entsprechen!

root@sonne> mke2fs -0 journal_dev /dev/hdb7
mke2fs 1.28 (31-Aug-2002)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
0 inodes, 12360 blocks
...
root@sonne> tune2fs -J device=/dev/hdb7 /dev/hda1
...

Auch die Wandlung eines ext3- in ein ext2-Dateisystem ist möglich. Das zu konvertierende Dateisystem ist hierzu abzuhängen oder als nur-lesend einzuhängen (Letzteres demonstriert das Beispiel).

root@sonne> umount /dev/hda1
root@sonne> mount /dev/hda1 /mnt -o ro
root@sonne> tune2fs -O ^has_journal /dev/hda1
tune2fs 1.28 (31-Aug-2002)

Anlegen eines Minix-Dateisystems

Aufruf:   mkfs.minix [OPTIONEN] DEVICE

Das Anlegen eines Minix-Dateisystems könnte höchstens für Disketten von Vorteil sein, da der Speicherverbrauch durch die Verwaltungsstrukturen geringer ausfällt als beim "ext2", so dass effektiv geringfügig (<30 kByte) mehr Kapazität zur Aufnahme der Daten zur Verfügung steht.

Im Falle von Disketten kann ein vorheriger Test des Mediums nicht schaden. Die Option -c gibt eine Liste fehlerhafter Blöcke aus, die beim anschließenden Formatieren ausgeblendet werden. Diese Blöcke lassen sich auch in einer Datei speichern, so dass ein nächster Durchlauf die Informationen über -l Datei aus dieser entnehmen könnte.

In der Voreinstellung gestattet Minix 30 Zeichen lange Dateinamen, dies kann mit der Option -n Länge auf 14 Zeichen beschränkt werden. Andere Längen sind nicht zulässig.

Die Anzahl anzulegender Inodes wird anhand des verfügbaren Speicherplatzes berechnet. Minix kalkuliert mit 3 Datenblöcken (immer 1k groß) für eine Datei, so dass die Anzahl Inodes für die meisten Fälle viel zu hoch gegriffen ist und mittels -i Anzahl reduziert werden kann. Als Beispiel formatieren wir eine Diskette:

root@sonne> mkfs.minix -c /dev/fd0
480 inodes
1440 blocks
Firstdatazone=19 (19)
Zonesize=1024
Maxsize=268966912

160 ...320 ...480 ...640 ...800 ...960 ...1120 ...1296 ...

Anlegen des SCO-bfs

Aufruf:   mkfs.bfs [OPTIONEN] DEVICE

Aus Gründen der Vollständigkeit soll auch dieses Dateisystem beschrieben sein, das standardmäßig in SCO-Unix Verwendung findet. Als Option ist nur -N Anzahl interessant, um die automatische Kalkulation der Inode-Anzahl auszusetzen. Zulässige Werte liegen dabei zwischen 48 und 512. Das Kommando selbst tätigt nur im Fehlerfall Ausgaben, es muss erst mit -v zu etwas mehr Auskunft überredet werden.

Das folgende Beispiel legt auf einer Diskette ein SCO-Dateisystem mit 100 Inodes an:

root@sonne> mkfs.bfs -N 100 -v /dev/fd0
Device: /dev/fd0
Volume: <      >
FSname: <      >
BlockSize: 512
Inodes: 100 (in 13 blocks)
Blocks: 2880
Inode end: 6911, Data end: 1474559

Anlegen eines FAT-Dateisystems

Aufruf:   mkdosfs [OPTIONEN] DEVICE [BLÖCKE]

Aus Effizienzgründen wird man wohl niemals ein FAT-Dateisystem als echtes Medium für eine Linux-Installation in Betracht ziehen, aber im Falle des Datenaustauschs mit einem Windows-System (vornehmlich NT, da es mit dem Beschreiben von Ntfs arge Probleme gibt) kann eine FAT-formatierte Partition oder Diskette durchaus nützlich sein.

Wie bereits bei ext2 und Minix beschrieben, versteht auch das Kommando mkdosfs die Optionen -c und -l Datei, um eine Überprüfung auf fehlerhafte Blöcke vorzunehmen bzw. um die Liste defekter Sektoren aus einer Datei zu lesen.

Um ein FAT32-System zu erzeugen, muss dem Kommando die Größe der File Allocation Table explizit mitgeteilt werden -F 32, anderenfalls werden in Abhängigkeit des Mediums 12 Bit (z.B. Disketten) oder 16 Bit (Festplatten) veranschlagt. Per Voreinstellung werden zwei FATs pro System abgelegt (falls eine zerstört wird, kann die zweite verwendet werden), mit -f Anzahl kann die Anzahl modifiziert werden (derzeit sind nur 1 oder 2 zulässig).

Schließlich kann die Anzahl von möglichen Einträgen im Wurzelverzeichnis modifiziert werden, was bei großen Festplatten (Voreinstellung 512) durchaus erforderlich sein könnte: -r Anzahl. Wie viele Sektoren einem Cluster zugeordnet werden, regelt die Option -s Anzahl, wobei nur Werte 2x, x=0,1,2,... gestattet sind.

Das Beispiel verwendet wieder die Diskette, wobei diese mit FAT32 bei nur einer Tabelle formatiert wird. Als Label soll das Dateisystem "DOS" erhalten. Die erweiterte Ausgabe bringt erst die Option -v ans Licht:

root@sonne> mkdosfs -F 32 -v -f 1 -n DOS /dev/fd0
mkdosfs 0.4, 27th February 1997 for MS-DOS/FAT/FAT32 FS
/dev/fd0 has 2 heads and 18 sectors per track,
using 0xf0 media descriptor, with 2880 sectors;
file system has 1 32-bit FAT and 1 sector per cluster.
FAT size is 23 sectors, and provides 2825 clusters.
Volume ID is 3992a22e, volume label DOS      .

Anlegen eines ReiserFS

Aufruf:   mkreiserfs [ OPTIONEN ] DEVICE [ ANZAHL_BLÖCKE ]

Die Werkzeuge zur Handhabung des ReiserFS liegen derzeit den wenigsten Distributionen (bei SuSE ab Version 6.4) bei, deswegen sollte man sich sowohl das Paket der Utilities (reiserfs-version) als auch den notwendigen Kernelpatch aus dem Internet besorgen. Der nächste Schritt ist das Einspielen des Patches in die Kernelsourcen und die Erzeugung desselben mit Unterstützung für das ReisferFS.

Da derzeit als Blockgröße einzig 4 kByte unterstützt werden, reduzieren sich die Optionen auf eine optionale Angabe der Anzahl anzulegender Blöcke (das macht eigentlich wenig Sinn, da mkreiserfs diese anhand der Partitionsgröße selbstständig berechnen kann) und eines Hash-Namens, der zur Sortierung der Dateinamen eingesetzt wird. Bei letzterem sind allerdings auch nur "tea" oder "rupasov" zulässig.

Zusammengefasst, reduziert sich die Liste der Argumente in den meisten Fällen auf den Namen des Devices (aufgrund der Größe des Journals erfordert ReiserFS eine mindestens 10MByte große Partition):

root@sonne> mkreiserfs /dev/hdb3

<-----------MKREISERFS, 2000----------->
ReiserFS version 3.5.23
Block size 4096 bytes
Block count 69048
First 16 blocks skipped
Super block is in 16
Bitmap blocks are :
17, 32768, 65536
Journal size 8192 (blocks 18-8210 of device 0x3:0x43)
Root block 8211
Used 8214 blocks
Hash function "tea"
ATTENTION: ALL DATA WILL BE LOST ON '/dev/hdb3'! (y/n)y
Initializing journal - 0%....20%....40%....60%....80%....100%
Syncing..

ReiserFS core development sponsored by SuSE Labs (suse.com)

Journaling sponsored by MP3.com.

To learn about the programmers and ReiserFS, please go to
http://www.devlinux.com/namesys

Have fun.

Sowohl der Kernel als auch die Daten des Bootmanagers dürfen nicht auf einer mit ReiserFS formatierten Partition liegen, da der Bootmanager dieses nicht lesen kann!

Einrichten von Swap

Jedes Programm, das von Linux abgearbeitet werden soll, muss in den Arbeitsspeicher (RAM) geladen werden. Linux führt aber zahlreiche Programme quasi parallel aus und jedes dieser Programme muss somit im RAM seinen Platz finden. Irgendwann wird der Arbeitsspeicher knapp... Und nun?

"Kein Speicher - kein Programm", so einfach ist die Regel und Linux weist jeden weiteren Programmstart mit dem Ausspruch Out of virtual memory. ab. Uns als Administratoren bleiben nun mehrere Möglichkeiten offen:

  1. Wir "killen" nicht benötigte Prozesse, um Speicher frei zu bekommen
  2. Wir spendieren dem Rechner mehr RAM
  3. Wir erzeugen "virtuellen Speicher"

Erstere Variante scheidet schon aus, da unser System möglichst problemlos ohne Aufsicht laufen soll. Vermutlich benötigen wir auch alle anderen Prozesse, so dass wir keinen "abschießen" mögen...

Die zweite Möglichkeit scheitert meist am Geld... und in 99% der Fälle genügt ja der installierte Arbeitsspeicher... Muss ich wirklich nur für die seltenen Situationen diesen aufstocken?

Die Lösung: Wir verwenden einfach einen Teil der Festplatte als "Verlängerung" des RAM. Linux trägt nun selbst Sorge, dass die Daten des jeweils benötigten Prozesses im physischen RAM liegen und Speicherseiten, die im Augenblick keine Verwendung finden, im Bereich des "virtuellen RAM" auf der Festplatte gehalten werden.

Meist wurde während der Installation bereits eine eigene Swap-Partition erzeugt, so dass ein nachträgliches Einrichten nicht notwendig wird. Was aber, wenn Sie feststellen, dass sich die "Out of virtual memory" häufen?

Steht Ihnen noch eine freie Partition auf einer Festplatte zur Verfügung, können Sie diese für den virtuellen Swap verwenden. Allerdings darf die Größe einer einzelnen Partition 2GB (bei Kerneln <2.1.117 128MB) nicht übersteigen (im Abschnitt Installation finden Sie nähere Informationen).

Das folgende Beispiel demonstriert die Schritte zum Einrichten einer Swap-Partition. Es wird angenommen, dass die Partition »/dev/hdb1« (100 MB) frei ist. Vorsicht: Der Inhalt der Partition wird rigoros überschrieben, vergewissern Sie sich, dass die von Ihnen auserwählte Partition tatsächlich nicht andersweitig verwendet wird!

  1. Zuerst muss die Partition als Swap-Bereich eingerichtet werden. Hierzu verwendet man das Kommando mkswap, dem als Argument das Device übergeben wird. Das Kommando verwendet den gesamten verfügbaren Speicher, maximal jedoch 128 MB. Um größere Partitionen komplett zu nutzen, muss die Option -v1 verwendet werden. Durch Angabe der Anzahl 1k-Blöcke als letztes Argument kann die Größe weiter beschränkt werden.

    root@sonne> mkswap /dev/hdb1
    Swapbereich Version 0 mit der Größe 104857600 Bytes wird angelegt
  2. Zu diesem Zeitpunkt existiert zwar die Swap-Partition, aber Linux weiß davon noch nichts. Dem System muss die Existenz erst mit dem Kommando swapon mitgeteilt werden.

    root@sonne> swapon /dev/hdb1
    Um in Zukunft den Befehl nicht immer von Hand ausführen zu müssen, können Sie eine Zeile der Art
    /dev/hdb1    none    swap    sw    0    0


    in die Datei /etc/fstab aufnehmen. Bereits nach dem Systemstart steht Ihnen die Swap-Partition zur Verfügung (Achtung: ohne entsprechenden Patch können Sie maximal 8 solcher Swap-Partitionen auf diese Weise verwenden).
  3. Ein aktivierter Swap-Bereich kann auch aus dem laufenden System entfernt werden. Rufen Sie hierzu einfach den Befehl swapoff auf.

    root@sonne> swapoff /dev/hdb1

Eine Swap-Datei sollte nur als Notlösung in Betracht gezogen werden, wenn bspw. keine Partition für den Swap mehr zur Verfügung steht. Ein Zugriff auf eine Datei erfordert immer den Umweg über das Dateisystem und ist somit langsamer als ein Zugriff auf eine Swap-Partition. Zunächst müssen Sie eine Datei der gewünschten Größe anlegen:

root@sonne> dd if=/dev/zero of=mein_swap_file bs=1024 count=102400
1024+0 records in
1024+0 records out

Im Beispiel wird mit Hilfe von dd eine 100MB große Datei »mein_swap_file« angelegt und mit Nullen beschrieben. Mit dieser Datei ist nun wie bei einer Swap-Partition beschrieben zu verfahren. Ersetzen Sie in den jeweiligen Zeilen den Device- durch den Datei-Namen.

Prüfen eines Dateisystems

Die Oberflächenbeschaffenheit des Mediums

In diesem Zusammenhang möchte ich mit einer Überprüfung der physischen Unversehrtheit des Speichermedium beginnen, da zumeist ein beschädigter Block Ursache für einen Fehler im Dateisystem ist.

Um »schlechte« Blöcke auf einer Diskette oder Festplatte festzustellen, verwendet man das Kommando badblocks.

Aufruf:   badblocks [ OPTIONEN ] DEVICE BLÖCKE [STARTBLOCK]

DEVICE steht dabei für den Gerätenamen des Mediums und mit BLÖCKE ist die Anzahl der zu untersuchenden Datenblöcke auf dem Medium anzugeben. Optional kann mit STARTBLOCK der erste zu testende Block spezifiziert werden.

Mit der Option -b Blockgröße kann die Anzahl Bytes je Block angegeben werden. Dies ist nur notwendig, wenn beim Einrichten des Dateisystems eine von der Voreinstellung abweichende Größe gewählt wurde. Mit -o Datei wird die Liste der beschädigten Blöcke in eine Datei geschrieben, die von einigen Programmen zum Einrichten eines Dateisystems verwendet werden kann. Des Weiteren kann das Fortschreiten der Überprüfung mit der Option -s beobachtet werden und -w nimmt gleichzeitig einen Schreibtest auf den Blöcken vor. Wenden Sie letzte Option nur auf unformatierte Medien an, eventuell darauf befindliche Daten sind anschließend pfutsch!

Als Beispiel soll eine 1.44MB-Diskette überprüft werden. Das Ergebnis des Tests wird in einer Datei »kaputt« gespeichert:

root@sonne> badblocks -s -o kaputt /dev/fd0 1440
Checking for bad blocks (read-only test): done

Die Integrität des Dateisystems

Untersuchen und - mit Einschränkungen - Reparieren lassen sich derzeit (aus Linux heraus) nur die Dateisysteme ext2, Minix und ReiserFS. Für beide erstere ist fsck zu verwenden, das wiederum ein Frontend ist und die Aufrufe der Kommandos fsck.ext2 und fsck.minix in Abhängigkeit vom verwendeten Dateisystem veranlasst. fsck sucht die Kommandos allerdings zunächst in bestimmten Verzeichnissen und befolgt nur falls dort es nicht fündig wird die Regeln der PATH-Variablen. Ein ReiserFS überprüft das Kommando reiserfsck. Laut dessen Manual ist der Einsatz wegen des Journals ohnehin nicht notwendig und zum anderen - auch auf Grund mangelnder Erfahrungen - mit Vorsicht zu genießen. Wir werden darauf nicht näher eingehen.

fsck sollte immer auf nicht-gemountete oder read-only gemountete Dateisysteme angewendet werden, da das Programm mitunter das Dateisystem modifiziert, ohne dass das System dies realisiert. Ein Systemabsturz könnte die Folge sein...

e2fsck - Routineuntersuchungen

Eine defektes Dateisystem beschwört eine Menge Ärger herauf. Kein Wunder also, dass es zu den Gepflogenheiten zählt, während des Startvorgangs den Status der Dateisysteme zu überprüfen.

Die verschiedenen Distributionen haben den Aufruf

fsck -a -A

in einem der Startskripte eingebaut (Debian "/etc/init.d/checkfs.sh", RedHat "/etc/rc.d/rc.sysinit", SuSE "/etc/rc.d/boot"). Die Option -A veranlasst das Kommando, alle in der Datei /etc/fstab als "zu testen" gekennzeichneten Dateisysteme zu überprüfen. -a bewirkt, eine Reparatur ohne Interaktion mit dem Benutzer - sofern die Mängelbeseitigung keinen manuellen Eingriff bedingt.

Wohl jeder Linuxer ist während des Bootens schon einmal auf eine der folgenden Ausgaben gestoßen:

/dev/hda2 was not cleanly unmounted, check forced.
/dev/hda2 has reached maximal mount count, check forced.
/dev/hda2 has gone too long without beeing checked, check forced.

Solche Ausgaben sind ärgerlich, weil der nachfolgende Test doch einige Zeit in Anspruch nimmt, aber unkritisch, denn es handelt sich um reine Vorsichtsmaßnahmen.

Als Ursache der ersten Ausgabe entpuppt sich meist ein vorangegangenes Abschalten des Systems, ohne das Dateisystem korrekt per "umount" abgemeldet zu haben. Hier hilft nur, in Zukunft mit dem Abdrehen der Stromzufuhr zu warten, bis Linux das vollständige Herunterfahren signalisiert hat.

Mit der zweiten Ausschrift kündigt fsck an, dass das System schon sehr häufig gemountet wurde und sicherheitshalber eine Untersuchung vorgenommen wird. Der konkrete Wert der maximal erlaubten Mountvorgänge ohne zwischenzeitliche Überprüfung ist im Superblock des ext2 gespeichert und kann bei Bedarf modifiziert werden.

Ebenso eine reine Vorsichtsmaßnahme ist die Überprüfung, die die dritte Ausschrift ankündigt. Hier liegt der Zeitpunkt des letzten Tests schon weiter zurück, als es laut Informationen im Superblock zulässig ist. Da dieser Wert in der Voreinstellung allerdings ein halbes Jahr beträgt, werden die wenigsten Anwender in den Genuss (oder Frust) dieser Mitteilung gelangen.

e2fsck - Die Checkliste

e2fsck überprüft das Dateisystem in fünf Phasen:

  1. Überprüfung der Inodes, Blöcke und Dateigrößen. Hier durchlüäuft e2fsck die Liste aller Inodes und sucht nach ungültigen Einträgen. Typische Fehler sind ungültige Zugriffsrechte, falsche Dateigrößen oder der Verweis auf einen Datenblock, der bereits in der Blockliste eines anderen Inodes enthalten ist.
  2. Überprüfung der Verzeichnisstruktur. Alle Verzeichniseinträge werden nach ungültigen Inode-Einträgen (aus Phase 1) durchsucht.
  3. Überprüfung der Verbindungen zwischen den Verzeichnissen. Es wird getestet, ob jedes Verzeichnis erreichbar ist (es in einem Pfadeintrag ausgehend vom obersten Verzeichnis des Dateisystems erscheint). Verzeichnisse, die keine Verbindung aufweisen, werden gemeinsam mit den enthaltenen Dateien nach "/lost+found" verschoben.
  4. Überprüfung des Verweiszählers. Die in jedem Inode gespeicherte Anzahl Hardlinks wird mit den tatsächlich auf diesen Inode verweisenden festen Links verglichen.
  5. Überprüfung der Bitmaps. Die Inode- und Blockbitmaps werden entsprechend der (un)belegten Inodes und Blöcke korrigiert.

e2fsck - Reparaturen

Manchmal kommt es dann doch vor, dass fsck die zu treffenden Maßnahmen nicht allein entscheiden kann. Aber auch nach dem manuellen Start (ohne Argument »-a«) werden Reparaturen erst nach Bestätigung durch den Administrator ausgeführt.

Um einen Ernstfall zu simulieren, wurden mehrere Dateien auf eine ext2-formatierte Diskette kopiert und diese während des Schreibvorgangs entnommen. Der anschließende Testlauf von »e2fsck« ist im nachstehenden Listing dargestellt (die einzelnen Phasen wurden farblich markiert):

root@sonne> e2fsck /dev/fd0
e2fsck 1.18, 11-Nov-1999 for EXT2 FS 0.5b, 95/08/09
/dev/fd0 was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Inode 13 has illegal block(s). Clear<y>?[Enter]yes

Illegal block #-1 (808796998) in inode 13. CLEARED.
Illegal block #-1 (1010704950) in inode 13. CLEARED.
Illegal block #-1 (1699626562) in inode 13. CLEARED.
Illegal block #-1 (1702328948) in inode 13. CLEARED.
Illegal block #-1 (1394633586) in inode 13. CLEARED.
Illegal block #-1 (1701340009) in inode 13. CLEARED.
Illegal block #-1 (1768253554) in inode 13. CLEARED.
Illegal block #-1 (1110391924) in inode 13. CLEARED.
Illegal block #-1 (1714371646) in inode 13. CLEARED.
Illegal block #-1 (1047817839) in inode 13. CLEARED.
Illegal block #-1 (1046556476) in inode 13. CLEARED.
Too many illegal blocks in inode 13.
Clear inode<y>?[Enter]yes

Restarting e2fsck from the beginning...
/dev/fd0 was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Entry 'linuxfibel.tar.gz' in / (2) has deleted/unused inode 13. Clear<y>?[Enter]yes

Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Block bitmap differences: -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -1 145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221...
fix<y>?[Enter] yes

Free blocks count wrong for group #0 (941, counted=1321).
Fix<y>?[Enter] yes

Free blocks count wrong (941, counted=1321).
Fix<y>?[Enter] yes

Inode bitmap differences: -13
Fix<y>?[Enter] yes

Free inodes count wrong for group #0 (170, counted=171).
Fix<y>?[Enter] yes

Free inodes count wrong (170, counted=171).
Fix<y>?[Enter] yes


/dev/fd0: ***** FILE SYSTEM WAS MODIFIED *****
/dev/fd0: 13/184 files (0.0% non-contiguous), 119/1440 blocks
  • In Phase 1 wurden Fehler in den vom Inode 13 reservierten Blöcken erkannt. Nach Entfernen dieser Einträge stellte »e2fsck« weitere Ungereimtheiten fest und schlägt das Löschen dieser vollkommen unbrauchbaren Inodes vor. Nach Bestätigung beginnt das Kommando wiederum mit Phase 1.
  • In Phase 2 wird nun in einem Verzeichnis die Datei gefunden (linuxfibel.tar.gz), die durch den Inode 13 beschrieben wurde. Da dieser nicht mehr existiert, ist das Löschen des Eintrags die einzig logische Konsequenz.
  • Phase 3 und 4 bringen keine Fehler zum Vorschein (es wurden ja auch keine Verzeichnisse angelegt). Sollten in Phase 3 Mängel auftreten, bietet »e2fsck« an, die Dateien nach /lost+found zu verschieben. Sie sollten dies bejahen und anschließend die dortigen Dateien nach wichtigen Daten durchsuchen. Wenn Sie diese nicht mehr benötigen, löschen Sie sie.
  • Die Fehler in Phase 5 resultieren aus dem Reservieren von Datenblöcken beim Anlegen neuer Dateien (und dem einen gelöschten Inode). Durch den verhinderten Abschluss des Kopiervorgangs blieben wesentlich mehr Blöcke als belegt markiert, als tatsächlich verwendet wurden. Die Korrektur der Bitmaps sollte unkritisch sein.

Hartnäckige Fälle

Was tun, wenn e2fsck die Reparatur verweigert?

Bevor Sie weiter experimentieren, empfiehlt sich dringend ein Backup der entsprechenden Partition (mit einem Low-Level-Werkzeug wie dd).

Wir gehen nachfolgend von einer intakten Partitionstabelle aus; bzw. für den Fall deren Beschädigung, dass Sie diese exakt reproduzieren können. Des Weiteren ist zu vermuten, dass e2fsck nicht wegen einiger fehlerhafter Datenblöcke oder Inodes die Segel strich, sondern wegen Zerstörung einer oder mehrerer Gruppen (und damit der wichtigen Informationen zu Superblock und Gruppendeskriptoren). Die Struktur des ext2 ist zum Glück so angelegt, dass diese immens wichtigen Informationen redundant zu Beginn einer jeden Gruppe abgelegt sind. Es geht also darum, diese Blöcke zu restaurieren.

Ihr erster Versuch sollte sein, e2fsck explizit einen alternativen Superblock vor die Nase zu setzen:

root@sonne> fsck -b 8193 /dev/hda1

Obige Blocknummer entspräche dem Superblock der zweiten Gruppe bei 1k Blockgröße. Demzufolge läge die nächste Kopie bei 16385 usw. Bei 4k-Blöcken wäre die erste Kopie bei Blocknummer 32769 zu finden. Sie können mit den Werten getrost experimentieren, da e2fsck mit einem Fehler endet, falls keine gültigen Superblockinformationen im angegebenen Block gefunden wurden. Im Erfolgsfall ersetzt das Kommando abschließend den korrupten Superblock mit der angegebenem Kopie.

Versagt oberes Vorgehen, sollten Sie die exakten Formatierungsdaten der fehlerhaften Partition kennen. Haben Sie bei der Einrichtung des Dateisystems dem Kommando mke2fs die Berechnung der Parameter überlassen, können Sie dieses nun anweisen, einzig die Superblöcke und Gruppendeskriptoren neu zu schreiben:

root@sonne> mke2fs -S /dev/hda1

Bei ursprünglicher Vorgabe eigener Werte (Anzahl Inodes...) sind diese zusätzlich als Kommandozeilenparameter anzugeben!

Optimieren des ext2/ext3

Der DOS/Windows9X-Umsteiger denkt hier vermutlich in erster Linie an ein zur Defragmentierung analoges Vorgehen. Tatsächlich existiert ein Defragmentierungswerkzeug für »ext2«, jedoch haben Messungen gezeigt, dass der erzielte Leistungsgewinn den Nutzen ad absurdum führt. Die Strategie des »ext2« beim Anlegen neuer Dateien minimiert den Grad der Fragmentierung erstaunlich gut.

Dennoch lassen sich einzelne Parameter des ext2 mit Hilfe des Kommandos tune2fs manipulieren. Betrachten wir zuerst die Informationen, die »tune2fs« einem ext2-Dateisystem zu entlocken vermag:

root@sonne> tune2fs -l /dev/fd0
tune2fs 1.18, 11-Nov-1999 for EXT2 FS 0.5b, 95/08/09
Filesystem volume name:   <none>
Last mounted on:          <not available>
Filesystem UUID:          5a101826-f249-4a60-baad-ccfe2d66f0ed
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      filetype sparse_super
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              184
Block count:              1440
Reserved block count:     72
Free blocks:              1321
Free inodes:              171
First block:              1
Block size:               1024
Fragment size:            1024
Blocks per group:         8192
Fragments per group:      8192
Inodes per group:         184
Inode blocks per group:   23
Last mount time:          Tue Oct  3 09:09:13 2000
Last write time:          Tue Oct  3 09:15:58 2000
Mount count:              0
Maximum mount count:      20
Last checked:             Tue Oct  3 09:15:58 2000
Check interval:           15552000 (6 months)
Next check after:         Sun Apr  1 09:15:58 2001
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               128

Alle Informationen gewinnt »tune2fs« aus dem Superblock des Dateisystems. Die änderbaren Einträge wurden farblich hervorgehoben, deren Bedeutung/Änderung wir uns nachfolgend zuwenden.

sparse_super ist ein Flag, das erst ab Kernel > 2.1 bekannt ist. Ist dieses gesetzt, speichert das Dateisystem »dünn besetzte« Dateien - diese enthalten Blöcke, die nur aus 0-Bytes bestehen - optimiert, indem diese »0-Blöcke« keinen physikalischen Speicherplatz belegen (das Dateisystem merkt sich nur die Position solcher Blöcke). Das Flag kann mittels tune2fs -s <Device> umgeschalten werden. Da dies aber keinen Nutzen bringt, ist davon abzuraten.

Wenn beim Dateisystemcheck ein Fehler erkannt wurde, regelt der unter Errors behavior eingestellte Modus das weitere Vorgehen. Zulässig sind »continue« zum Fortfahren mit dem »normalen« Vorgehen, »remount-ro« zum nur-lesenden Mounten des Dateisystem oder »panic« zum Stoppen mit einer »kernel panic«.

root@sonne> tune2fs -e remount-ro /dev/hda2

Üblich ist, das Root-Dateisystem mit »remount-ro« und alle nicht zwingend notwendigen Dateisysteme mit »continue« zu versehen.

Reserved block count bezeichnet Datenblöcke, die einzig Root vorbehalten sind. D.h. aus Sicht jedes »normalen« Anwenders ist das Dateisystem um die Anzahl reservierter Blöcke kleiner als es die tatsächliche Speicherkapazität ist. Der Grund ist, dass zumindest Root noch mit dem Dateisystem arbeiten können muss, wenn es - warum auch immer - in seiner Kapazität erschöpft ist (um die Ursache zu beheben):

# Setzen der Anzahl reservierter Blöcke
root@sonne> tune2fs -r 100 /dev/fd0

# Setzen des prozentualen Anteils reservierter Blöcke (10%)
root@sonne> tune2fs -m 10 /dev/hda2

Mount count gibt die Anzahl der Mountvorgänge seit der letzten Dateisystemüberprüfung an und Maximum mount count beinhaltet die Anzahl Mountvorgänge, die ohne eine zwischenzeitliche Überprüfung zulässig sind (letzterer Wert ist sicherlich die sinnvollste »Optimierung« des ext2 uuml;berhaupt):

# Setzen der Anzahl Mountvorgänge
root@sonne> tune2fs -C 10 /dev/fd0

# Setzen der Anzahl maximal erlaubter Mountvorgänge
root@sonne> tune2fs -c 100 /dev/hda2

Check interval ist die zeitliche Spanne, die maximal zwischen zwei Überprüfungen verstreichen darf:

# Maximal 100 Tage
root@sonne> tune2fs -i 100d /dev/fd0

# Maximal 10 Wochen
root@sonne> tune2fs -i 10w /dev/hda2

# Maximal 12 Monate
root@sonne> tune2fs -i 12m /dev/hda2

Die letzten hier vorgestellten Modifikationen bestimmen die Benutzer Reserved blocks uid bzw. Gruppe Reserved blocks gid, die die reservierten Blöcke verwenden dürfen. Beide Werte dürfen sowohl symbolisch als auch numerisch angegeben werden:

Anmerkung zum ext3-Dateisystem

Die Journaling-Funktionalität garantiert die Datenkonsistenz. Somit sind die ext2-typischen Dateisystemprüfungen nicht notwendig und können abgeschaltet werden:

# Dateisystemprüfung deaktivieren
root@sonne> tune2fs -c 0 -i 0 /dev/hda2

 

# Gruppen 100 und root
root@sonne> tune2fs -g 100 -g root /dev/fd0

# Benutzer tux, user, root
root@sonne> tune2fs -u tux -u user -u root /dev/hda2

 

Mounten eines Dateisystems

Bevor ein Dateisystem unter Unix verwendet werden kann, muss es in die Verzeichnisstruktur integriert werden. Man bezeichnet diesen Vorgang als Mounten.

Wenn Linux bootet, benötigt der Kernel verschiedene Programme, um bspw. Tests und Initialisierungen vornehmen zu können oder verschiedene Dienste zu aktivieren. Diese Programme sind in einem Dateisystem auf einem permanenten Medium (meistens die Partition einer lokalen Festplatte) gespeichert. Um sie verwenden zu können, »mountet« der Kernel das Medium (also die Partition) als Rootverzeichnis.

Meist wird man allerdings das System nicht auf einer einzigen Festplattenpartition installiert haben, sondern es ist auf mehrere Partitionen oder Festplatten verteilt. Vielleicht sind Teile des Systems gar auf einem anderen Rechner im Netz gespeichert? Um auf das Dateisystem einer solchen Partitionen zugreifen zu können, muss ein im Rootverzeichnis vorhandener Verzeichniseintrag mit einer solchen Partition verbunden werden. Diese Verbindung stellt das Kommando mount her.

Es sollte klar sein, dass die Verwaltung der Dateisysteme allein dem Administrator obliegt; der Aufruf von mount Bedarf also immer Rootrechte mit einer Ausnahme, falls Root für bestimmte Dateisysteme (z.B. um den Zugriff auf Disketten oder CDROMs zu gestatten) den Benutzern das Mounten gestattet (siehe /etc/fstab).

Aufruf:   mount [OPTIONEN] Gerät Mountpunkt

Dem Kommando wird im Normalfall mitgeteilt, »was« zu mounten ist (Gerät) und in welchem Verzeichnis dieses eingehangen werden soll (Mountpunkt). Die Angabe der Optionen kann entfallen, wenn

  • das Dateisystem auf dem Gerät vom Kommando »erprobt« werden kann und des Weiteren die Voreinstellungen (abhängig vom Dateisystemtyp) gelten sollen
  • die fehlenden Optionen einem entsprechenden Eintrag der Datei /etc/fstab entnommen werden können.

»Entsprechender Eintrag« heißt, dass in der Datei eine Zeile existiert, die die Parameter zum Mounten dieses Gerätes auf diesen Mountpunkt beschreibt. Unter den beschriebenen Voraussetzungen ist es sogar zulässig, die Argumente von mount auf das Gerät oder den Mountpunkt zu beschränken.

Der Aufruf von mount ohne Argumente bringt alle momentan gemounteten Dateisysteme zum Vorschein:

user@sonne> mount
/dev/hdb3 on / type ext2 (rw)
proc on /proc type proc (rw)
/dev/hdb4 on /opt type ext2 (rw)
/dev/hdb1 on /boot type ext2 (rw)
/dev/hda2 on /home type ext2 (rw,usrquota)
devpts on /dev/pts type devpts (rw,gid=5,mode=0620)

Die wichtigsten Optionen, die mount für jeden Dateisystemtyp unterstützt, sind:

-a
         Mounten aller in der Datei /etc/fstab aufgeführten Dateisysteme, sofern für diese nicht die Option noauto angegeben wurde. Wird optional der Dateisystemtyp angegeben (-t fstype), so werden nur solche Geräte gemountet.
-r
         Dateisystem wird »read-only« eingehangen (Schreiben verboten).
-w
         Dateisystem wird »read-write« eingehangen (Schreiben und Lesen erlaubt).
-t vstype
         Angabe des Typs des zu mountenden Dateisystems. Dies ist nur notwendig, falls der Kernel anhand des Superblocks den konkreten Typ nicht ermitteln kann.
-o Optionen
         Kommaseparierte Liste von Optionen, siehe nachfolgende Tabelle.

Eigenschaften wie das Dateisystem zu mounten ist, werden durch »-o« eingeleitet. Bei vorangestelltem »no« (»noauto«, »nodev«...) werden die Eigenschaften negiert (es gibt aber kein »noremount«, »noro« und »norw«!). Die wichtigsten Angaben sind:

-o async
         Ein- und Ausgaben auf dem Dateisystem erfolgen asynchron (bspw. werden Daten zwischengespeichert (»gecached«) und zyklisch geschrieben).
-o atime
         Die Zugriffszeit einer Datei wird bei jedem Zugriff aktualisiert (im Inode).
-o auto
         Automatisches Mounten (nur als Option in der Datei /etc/fstab sinnvoll).
-o defaults
         Voreingestellte Optionen verwenden ( rw, suid, dev, exec, auto, nouser, async).
-o dev
         Devices des zu mountenden Dateisystem werden auch als solche interpretiert.
-o exec
         Ausführen von Programmen erlaubt.
-o remount
         Zum erneuten Mounten eines schon eingehangenen Dateisystems.
-o ro
         Nur Leseberechtigung.
-o rw
         Lese- und Schreibberechtigung.
-o suid
         »suid«-Bits behalten ihre Wirkung
-o sync
         Alle Ein- und Ausgaben erfolgen synchron (ohne Zwischenpufferung).
-o user
         Dateisystem darf von normalen Benutzern gemountet werden (Angabe ist nur in der Datei /etc/fstab sinnvoll).

Im Zusammenhang mit dem Network File System und mit Samba werden Sie einige dateisystemspezifische Optionen des Kommandos kennen lernen. An dieser Stelle möchten wir nur auf das Mapping der Nutzerkennungen auf Windows- und DOS-Laufwerken hinweisen. Da diese die Unix-Rechte nicht kennen, werden in der Voreinstellung sowohl die Benutzerkennung als auch die Gruppenkennung aller Dateien eines solchen Dateisystems auf den Wert der Rechte des Prozesses gesetzt, der den »mount«-Befehl ausführt (startet Root das Kommando, erhält der Prozess dessen Rechte...). Um dennoch allen Benutzern das Schreiben auf einer solchen Partition zu gestatten, muss als Option "umask=000" angegeben werden. Um das Schreiben einem bestimmten Benutzer/Gruppe zu gestatten, lassen sich die Dateien mit "uid=<UID_des_Nutzer>" bzw. "gid=<GID_der_Gruppe>" dem Benutzer/der Gruppe gezielt zuordnen.

Die Datei /etc/fstab

Die Datei /etc/fstab enthält Parameter über das (permanente) Dateisystem. Hier werden die schon beim Systemstart zu mountenden Dateisysteme aufgeführt und alle Dateisysteme, die z.B. auch von einem normalen Nutzer zum System hinzugefügt bzw. aus dem System entfernt werden dürfen.

Jedes Dateisystem wird durch eine eigene Zeile beschrieben; anhand einer typischen /etc/fstab betrachten wir die wichtigsten Einträge (mit einem Doppelkreuz beginnende Zeilen sind Kommentare):

user@sonne> cat /etc/fstab
# Root-Dateisystem
/dev/hda1    /            ext2         defaults       1   1
# Das Verzeichnis /usr erhält eine eigene Partition
/dev/hdb2    /usr         ext2         defaults       1   2
# Die Swap-Partition
/dev/hda3    swap         swap         defaults       0   0

# ATAPI-Cdrom und Disketten-LW
/dev/hdc     /cdrom       iso9660      ro,noauto,user 0   0
/dev/fd0     /floppy      auto         noauto,user    0   0

# Das Prozessdateisystem
proc         /proc        proc         defaults       0   0

# Ein NFS-Verzeichnis
erde.galaxis.de:/home/nfs /mnt/nfs    nfs    defaults    0   0

Drei der Einträge dieser Beispieldatei sind für alle Systeme zu empfehlen:

Zeile 1: Betrifft das Root-Dateisystem (notwendig)
Zeile 3: Einbinden einer Swap-Partition (optional)
Zeile 8: Einbinden des Prozessdateisystems (notwendig)

Alle weiteren Zeilen sind optional. Jede Zeile besteht aus 6 Spalten, die im Einzelnen folgende Bedeutung besitzen:

Device Mountpunkt Type Options Dump Check

Die Einträge bedeuten:

Device
         Blockdevice oder entferntes Dateisystem, welches zu mounten ist
Mountpunkt
         Verzeichniseintrag, in dem das Dateisystem erscheinen soll
Type
         Typ des Dateisystems (auto steht für automatische Erkennung bei Diskettenlaufwerken)
Options
         Optionen (siehe nachfolgende Tabelle)
Dump
         Gibt an, ob das Dateisystem vom Kommando dump zu sichern ist. Dieser Eintrag wird derzeit nur beim Dateisystemtyp ext2 bewertet.
Check
         Gibt an, ob das Dateisystem vor dem Mounten zu überprüfen ist. Beim Root-Dateisystem sollte hier eine "1" stehen und bei allen anderen entweder eine "0" (keine Prüfung) oder eine "2". Dateisysteme mit gleicher Nummer werden parallel überprüft, das Root-Dateisystem sollte immer allein und als erstes getestet werden.

Mit den Optionen kann der Mount-Vorgang gesteuert werden (Auswahl):

defaults
         Voreinstellungen (rw, suid, auto, nouser...)
noauto
         Kein automatisches Mounten beim Booten
user
         Device darf von normalen Nutzern gemountet werden
ro, rw
         read only, read write
exec
         Ausführung von Binaries gestattet
sync
         Ungepuffertes Schreiben

 

Die Datei /etc/mtab

Alle momentan gemounteten Dateisysteme sind in der Datei /etc/mtab gespeichert:

user@sonne> cat /etc/mtab
/dev/hda5 / ext2 rw 0 0
proc /proc proc rw 0 0
/dev/hda4 /opt ext2 rw 0 0
/dev/hda3 /usr ext2 rw 0 0
/dev/hda7 /home ext2 rw 0 0
devpts /dev/pts devpts rw,gid=5,mode=0620 0 0

Bei vorhandenem Prozessdateisystem wird die Information zusätzlich in der Datei "/proc/mounts" gehalten. Das Kommando "mount" wertet jedoch nur "/etc/mtab" aus.

Der Automounter

Die Flexibilität des Unix-Mount-Konzepts offenbart sich dem Administrator spätestens, wenn er dem expandierenden System eine neue Platte spendiert und Teile der bestehenden Installation nachträglich auf diese auslagert. Sicherlich erfordert eine solche Maßnahme fundierte Kenntnisse und trickreiche Kniffe, aber so ist es möglich, einem vollgestopften System ohne Neuinstallation Freiraum zur Arbeit zu verschaffen.

Andererseits vermisst der Linux-Neuling die einfache Handhabung beim Zugriff auf eine Diskette oder CDROM wohl schmerzlich. Diskette rein, Laufwerk mounten, ins betreffende Verzeichnis wechseln, Datei bearbeiten, Verzeichnis verlassen, Diskette unmounten - und das ganze Prozedere wiederholt sich mit der nächsten Magnetscheibe.

Aber der umständlichen Verfahrensweise mit Wechselmedien entsprang weniger die Motivation zur Entwicklung des Kernel-Automounters, der bei Bedarf, sprich beim Zugriff auf ein Dateisystem, dieses »im Hintergrund« mountet und - bei Nichtverwendung und Ablauf einer konfigurierbaren Zeitspanne auch wieder selbsttätig abhängt. Wichtigster Grund war wohl die beschränkte Anzahl gleichzeitig gemounteter Dateisysteme, die in großen Netzwerken rasch zu Engpässen führt(e). Im Zusammenhang mit dem Import von NFS-Verzeichnissen ist das automatische Unmounten bei Nichtbedarf ein positiver Nebeneffekt, um unnütze Mounts nach einem Server- oder Netzwerkcrash zu entfernen.

Einrichten des Kernel-Automounters

Die beiden Voraussetzungen zur Verwendung des Automounters sind das installierte Paket (autofs-version-nummer.rpm) und die Unterstützung durch den Kernel (FilesystemsKernel automounter support).

  1. Der Systemverwalter legt nun eine Datei /etc/auto.master an, die Zeilen mit jeweils dem Namen eines einzelnen Mountpunkts (existierendes Verzeichnis) und dem Namen einer Konfigurationsdatei enthält, die eine Beschreibung der unter diesem Mountpunkt zu montierenden Dateisysteme beinhaltet. Ein optionaler dritter Parameter kann Mount-Optionen enthalten, die für alle Dateisysteme gelten (oft wird hier die Zeitspanne angegeben, nach der der Automounter versuchen soll, das Dateisystem abzuhängen):

    root@sonne> vi /etc/auto.master
    # Unterhalb von /mnt sollen das lokale CDROM und das Floppy gemountet werden; beide sollen nach 60 Sekunden automatisch abgehangen werden
    /mnt   /etc/auto.local   --timeout 60

    # Unterhalb von /home sollen die Heimatverzeichnisse erscheinen
    /home  /etc/auto.homes
  2. Die Konfigurationsdateien zu den jeweiligen Mountpunkts enthalten für jedes zu mountende Dateisystem eine eigene Zeile bestehend aus:

    <Name des Mountpunkts> <Mount-Optionen> [Rechner]:<Device>


    Name des Mountpunkts bezeichnet das nicht-existente (!) Verzeichnis, das unterhalb vom in /etc/auto.master genannten Mountpunkt zur Aufnahme des Dateisystems dient. Die Mount-Optionen entsprechen denen des Kommandos mount und Device ist bei lokalen Dateisystemen der Name der Gerätedatei (die Angabe eines Rechnernamens entfällt) und bei Dateisystemen, die von einem anderen Rechner importiert werden, der dortige Mountpunkt.

    root@sonne> vi /etc/auto.local
    cdrom   -fstype=iso9660,ro,user  :/dev/cdrom
    floppy  -fstype=auto,rw,user     :/dev/fd0


    Im Beispiel lautet der vollständige Mountpunkt für das CDROM-Laufwerk »/mnt/cdrom« und für das Disketten-Laufwerk »/mnt/floppy«.

    Die Einträge der Datei /etc/auto.homes sollen das Importieren von einem NFS-Server demonstrieren:

    root@sonne> vi /etc/auto.home
    tux   -fstype=nfs,rw,no_squash_all  erde:/home/tux
    user  -fstype=nfs,rw,no_squash_all  erde:/home/user


  3. Die vom Automounter zu verwaltenden Dateisysteme müssen diesem nun bekannt gegeben werden. Hierzu sollte ein Skript autofs im Verzeichnis der Init-Skripte existieren. Dieses Skript wertet die oben beschriebenen Konfigurationsdateien aus, extrahiert die Parameter und ruft das Kommando automount mit diesen auf. In einem SuSE-System sähe der Aufruf wie folgt aus:

    root@sonne> /sbin/init.d/autofs start
    Starting service automounter                                    done


  4. Den aktuellen Zustand des Automounters kann der Systemverwalter ebenfalls mittels des »autofs«-Skripts erfragen:

    root@sonne> /sbin/init.d/autofs status
    Checking for service autofs: OK
    Configured Mount Points:
    ------------------------
    automount -t 300 /mnt file /etc/auto.local -timeout 60
    automount -t 300 /home file /etc/auto.homes

    Active Mount Points:
    --------------------
    automount -t 300 /mnt file /etc/auto.local -timeout 60


    Soll der Automounter nach jedem Systemstart zur Verfügung stehen, sind die entsprechenden Links in den jeweiligen Runleveln zu erzeugen.

Zugriff auf ein »Automount-Verzeichnis«

Ein erster Blick in das Verzeichnis »/mnt« bringt nichts zu Tage:

user@sonne> ls /mnt

Zu jenem Zeitpunkt kennt (hoffentlich) der Kernel zwar die Mountpunkts, aber das Anhängen des Dateisystems geschieht erst mit dem ersten Zugriff auf dieses selbst:

user@sonne> ls /mnt/floppy
linuxfibel.tar.gz TODO.txt Automount.gz
user@sonne> ls /mnt
floppy

Der Sinn des Automounters liegt ja gerade darin, dass er ein Dateisystem nur im Falle des Zugriffs mountet. Allerdings bringt dies auch Probleme mit sich:

  • Man muss den Namen des Mountpunkts genau kennen
  • Ein Kommando wie find kann ein Verzeichnis erst durchsuchen, nachdem es gemountet wurde (ein »find« auf ein nicht-lokales Dateisystem kann mitunter mit sehr langen Laufzeiten aufwarten; vor »versehentlichem« Durchsuchen schützt die Option »-xdev«)
  • Der Mountvorgang bringt eine Verzögerung mit sich

Automatisches und manuelles Unmounten

Mit jedem Zugriff auf ein vom Automounter verwaltetes Dateisystem wird ein zugehöriger Timer neu gestartet. Erreicht dieser einen bestimmten Wert, so versucht der Automounter, das Dateisystem selbsttätig abzuhängen. In der Voreinstellung steht die Zeitspanne auf 5 Minuten, wird aber häufig in den Konfigurationsdateien und/oder im »autofs«-Skript auf einen geringeren Wert gesetzt.

Es kann allerdings vorkommen, dass ein Benutzer binnen kürzerer Zeit die Diskette wechseln will, was ein manuelles »Unmounten« dieser bedingt. Prinzipiell ist dies auf drei Wegen möglich:

  • Der Wert des Timeouts wird sehr klein gewählt. Allerdings nimmt man damit die Verzögerung beim Zugriff in Kauf, da das Dateisystem womöglich zu früh abgehangen wurde und nun erneut zu mounten ist.
  • Dem normalen Benutzer wird das (Un)Mounten gestattet. Das Problem ist, dass nun jeder die Berechtigung dazu besitzt.
  • Der Automounter wird über das Signal SIGUSR1 explizit zum Unmounten aller derzeit möglichen Dateisysteme gezwungen. Allerdings bedarf das Versenden des Signales Rootrechte. Solche können bestimmten Benutzern komfortabel mit Hilfe des Kommandos sudo eingeräumt werden.

Anmerkung: Ein Unmounten ist nicht möglich, wenn sich irgend jemand innerhalb des abzuhängenden Dateisystems befindet oder eine Datei aus diesem eröffnet hat.

 
 
 
 Korrekturen, Hinweise?    
Startseite Nächste Seite Nächstes Kapitel Vorherige Seite Kapitelanfang