2.2 Der erste Kontakt mit dem System
In diesem Abschnitt wollen wir uns mit dem ersten Kontakt mit einem Linux-System beschäftigen. Der »erste Kontakt« kann natürlich ein Thema nicht umfassend behandeln, daher werden wir später noch ausführlich auf einzelne Punkte eingehen.
Jedoch muss man an einer Stelle anfangen und eine Basis für spätere Kapitel schaffen.
2.2.1 Booten
Beginnen wir mit dem Start des Systems. Egal ob bei einer Installation auf Festplatte oder dem Laden einer Live-Distribution wie Knoppix, das Geschehen ist eigentlich immer gleich. Im BIOS wird festgelegt, auf welchen Medien in welcher Reihenfolge nach einem zu bootenden Betriebssystem gesucht werden soll. Dabei kann mittlerweile sogar von exotischen Geräten wie USB-Sticks gestartet werden, wobei die meisten Anwender doch lieber bei CD/DVD-Laufwerken und natürlich Festplatten bleiben.
Die ersten 512 Byte
Wird nun auf einem der im BIOS angegebenen Bootlaufwerke ein zu startendes Betriebssystem gefunden, wird dies auch geladen.
Auf allen bootfähigen Medien wird nämlich nach einem gültigen MBR (Master Boot Record) gesucht, das ist zum Beispiel bei einer Festplatte immer der erste Sektor (= 512 Bytes) der Festplatte. Dieser Master Boot Record enthält dabei folgende Informationen:
- Bootloader
- Der Bootloader besteht aus Code zum Laden eines Betriebssystems oder weiteren Bootloadercodes. Damit von diesem Medium gebootet werden kann, muss dieser Code gültig sein und ein Betriebssystem laden können.
- Partitionstabelle
- Die Partitionstabelle gibt an, welche Partitionen wo auf dem Medium vorhanden sind. Die Partitionstabelle besteht aus vier Einträgen zu je 16 Byte und ist damit insgesamt 64 Byte groß. Sie liegt relativ am Ende der Partitionstabelle bei Byte 446.
- Magic Number
Bootfähige Medien erkennen
Die fehlenden 2 Byte <Die Partitionstabelle beginnt bei Byte 446 und ist 64 Byte lang – das ergibt 510 von 512 im MBR zur Verfügung stehenden Bytes.> bis zum Ende des Sektors werden nun mit einem Wert gefüllt, anhand dessen das BIOS nun entscheiden kann, ob es sich um ein bootbares Medium handelt oder nicht: Ist der Wert 55AAHex, so kann der Code am Anfang des MBR geladen werden. Ändert man diesen Wert, wird das Medium nicht als bootfähig erkannt.Unter Linux kann man sich den MBR mit folgenden Befehlen ansehen, wobei das Gerät /dev/sda </dev/hda bei älteren Distributionen, die noch nicht die libata verwenden.> die erste Festplatte im System bezeichnet, <Die Gerätenamen sind einer der zahlreichen kleinen Unterschiede zwischen den einzelnen Unix-Derivaten wie Linux und BSD.> von dem in unserem Beispiel der MBR gezogen werden soll:
# dd if=/dev/sda of=mbr.img count=1 bs=512 # od -x mbr.img
Listing 2.1 Extrahieren und Betrachten des MBR
Sehen wir uns jedoch den Bootvorgang weiter an: Hat man nun ein Linux auf seinem System installiert, so wird mit ziemlicher Sicherheit ein Bootloader wie grub geladen. In einem solchen Bootmanager kann man zwischen allen auf diesem Medium installierten Betriebssystemen das zu startende auswählen.
Der erste Prozess: init
Als Nächstes wird dann der Kernel geladen, der das System schließlich langsam initialisiert und mit init auch den ersten Prozess des Userlandes explizit startet. Dieser Prozess übernimmt dann das eigentliche Starten des Systems, indem dafür vorgesehene Konfigurationsdateien ausgelesen und entsprechende Dienste im Hintergrund gestartet werden.
Dabei werden von init verschiedene Systemkonfigurationen, sogenannte Runlevel, unterschieden. Je nach Runlevel werden unterschiedliche Dienste gestartet. So gibt es zum Beispiel bei den meisten Systemen einen Runlevel mit grafischer Oberfläche und einen ohne. Auch gibt es bestimmte Runlevel zum Herunterfahren (Level 0) und Neustarten (Level 6) des Systems.
2.2.2 Das Login
Auch die Login-Dienste der Textoberfläche – realisiert durch das Programm (m)getty – werden von init gestartet. Je nach Runlevel kann aber auch ein grafischer Login-Dienst wie der gdm oder der kdm gestartet sein. In jedem Fall wird der Nutzer aufgefordert, sich mit einem Usernamen und einem Passwort einzuloggen, damit er am System arbeiten kann.
Netzwerk- transparenz
Das Login ist dabei wieder ein typisches Beispiel für die Netzwerktransparenz: Normalerweise wird bei der Anmeldung eines Benutzers überprüft, ob sein Benutzername in der /etc/passwd verzeichnet ist und mit seinem Passwort in der /etc/shadow unter Linux beziehungsweise der /etc/master.passwd unter BSD übereinstimmt. Setzt man im Netzwerk jedoch Dienste wie NIS/NIS+ oder LDAP ein, kann man ein Unix-System überreden, die Benutzerinformationen von einem solchen zentralen Server zu laden – der Anwender selbst merkt nichts. Verbindet man dieses Feature noch geschickt mit dem Einsatz von NFS, kann einem Anwender so auf jedem System der Firma die gleiche Arbeitsumgebung zur Verfügung gestellt werden.
2.2.3 Das Arbeiten am System
Das Home- verzeichnis
Nach dem Einloggen kann man am System arbeiten. Je nach Aufgabenspektrum oder Präferenz kann dies in verschiedenen Umgebungen erfolgen. Auch die verwendeten Programme werden stark variieren. Eines ist jedoch für alle Benutzer gleich:
Der Ort ihrer Arbeit und der Platz zum Speichern wichtiger Daten ist jeweils das Heimatverzeichnis (engl. »home directory«, im Deutschen oft auch Homeverzeichnis genannt).
Unter Linux und BSD besitzt jeder Benutzer sein eigenes Verzeichnis innerhalb des /home-Verzeichnisses, wohingegen dieses Verzeichnis unter anderen Unix-Systemen zum Beispiel auch unterhalb des /usr-Verzeichnis liegen kann. Im Normalfall hat der Benutzer nur in seinem eigenen Verzeichnis das Recht, Dateien anzulegen, zu ändern und zu löschen. <Ja, von Spezialfällen wie dem Verzeichnis für temporäre Dateien /tmp einmal abgesehen.> Dafür besitzt er dann aber dort auch Narren- und Gestaltungsfreiheit. Wie dort die Daten organisiert werden, steht jedem Benutzer absolut frei.
Dateien verstecken
Auch alle Programme, die dies möchten, können Dateien im jeweiligen Verzeichnis des Benutzers ablegen. Im Regelfall sind diese Dateien und Verzeichnisse jedoch »versteckt«, werden also bei einem normalen Betrachten des Verzeichnisses nicht angezeigt. Solche versteckten Dateien beginnen alle mit einem Punkt und können natürlich unter Angabe spezieller Optionen angezeigt werden. In diesem Sinne sind die Dateien also nicht versteckt, sondern werden im Normalfall schlicht ausgeblendet, um dem Benutzer einen besseren Überblick über die von ihm selbst angelegten und bearbeiteten Dateien zu geben.
Die Verzeichnisstruktur
Wie Sie bereits wissen, besitzt Linux ein virtuelles Dateisystem, das von physikalischen Speichermedien auf eine Verzeichnisstruktur abstrahiert. Doch auch diese Verzeichnisstruktur selbst ist interessant, da sich das zugrunde liegende Konzept von anderen nicht Unix-artigen Betriebssystemen unterscheidet.
Klassifikation
Im Folgenden wollen wir die wichtigsten Verzeichnisse sowie ihre Bedeutung kurz erläutern. Dazu müssen aber vorher einige Begriffe geklärt werden, mit denen die Daten später klassifiziert werden:
Dateien sind »shareable«, wenn sie auf einem Rechner im Netzwerk gespeichert und auch auf anderen Rechnern genutzt werden können. Ein gutes Beispiel dafür sind die Dateien in den Homeverzeichnissen der User, wogegen der Zugriff auf Systemressourcen kontrollierende Lockfiles eben nicht shareable – also »unshareable« – ist.
Wie man sieht, spielt die Netzwerktransparenz also auch beim Dateisystem eine Rolle. Doch auch die Frage, wann und wie Daten verändert werden, ist für das Dateisystemlayout wichtig:
Dateien sind »statisch« (engl. »static«), wenn sie nicht ohne die Intervention des Administrators geändert werden können. Im Gegensatz dazu stehen »variable«, also veränderbare Daten.
Typische Beispiele für statische, also im Normalfall nicht schreibbare Daten sind Programmbinaries, Dokumentation oder Systembibliotheken. Veränderbare Dateien wären zum Beispiel Logfiles, temporäre Dateien oder natürlich auch Datenbanken.
Doch beginnen wir mit den wichtigsten Verzeichnissen und ihrer Bedeutung:
- /bin
- Dieses Verzeichnis beinhaltet essenzielle (Shell-)Programme. Diese sind statisch und durchaus shareable.
- /boot
Der Kernel
Das /boot-Verzeichnis beinhaltet alle wichtigen Dateien zum Hochfahren des Systems, wozu natürlich vor allem der Kernel gehört. Diese Dateien sind im Allgemeinen statisch und nicht shareable, da sie durch verschiedene Treiber und die Konfiguration sehr systemspezifisch sind.
- /dev
- In diesem Verzeichnis finden sich die Gerätedateien. Je nach Kernel-Version und eingesetzter Technik kann dieses Verzeichnis aber nur virtuell sein. <Zum Beispiel beim mittlerweile obsoleten devfs.>
- /etc
- Jegliche Konfigurationsdateien eines Systems sollten sich in dessen /etc-Verzeichnis befinden. Da sich eine Konfiguration selten selbst ändert, sind auch diese Daten statisch und aufgrund des personalisierenden Charakters einer Konfiguration eher als unshareable einzustufen. <Natürlich hindert Sie niemand daran, das /etc-Verzeichnis im Netzwerk freizugeben. Inwieweit das sinnvoll ist, ist allerdings eine andere Frage -- und nur darauf bezieht sich die »unshareable«-Aussage.>
- /home
- Das Homeverzeichnis eines Users unter /home/username haben wir Ihnen bereits vorgestellt. Hier werden die eingeloggten Benutzer in der Regel arbeiten.
- /lib
- In diesem Verzeichnis finden sich alle essenziellen Bibliotheken. In /lib/modules/ <kernelversion>
- finden sich so auch die Module, die zur Laufzeit dynamisch in den Kernel geladen werden können.
- /mnt
- In /mnt sollten Wechseldatenträger wie CD-ROMs, DVDs oder USB-Sticks gemountet werden. Früher wurden dafür oft direkt Verzeichnisse unter / genutzt, was jedoch dem Konsens über die Verzeichnisstruktur widerspricht.
- /opt
- Damit Softwarepakete auch von Drittanbietern ins System integriert werden können, gibt es das opt-Verzeichnis. Dort sollten entsprechend dem Firmen- oder Softwarenamen Unterverzeichnisse angelegt werden, in denen dann die jeweilige Software installiert werden kann.
- /proc (nur Linux)
- Im /proc-Verzeichnis findet sich ein gemountetes virtuelles Dateisystem, in dem sich Informationen über alle Prozesse und das System generell abrufen lassen. Dieses Verzeichnis finden Sie allerdings nicht unbedingt auf jedem System.
- /root
- Dies ist das Homeverzeichnis von root. Da man als root nicht direkt am System arbeiten sollte, wird dieses Verzeichnis recht selten genutzt werden.
- /sbin
- In diesem Verzeichnis finden sich essenzielle Systembinaries.
- /tmp
- Dies ist das Verzeichnis für temporäre Daten. Im Regelfall werden während des Bootens alte, von der letzten Sitzung zurückgebliebene Dateien gelöscht.
- /usr
- Die /usr-Hierarchie ist die größte und wichtigste Ansammlung statischer, sharebarer Daten. Die wichtigsten Unterverzeichnisse finden Sie hier:
- /usr/X11R6/:
Verzeichnis für die grafische Oberfläche X11
- /usr/bin/:
Benutzerprogramme (Binaries)
- /usr/include/:
Standardverzeichnis für Include-Dateien <Siehe auch das Kapitel 22 zur Programmierung.>
- /usr/lib/:
Bibliotheken für Benutzerprogramme
- /usr/local/:
Extra-Hierarchie für selbstkompilierte Software
- /usr/sbin/:
Nicht-essenzielle Systemprogramme
- /usr/share/:
Architekturunabhängige Daten <Diese Daten müssen wie alle Daten in /usr »read-only«, also statisch, sein.>
- /usr/src/:
Verzeichnis für Sourcecode (optional)
-
- Aus den Charakteristika dieser Daten ergibt sich die Möglichkeit, das /usr-Verzeichnis auf eine eigene Partition zu legen, es read-only zu mounten <Beim Aktualisieren des Systems muss dann natürlich ein Remount mit möglichem Schreibzugriff erfolgen, da sonst zum Beispiel keine Binaries ersetzt werden können.> sowie es schließlich im Netzwerk freizugeben und auf anderen Systemen zu mounten.
- /var
- Das /var-Verzeichnis besitzt ähnlich wie /usr eine ganze Hierarchie von Unterverzeichnissen mit speziellen Aufgaben. Im Gegensatz zu diesem sind die Daten in /var jedoch variabel und im Allgemeinen nicht shareable.
- /var/cache/:
Anwendungsspezifische Cachedaten
- /var/lib/:
Variable Statusinformationen
- /var/local/:
Variable Daten für /usr/local
- /var/lock/:
Lockdateien <Diese Dateien stellen den exklusiven Zugriff auf bestimmte Ressourcen sicher: Ist eine bestimmte Datei vorhanden, ist die zugehörige Ressource belegt. Erst nach dem Löschen der Datei kann wieder versucht werden, die Ressource anzufordern.>
- /var/log/:
Logdateien
- /var/opt/:
Variable Daten für /opt
- /var/run/:
Für laufende Prozesse relevante Daten <Soll zum Beispiel ein Programm wie ein bestimmter Serverdienst nur einmal gestartet werden können, kann in /var/run eine Datei mit der Prozess-ID abgelegt werden. Beim einem versuchten zweiten Start des Programms kann dieses anhand der Datei nun feststellen, dass es schon läuft, und daher den Start verweigern.>
- /var/spool/:
Spooling-Daten wie beispielsweise zu druckende Dateien oder noch nicht abgeholte Mails
- /var/tmp/:
Temporäre Dateien, die nicht bei einem Reboot gelöscht werden sollten
-
- Auch bei /var kann sich die Speicherung der Daten auf einer eigenen Partition beziehungsweise Platte anbieten, um bei knapper werdendem Plattenplatz immer noch etwas Platz auf der Rootpartition zu halten und damit ein funktionierendes System gewährleisten zu können.
Mit Ausnahme des Homeverzeichnisses wird man mit diesen Verzeichnissen in aller Regel jedoch nur als Administrator zu tun haben. Das liegt vor allem am Rechtesystem, da bis auf die temporären Verzeichnisse ein normaler Benutzer nur in sein Homeverzeichnis schreiben kann.
Das Rechtesystem
Dieser Zustand ist sinnvoll, da so kein normaler Benutzer das System manipulieren oder umkonfigurieren kann. Wir wollen im Zusammenhang mit dem Rechtesystem als Erstes natürlich die Rechte etwas näher betrachten, die einem Benutzer gewährt oder nicht gewährt werden können:
- Write
- Das Schreibrecht. Hat ein Benutzer dieses Recht auf eine Datei, so kann er sie zum Schreiben öffnen oder sie auch löschen. Diese Berechtigung wird sinnvollerweise fast nur für eigene Dateien im Heimatverzeichnis des Benutzers benötigt und ist daher auch nur dort gesetzt. Auf Verzeichnissen bewirkt dieses Recht, dass ein Benutzer dort Dateien anlegen und löschen kann.
- Read
- Das Leserecht. Dieses Recht erlaubt es einem Benutzer, lesend auf entsprechende Dateien zuzugreifen. Die Benutzer haben dieses Recht für die meisten Systemdateien wie Programme oder Dokumentation. Nur in Ausnahmefällen wie bei wichtigen Passwortdateien bekommen normale Benutzer dieses Recht nicht zugesprochen.
- Execute
- Dateien mit diesem Rechte-Flag können ausgeführt werden. Entweder handelt es sich bei diesen Dateien um binäre Formate wie ELF oder um Skriptdateien bestimmter Sprachen wie Bash oder Perl. Bei Letzteren muss jedoch in der ersten Zeile des Skripts der Interpreter genannt werden, mit dem die Datei ausgeführt werden kann. Das Rechte-Bit wird dabei in erster Linie verwendet, um zwischen Programmen und Daten zu differenzieren, jedoch seltener, um festzulegen, wer ein bestimmtes Programm ausführen darf und wer nicht.
- Auf Verzeichnissen besitzt dieses Bit eine etwas andere Semantik: Dort wird nämlich durch das x-Flag der Zugriff auf ein Verzeichnis gesteuert. Wem dieses Flag nicht gewährt wird, dem bleibt das Wechseln in den entsprechenden Ordner verwehrt.
Werden diese Rechte nun auf Dateien beziehungsweise Verzeichnisse vergeben, so müssen sich von einer bestimmten Rechtemaske auf einer Datei die Berechtigungen für jeden möglichen Benutzer ableiten lassen. Jedem Benutzer ist im System daher eine Benutzer-ID (UID) und mindestens eine Gruppen-ID (GID) zugeordnet. Eine Datei wird nun auch einem Benutzer – nämlich dem Eigentümer beziehungsweise dem Ersteller der Datei – sowie einer Gruppe zugeordnet.
Für den Rechtekontext bedeutet dies, dass man jeweils eine Rechtemaske setzen kann, die aus je einem Bit für Read, Write und Execute für den Eigentümer, die Gruppe und schließlich noch für den Rest der Welt besteht. Möchte ein Benutzer nun auf eine Datei zugreifen, so wird zuerst geprüft, ob er der Eigentümer der Datei ist. Ist dies der Fall, so wird die entsprechende Rechtemaske zur Prüfung der Gültigkeit des geforderten Zugriffs herangezogen. Ist der Benutzer nicht der Eigentümer, so wird geprüft, ob er in der Gruppe der Datei ist, um dann eventuell die Rechtemaske der Gruppe heranzuziehen. Ist auch das nicht der Fall, werden automatisch die Rechte für den Rest der Welt aktiv.
root
Der Superuser
Eine Ausnahme in diesem Rechtekontext bildet der Benutzer root mit der UID 0, der immer auf alle Dateien Zugriff hat. Er ist, vom Eigentümer einer Datei abgesehen, auch der Einzige, der die Rechte auf eine Datei ändern kann.
Dieser Superuser ist in der Regel der Administrator des Systems und hat sozusagen die absolute Macht durch den unbeschränkten Zugriff auf alle Dateien. Und wie man spätestens seit Spider-Man weiß: Mit großer Macht kommt große Verantwortung.
Rechte und Hardware
Rechte werden jedoch nur auf Dateien oder Verzeichnisse vergeben. Da jedoch zum Beispiel Geräte und bestimmte Ressourcen als Dateien im System repräsentiert sind und Unix an sich generell sehr dateiorientiert ist, ergibt sich so wieder ein konsistentes Gesamtbild.
Auch sollte erwähnt werden, dass es problemlos möglich ist, mit mehreren Benutzern zur selben Zeit an einem System zu arbeiten. Natürlich ist ein PC in der Regel nur mit einem Bildschirm und nur einer Grafikkarte <Auch wenn man Linux durchaus so konfigurieren kann, dass zwei Grafikkarten und zwei Tastaturen für insgesamt zwei Benutzer zur Verfügung stehen.> ausgestattet, jedoch kann zum Beispiel über den SSH-Dienst das Remote-Arbeiten, also ausgehend von anderen Rechnern im Netzwerk, ermöglicht werden.
2.2.4 Das Herunterfahren
Ein weiterer wichtiger Schritt im ersten Kontakt mit dem System ist das Herunterfahren. Wie heutzutage eigentlich bei allen komplexeren Systemen üblich, kann man ein System nicht an einer beliebigen Stelle einfach von dessen Stromquelle trennen. Damit man das System in einem konsistenten Zustand halten kann, müssen
- alle Programme ihre temporären Daten speichern,
- alle verwendeten Ressourcen freigegeben und
- das Dateisystem in einem konsistenten Zustand hinterlassen werden.
Puffer und Caches leeren
Vor allem die Problematik des Dateisystems ist offensichtlich, wenn man sich an das letzte Kapitel und den Fakt erinnert, dass viele Daten zwischengespeichert und gepuffert werden, um die Performance des Systems zu erhöhen. Werden diese gepufferten Daten nicht zurückgeschrieben oder wird die Festplatte vielleicht sogar inmitten eines Schreibvorgangs unterbrochen, tritt ein Datenverlust auf oder es kommt zu inkonsistenten (Meta-)Daten auf der Festplatte.
Ein System herunterfahren und solche Probleme vermeiden kann man mit dem Befehl shutdown:
- shutdown -h now
- Mit diesem Befehl hält man das System an. Dazu wird das System in den Runlevel 0 überführt, wobei alle gestarteten Dienste beendet werden. Schließlich werden alle verbleibenden Prozesse über ein SIGTERM aufgefordert, sich zu beenden, um sie dann nach kurzer Zeit mit einem SIGKILL auf die »harte Tour« durch den Kernel zu beenden.
- Die Prozesse werden extra beendet, damit alle offenen Dateien noch geschlossen werden können. Würde man diese im Prozesskontrollblock vermerkten Daten ignorieren, würden eventuell bisher nur gepufferte Schreibzugriffe nicht ausgeführt und so verloren gehen.
- shutdown -r now
- Mit diesem Befehl wird das System neu gestartet (engl. reboot) und dazu in den Runlevel 6
- überführt. Ansonsten entsprechen alle Aktionen, vom Herunterfahren der beim Systemstart von init aktivierten Dienste bis zum Senden der Signale an alle Prozesse, dem Vorgehen beim Systemhalt.
Natürlich muss man diese Befehle nicht auf der Shell eingeben, sondern kann auch von einer grafischen Oberfläche wie KDE aus ein System herunterfahren. Allerdings hat man auf der Shell die Möglichkeit, anstatt von »now« auch einen genauen Zeitpunkt anzugeben, zu dem das System heruntergefahren oder neu gestartet wird. Auch kann man hier eine Nachricht angeben, die vor der shutdown-Aktion an alle eingeloggten Nutzer gesendet wird.