Betriebssysteme
Transcription
Betriebssysteme
Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Alois Schütte 25. April 2016 1 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Inhaltsverzeichnis In diesem Teil wird in die Thematik der Betriebssysteme eingeführt. 1 Überblick 2 Was ist ein Betriebssystem 3 Historische Betrachtung 4 Grundlegende Konzepte 5 Systemaufrufe 6 Betriebssystemstrukturen 2 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Vorlesung & Praktika • Vorlesung im Hörsaal mit Hörsaalübungen • Hörsaalübungen und Fragen in der Vorlesung bilden Grundlage für die Klausur 3 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Vorlesung & Praktika • Vorlesung im Hörsaal mit Hörsaalübungen • Hörsaalübungen und Fragen in der Vorlesung bilden Grundlage für die Klausur • Skript reicht aus, ergänzend für Interessierte: ’Tannenbaum: Moderne Betriebssysteme, ISBN 978-3-8632-6561-8’ 3 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Vorlesung & Praktika • Vorlesung im Hörsaal mit Hörsaalübungen • Hörsaalübungen und Fragen in der Vorlesung bilden Grundlage für die Klausur • Skript reicht aus, ergänzend für Interessierte: ’Tannenbaum: Moderne Betriebssysteme, ISBN 978-3-8632-6561-8’ • Praktikum in D14/310 mit VM auf iMacs 3 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Vorlesung & Praktika • Vorlesung im Hörsaal mit Hörsaalübungen • Hörsaalübungen und Fragen in der Vorlesung bilden Grundlage für die Klausur • Skript reicht aus, ergänzend für Interessierte: ’Tannenbaum: Moderne Betriebssysteme, ISBN 978-3-8632-6561-8’ • Praktikum in D14/310 mit VM auf iMacs • Testat nur innerhalb der VM → VirtualBox 3 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Vorlesung & Praktika • Vorlesung im Hörsaal mit Hörsaalübungen • Hörsaalübungen und Fragen in der Vorlesung bilden Grundlage für die Klausur • Skript reicht aus, ergänzend für Interessierte: ’Tannenbaum: Moderne Betriebssysteme, ISBN 978-3-8632-6561-8’ • Praktikum in D14/310 mit VM auf iMacs • Testat nur innerhalb der VM → VirtualBox 3 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Fragen und Feedback Für die Veranstaltung können Sie Fragen und Kommentare und auch Live Feedback anonym abgeben. Dazu wird die Software ARSnova des Kollegen Klaus Quibeldey-Cirkel verwendet. Im Browser bitte https://arsnova.eu/mobile/#id/19226584 eingeben, oder im Smartphone den QR-Kode verwenden: Bitte versuchen Sie es. 4 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Überblick Überblick Software kann grob in zwei Arten eingeteilt werden: • Systemsoftware, die den Rechner selbst steuert und • Anwenderprogramme, die die Aufgaben der Anwender lösen. Das wichtigste Systemprogramm ist das Betriebssystem, es • kontrolliert die Ressourcen des Rechners und • ist Basis für die Entwicklung der Anwenderprogramme. 5 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Überblick Ein moderner Rechner besteht u.a. aus den Komponenten: • ein oder mehrere Prozessoren, • Hauptspeicher, • Taktgeneratoren, • Datenendgeräte, • Plattenlaufwerke, • Netzwerkkomponenten und • DFÜ Einrichtungen. Insgesamt also eine komplexe Hardware. 6 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Überblick Schichtenmodell • Ziel der Systemprogrammierung ist es, die Anwender vor der Komplexität der Hardware zu bewahren. • Um der Komplexität Herr zu werden, kann man Rechner in Schichten einteilen. SAP Office Compiler Editoren Betriebssystem Anwendungsprogramme ... Shells Systemprogramme • Das Betriebssystem ist eine Softwareschicht oberhalb der Hardware, bedient alle Teile des Systems und stellt dem Anwender eine virtuelle Maschine bereit, die einfach zu verstehen und zu bedienen ist. Maschinensprache Mikroprogrammierung Hardware physikalische Geräte 7 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Was ist ein Betriebssystem Betriebssystem als virtuelle Maschine • Rechner sind auf Maschinenebene umständlich zu programmieren. Soll ein Text auf der Festplatte gespeichert werden, muss man auf Maschinenebene die Struktur des Speichermediums (Spuren, Sektoren, ...) und die Maschinenbefehle zum Positionieren des Lese/Schreibkopfes kennen. • Ein Anwendungsprogrammierer soll sich mit solchen Details der physischen Geräte nicht kümmern. Er erwartet von einem Betriebssystem eine virtuelle Maschine“, auf der er dateiorientiert ” Lesen und Schreiben kann. 8 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Was ist ein Betriebssystem Betriebssystem als Ressourcenverwalter • Heutige Rechner sind leistungsfähig genug, um mehreren Benutzern Zugriff auf angeschlossene Drucker, Modems oder Prozessoren zu geben. Damit unterschiedliche Benutzer die selben Ressourcen gleichzeitig“ nutzen können, sind Verwaltungsaufgaben ” erforderlich. • Ein Betriebssystem übernimmt die Verwaltung der unterschiedlichen an den Rechner angeschlossenen Geräte und der Bestandteile des Rechners selbst, wie Hauptspeicher oder Prozessoren. 9 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Historische Betrachtung 1 Überblick 2 Was ist ein Betriebssystem 3 Historische Betrachtung Erste Generation: Röhrenrechner (1945-1955) Zweite Generation: Transistoren und Stapelsysteme (1955-1965) Dritte Generation: Multiprogrammierung (1965-1980) Vierte Generation: Personalcomputer (seit 1980) Netzwerk-Betriebssysteme und Verteilte Systeme 4 Grundlegende Konzepte 5 Systemaufrufe 6 Betriebssystemstrukturen 10 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung analytical engine Der erste digitale Rechner wurde von dem englischen Mathematiker Charles Babbage (17921871) entworfen. • Seine analytical engine“ funktionierte nie, ” denn ihr rein mechanischer Aufbau ließen die Fertigung mit der erforderlichen Präzision damals nicht zu. • Programmiert wurde in Assembler; es war die erste Turing-vollständige Programmiersprache. • Dennoch, dieser Rechner wäre ohne Abbildung: analytical engine Betriebssystem ausgekommen. 11 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Erste Generation: Röhrenrechner (1945-1955) Erste Generation: Röhrenrechner (1945-1955) Der erste brauchbare digitale Rechner wurde im zweiten Weltkrieg entwickelt, die trotz ihre Größe (ein ganzer Raum voll mit Rohren, Kühlungen und E/A Geräten) weniger Rechenleistung vollbrachten als ein Smartphone. • Diese Röhrenrechner wurden von wenigen Ingenieuren konzipiert, gebaut, programmiert, betrieben und gewartet. Die Programmierung erfolgte im Binärcode. Programmiersprachen und Betriebssysteme waren noch unbekannt. Die ersten Programme waren Berechnungen von Sinus- und Kosinustabellen. • Anfang der fünfziger Jahre begann man, die Programme im Binärcode auf Lochkarten zu schreiben, damit sie wieder verwendbar waren. Abbildung: Zuse Z22 12 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Zweite Generation: Transistoren und Stapelsysteme (1955-1965) Zweite Generation: Transistoren und Stapelsysteme (1955-1965) Die Erfindung des Transistors führte dazu, dass Rechner zuverlässiger arbeiteten. Ab diesem Zeitpunkt wurde zwischen Entwicklern, Herstellern, Betreibern und Wartungspersonal unterschieden. • Die Maschinen wurden in gesicherten Räumen aufgestellt, die von Bedienern (operator) betreut wurden. • Wenn ein Rechenauftrag (job) ausgeführt werden sollte, musste ein Programmierer die Befehlsfolge auf Lochkarten stanzen und dem Operator übergeben. Der legte die Lochkarten in den Kartenleser und startete den Übersetzungslauf und anschliessend das Programm. Das Ergebnis (Ausdruck auf Papier) brachte der Operator in den Ausgaberaum, wo der Programmierer das Resultat abholen konnte. 13 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Zweite Generation: Transistoren und Stapelsysteme (1955-1965) • Die hohen Investitionskosten zwangen die Entwickler dazu, nach effizienteren Wegen zu suchen. Der Stapelbetrieb (batch system) sollte die Systeme besser auslasten. Zuerst wurden die Aufträge im Eingaberaum gesammelt und dort auf einem Magnetband mit einem kleineren Rechner übertragen, der teilweise auch die Übersetzung (Fortran-Maschinenkode) vornahm. Diese Prozedur wurde wiederholt (etwa eine Stunde) bis genügend viele Aufträge auf dem Magnetband waren. • Das erzeugte Eingabeband wurde dann zum eigentlichen Rechner gebracht. Dort wurde ein spezielles Programm gestartet (eigentlich der Vorfahre eines Betriebssystems), das das Eingabeband einlas, die Programme ausführte und das Ergebnis auf ein Ausgabeband schrieb. Der Operator brachte das Band dann zu einem weiteren Rechner, der die Ergebnisse ausdruckte. 14 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Zweite Generation: Transistoren und Stapelsysteme (1955-1965) • Diese Abarbeitungsmethodik von Kontrollkarten war der Vorgänger heutiger Kommandointerpreter (Shells). • Großrechner der zweiten Generation wurden weitgehend in Forschungseinrichtungen, etwa zur Lösung von Differentialgleichungen eingesetzt. Programmiert wurde in Fortran oder Assembler. In Banken und Versicherungen begann die EDV eine wichtige Rolle zu spielen – der closed job“ Betrieb ” wurde etabliert. • Typische Betriebssysteme waren FMS (Fortran Abbildung: Lochkartenstapel Monitor System) und IBSYS, das IBM Betriebssystem des Großrechners 7094. 15 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Dritte Generation: Multiprogrammierung (1965-1980) Dritte Generation: Multiprogrammierung (1965-1980) Anfang der sechziger Jahre hatten die meisten Computerhersteller zwei unterschiedliche und gegenseitig inkompatible Produktlinien: • wortorientierte Grossrechner für den technisch-wissenschaftlichen Bereich und • zeichenorientierte Rechner für den kommerziellen Bereich, die hauptsächlich für Bandsortierungen und zum Ausdrucken (Auszüge, Fälligkeitslisten) bei Banken. • IBM versuchte daraufhin mit einem einheitlichen Konzept, dem System /360, beide Anwendungsbereiche durch eine Systemfamilie mit softwarekompatiblen Abbildung: IBM 360 Rechnern abzudecken. Dieses Konzept war sehr erfolgreich. Nachfolger dieser Familie (z.B. 370, 3090) sind z.T. noch heute bei Banken im Einsatz. 16 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Dritte Generation: Multiprogrammierung (1965-1980) Der Vorteil, ein Betriebssystem für alle Bereiche und Programme, das auf allen Rechnern der Familie lauffähig war, erwies sich im Laufe der Zeit als die größte Schwachstelle: es entstand ein sehr großes, kaum mehr zu wartendes Betriebssystem. Die wichtigsten Schlüsseltechniken der Betriebssysteme dieser Generation waren/sind: 1 Mehrprogrammbetrieb, 2 Spooling und 3 Timesharing Betrieb. 17 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Dritte Generation: Multiprogrammierung (1965-1980) Mehrprogrammbetrieb Der Mehrprogrammbetrieb (multiprogramming) wurde entwickelt, nachdem festgestellt wurde, dass gerade bei E/A intensiven Anwendungen die CPU die meiste Zeit nicht ausgelastet war. Z.B. wartete die CPU auf das Terminieren eines Bandkopierens, bevor sie den nächsten Auftrag ausführte. Job5 • Die Lösung bestand in der Aufteilung des Hauptspeichers in Speicherabschnitte auf Hardwareebene (jeweils mit Auftrag und Schutzmechanismen), die sicherstellen, dass Aufträge sich nicht gegenseitig beeinträchtigen. Job4 Job3 Job2 Job 1 Betriebssystem Hauptspeicher Abbildung: Mehrprogrammbetrieb mit 5 Jobs im Speicher 18 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Dritte Generation: Multiprogrammierung (1965-1980) Spooling Spooling (Simultaneous Peripheral Operation On Line) bezeichnet ursprünglich die unmittelbare Zwischenspeicherung von Aufträgen, die vom Kartenleser direkt auf Platten übertragen wurden. • Wenn ein Auftrag terminierte, konnte das Betriebssystem einen neuen Auftrag sofort in den freien Speicherbereich laden und bearbeiten. • Heute wird diese Technik noch im Bereich Ausgabe angewendet (Drucker Spooling). Die Rechner der dritten Generation waren zwar sehr leistungsfähig, sowohl im kaufmännischen als auch im technisch wissenschaftlichen Bereich. Die Verarbeitung war aber hauptsächlich Stapelverarbeitung: ein Fehler, der in einer Ausgabe (Liste) bemerkt wird, muss korrigiert werden und ein neuer Compile Auftrag muss eingeplant werden, dann erst kann die korrigierte Version in einem neuen Auftrag laufen. 19 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Dritte Generation: Multiprogrammierung (1965-1980) Dialogsysteme Der Wunsch nach schnelleren Reaktions- und Antwortzeiten brachte Dialogsystem (timesharing) hervor: jeder Benutzer ist online mit dem Rechner über ein eigenes Terminal verbunden. MULTICS Das MIT, Bell Labs und General Electric wollten eine Maschine entwickeln, mit der gleichzeitig mehrere hundert Benutzer arbeiten können sollten. Vorbild war das elektrische Versorgungssystem: ein elektrisches Gerät wird einfach an eine Steckdose angeschlossen. Obwohl das Projekt MULTICS (MULTiplexed Information and Computing Service) nie abgeschlossen wurde, sind aus ihm viele wichtige Ideen in die Informatik eingeflossen und Nachfolgeprojekte stark beeinflusst worden. 20 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Dritte Generation: Multiprogrammierung (1965-1980) Minicomputer • Ein weiterer wesentlicher Faktor der Entwicklung der Rechner der 3. Generation bestand im Wachstum der Minicomputer, beginnend mit der DEC PDP-1 im Jahre 1961. Sie verfügte über 4k 18 Bit Worte, kostete nur 120.000 USD (ca. 5% einer IBM 7094) und war im Bereich numerische Berechnungen mit einer IBM 7094 vergleichbar, aber zu IBM inkompatibel. • Die leistungsstärksten PDP Rechner (PDP-11) waren noch Ende der 80er Jahre in vielen Forschungsinstituten zu finden. Abbildung: Ken Thompson und Dennis Ritchie 1972 vor einer PDP-11 21 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Dritte Generation: Multiprogrammierung (1965-1980) UNICS, C • Ein Mitarbeiter des MULTICS Projektes bei Bell Labs, Ken Thompson, schrieb eine abgemagerte Version als Einbenutzersystem. Brian Kernighan bezeichnete dieses System als UNICS (UNiplexed Information and Computing Service), später wurde es dann UNIX genannt. • Ein anderer Informatiker bei Bell, Dennis Ritchi entwickelte die Programmiersprache C, um damit Unix neu zu schreiben. Ziel war es, ein Betriebssystem für den Mehrbenutzerbetrieb zu realisieren, das leicht auf unterschiedliche Rechner portierbar war. Bell Labs vergab Unix Lizenzen kostenlos an Hochschulen. Dadurch wurde es auf viele Plattformen portiert. Unix und die freie Version Linux ist das Betriebssystem, das auf den meisten Plattformen portiert wurde. Die Vorlesung wird sich stark an Unix orientieren, um Konzepte von Betriebssystemen zu erklären. 22 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Vierte Generation: Personalcomputer (seit 1980) Vierte Generation: Personalcomputer (seit 1980) Durch Fortschritte in der Entwicklung hochintegrierter Schaltkreise konnten Rechner konstruiert werden, die auch für Einzelpersonen erschwinglich waren. Der PC wurde mit Betriebssystemen und Oberflächen ausgestattet, die es auch Normalbenutzern“ ermöglichten, damit zu arbeiten. ” Zwei Betriebssysteme hatten sich für PCs durchgesetzt: • MS-DOS von Microsoft für Intel-basierte Hardware und • Unix für Systeme, die auf Motorolas 68000er Familie beruhten. MS-DOS entwickelte sich bezogen auf die Funktionalität immer mehr in Richtung Unix (Microsoft war zu dieser Zeit der führende Unix Lieferant [XENIX]). 23 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Netzwerk-Betriebssysteme und Verteilte Systeme Netzwerk-Betriebssysteme und Verteilte Systeme Seit Mitte der 80er Jahre wurden Rechner mehr und mehr vernetzt. Dadurch wurden Betriebssystemkonzepte erforderlich, die mit der Problematik • des Datenaustausches, • dem Verteilen von Aufgaben und • der Kommunikation zwischen Prozessen, die auf unterschiedliche Knoten im Netz ablaufen, erforderlich. 24 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Netzwerk-Betriebssysteme und Verteilte Systeme Netzwerkbetriebssysteme Netzwerkbetriebssysteme erlauben einem Benutzer, Daten von anderen bekannten Rechnern zu verwenden und sich auf anderen bekannten Rechnern anzumelden. • Dabei können die verschiedenen Rechner unterschiedliche Betriebssysteme haben. Die Transparenz beim Kopieren von Daten geschieht durch die Verwendung von Standardprotokollen (z.B. ftp). • Die Netzwerkbetriebssysteme unterscheiden sich nicht von den Einprozessor Betriebssystemen; auf unterster Ebene ist lediglich eine Schicht, die über einen Netzwerkkontroller auf Netzressourcen zugreift. • Weiterhin sind Programme erforderlich, um Remoterechner ansprechen zu können (telnet, rsh, ssh, sftp, scp). 25 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Historische Betrachtung Netzwerk-Betriebssysteme und Verteilte Systeme Verteilte Betriebssysteme Verteilte Betriebssysteme spiegeln dem Benutzer ein Einprozessorsystem vor: der Benutzer weiß nicht, auf welchem Knoten im verteilten System sein Programm abläuft. • Auf der Betriebssystemseite sind (im Gegensatz zu Netzwerkbetriebssystemen) hier neue komplexere Algorithmen erforderlich, die die Verteilung der Programmstücke auf verschiedene Prozessoren vornehmen, um viel paralleles Arbeiten zu ermöglichen. • Die Problematik resultiert im Prinzip daraus, dass es keine zentrale Haltung von Zustandsinformation gibt. Der Entwurf eines verteilten Systems hat darüber hinaus zum Ziel, die Ausfallsicherheit und Fehlertoleranz des Gesamtsystems zu erhöhen: der Ausfall von Komponenten soll ohne Beeinträchtigung der Funktionalität gewährleistet werden können. Diese Verteilten Betriebssysteme werden hier nicht behandelt ! 26 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Grundlegende Konzepte Grundlegende Konzepte 1 Überblick 2 Was ist ein Betriebssystem 3 Historische Betrachtung 4 Grundlegende Konzepte Prozesse Dateien Kommandointerpreter 5 Systemaufrufe 6 Betriebssystemstrukturen 27 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Grundlegende Konzepte Prozesse Prozesse Ein Prozess ist ein Programm, das sich in der Ausführung befindet. Während ein Programm nur einmal auf der Festplatte gespeichert ist, dann dieses Programm mehrmals aufgerufen sein, also können von einem Programm mehrere Prozesse existieren. Ein Prozess besteht aus: • dem Programmcode, • den Programmdaten, • dem Programmstack, • dem Befehlszähler, • dem Stackzeiger und • Speicherinformationen, die zum Ablauf erforderlich sind. 28 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Grundlegende Konzepte Prozesse Der Prozessbegriff orientiert sich an den Erfordernissen von Timesharing Systemen, d.h. das Betriebssystem muss periodisch entscheiden, • ob der aktuelle Prozess weiterlaufen darf, oder • ob seine Zeitscheibe schon abgelaufen ist, er also suspendiert werden muss, um einem neuen Prozess die CPU zuteilen zu können. Wird ein Prozess suspendiert, so muss er bei der Reaktivierung im selben Zustand weitermachen können. Deshalb ist es erforderlich, sich den zuletzt ausgeführten Befehl vor der Suspendierung mit allen Umgebungsmerkmalen zu merken, z.B. die aktuell geöffneten Dateien, pro Datei den Stand des Lese/Schreib-Kopfes usw. 29 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Grundlegende Konzepte Prozesse Prozesstabelle Diese Informationen werden i.A. in einer so genannten Prozesstabelle gespeichert. Sie besteht aus einem Feld von Strukturen, die die o.a. Informationen pro suspendiertem Prozess enthält. Damit besteht ein suspendierter Prozess aus: • seinem Prozessadressraum (dem Speicher in dem Programm und Daten liegen) und • seinem Eintrag in der Prozesstabelle. 30 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Grundlegende Konzepte Prozesse Systemaufrufe Systemaufrufe zur Prozessverwaltung sind u.a. dafür verantwortlich, dass • Prozesse erzeugt und terminiert werden, • Speicher für einen Prozess angefordert und freigegeben wird, • ein Prozess sich mit anderen unterhalten kann“ und ” • die Ablaufumgebung von Prozessen definiert (Größe des Speichers, Anzahl max. geöffneter Dateien, ...) wird. 31 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Grundlegende Konzepte Prozesse Prozessbaum • Wenn ein Benutzer mit dem Betriebssystem arbeitet, so werden seine Anfragen von der Shell bearbeitet. • Dies ist ein Prozess, der die Kommandos des Benutzers liest, interpretiert und ausführt. • Nehmen wir an, der Benutzer gibt ein Kommando zum Suchen einer Datei ein. Dann muss die Shell einen Prozess erzeugen, ihm den Code des Such-Kommandos überlagern, ihn ausführen und dann beenden. Abbildung: Prozessbaum • Durch das Erzeugen von Prozessen (Kindern), ausgehend von einem Erzeuger-Prozess (Vater), entsteht eine Baumstruktur von Prozessen. 32 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Grundlegende Konzepte Dateien Dateien • Dateien werden in Betriebssystem systematisch auf Plattenbereiche verteilt. • Systemaufrufe existieren zum Öffnen, Lesen, Schreiben und Schließen einer Datei. • Dateien in Linux werden organisiert, indem man Verzeichnisse anlegen kann. Ein Verzeichnis ist ein Katalog mit Inhalten, die aus Dateien und selbst wieder Verzeichnissen bestehen können. Somit hat auch das Dateisystem eine baumartige Struktur. • Wenn ein Benutzer sich in Linux anmeldet, so ist er automatisch in seinem Heimatverzeichnis (home directory). Die Daten kann er sich dort selbst organisieren. Abbildung: Dateibaum 33 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Grundlegende Konzepte Dateien Zugriffsrechte Der Zugriff auf Dateien ist in Linux durch einen neunstelligen binären Zugriffscode, der jeder Datei zugeordnet ist, geschützt. • Dieser Code besteht aus jeweils 3 Bit für den Eigentümer, die Gruppe zu der der Eigentümer gehört und für alle anderen. • Rechte können pro Kategorie vergeben werden: Lesen (r), Schreiben (w) und Ausführen (x). • Somit hat eine Datei, die nur der Benutzer Lesen, Schreiben und Ausführen und die Gruppenmitglieder nur Lesen dürfen, die Zugriffsmaske "rwx r-- ---" (entspricht oktal 740). • Für Verzeichnisse bedeutet das x-Bit, dass im Katalog gesucht werden darf. (sticky bit und set user id bit später) 34 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Grundlegende Konzepte Dateien mounten Wenn ein Betriebssystem hochgefahren wird, so wird i.A. zuerst das Dateisystem, auf dem sich das Betriebssystem selbst befindet, verfügbar gemacht. Es befindet sich normalerweise auf der Festplatte. • Daneben existieren auswechselbare Speichermedien z.B. USB-Laufwerke oder CD Laufwerke. • Auf solchen Medien kann man ein auswechselbares Dateisystem (mounted file system) anlegen. Es wird in das Hauptdateisystem eingehängt und ist ab diesem Zeitpunkt normal“ über den ” Pfadnamen erreichbar. Abbildung: mounten 35 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Grundlegende Konzepte Kommandointerpreter Kommandointerpreter Das Betriebssystem ist der für die Ausführung von Systemaufrufen verantwortliche Teil der Systemsoftware. Wie im Schichtenmodell gezeigt, ist der Kommandointerpreter nicht Bestandteil des Betriebssystems. • Jedes Kommando, das der Benutzer absendet, bewirkt, dass die Shell einen Kindprozess erzeugt, der das Kommando ausführt. • Die Shell wartet, bis der Kindprozess terminiert ist. • Dann wird wieder ein Prompt geschrieben. • Soll ein Programm im Hintergrund ablaufen, so wird das Kommando mit dem Zeichen ’&’ abgeschlossen. 36 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Systemaufrufe 1 Überblick 2 Was ist ein Betriebssystem 3 Historische Betrachtung 4 Grundlegende Konzepte 5 Systemaufrufe Prozessverwaltung Signale Dateiverwaltung Katalogverwaltung Schutzmechanismen Zeitverwaltung Ablaufumgebung von Prozessen 37 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Systemaufrufe Die vorgestellten Systemaufrufe sind an der Implementierung in Unix orientiert. In anderen Betriebssystemen sind die Umsetzungen zwar teilweise anders, das Prinzip ist aber das gleiche. • Systemaufrufe bilden die Schnittstelle zur Hardware, auf dem das Betriebssystem abläuft. • Deshalb sind grosse Teile eines Systemaufrufs in Assembler programmiert. • Um sie für Programmierer nutzbar zu machen, wird oft eine C-Bibliothek bereitgestellt. • Systemaufruf zum Lesen einer Datei ist read“. ” count = read(file, buffer, nbytes); Mit drei Parametern von read“ wird beschrieben, welche Datei ” gelesen werden soll, wohin die Leseoperation das Ergebnis ablegen soll und wieviele Bytes aus der Datei gelesen werden sollen. 38 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Beispiel simpleCat.c 1 2 3 4 5 6 7 # define BUFSIZE 512 int main (){ char buf [ BUFSIZE ]; int n ; while (( n = read (0 , buf , BUFSIZE )) > 0) write (1 , buf , n ); } <<- Das Programm wird von Shellebene aus mit dem Kommando $ cc simpleCat.c -o simpleCat übersetzt. Die resultierende ausführbare Datei simpleCat“ kann nun verwendet ” werden, um Dateien zu lesen, etwa durch: $ simpleCat < /etc/passwd Im Folgenden werden nun die wichtigsten Systemaufrufe kurz für Prozessverwaltung, Signale, Dateiverwaltung, Katalog- und Dateisystemverwaltung, Schutzmechanismen und Zeitverwaltung vorgestellt. 39 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung Prozessverwaltung Ein Prozess besitzt einen Adressraum, in dem er abläuft. Der Prozessraum ist in mehrere Teile (Segmente) aufgeteilt. • Der Programmcode befindet sich im Textsegment. • Im Datensegment sind globale Objekte abgelegt, • dann folgt der Heap für dynamische Objekte. • Der Stack ist zur Speicherung lokaler Objekte und für Rücksprungadressen bei Funktionsaufrufen nötig. • Stack und Heap wachsen aufeinander FFFF Stack Heap Daten Textsegment 0000 zu. 40 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung fork Ein Prozess wird erzeugt, in dem ein Eltern Prozess durch den Systemaufruf fork“ einen Kind Prozess erzeugt. ” • Der Aufruf erzeugt eine exakte Kopie des Originalprozesses (Kind=Clone des Vaters), einschließlich aller CC00 Stack Dateideskriptoren, Register usw. Stack DD00 • Nach dem fork werden beide Prozesse unterschiedliche Aktivitäten übernehmen. • Zum Zeitpunkt des fork haben alle Variablen die gleichen Werte, nach dem fork wirken sich Änderungen der Variablen nur noch im jeweiligen Prozess aus. Heap Heap Daten Daten pid= fork() pid= fork() CC01 AA01 Vater Kind 41 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung fork Der fork Aufruf gibt einen Wert zurück, durch den im Programm unterschieden werden kann, ob der Code des Kindes oder des Vaters gemeint ist. 0 ist der Kindprozess, >0 der Wert ist die Prozessidentifikation (pid) des Kindprozesses für den Eltern Prozess. <0 Ein Rückgabewert von fork, der kleiner als 0 ist, zeigt an, dass kein neuer Prozess erzeugt werden konnte (Fehler). CC00 Stack Stack Heap Heap Daten Daten pid= fork() pid= fork() CC01 AA01 Vater DD00 Kind 42 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung Beispiel fork.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # include < stdio .h > int main (){ int childPid ; if (( childPid = fork ()) == -1) { <fprintf ( stderr , " can 't fork \ n " ); exit (1); } else if ( childPid == 0) { /* child process */ fprintf ( stdout , " child : child pid = %d , parent pid = % d \ n " , getpid () , getppid ()); exit (0); } else { /* parent process */ fprintf ( stdout , " parent : child pid = %d , parent pid = % d \ n " , childPid , getpid ()); exit (0); } } 43 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung In welcher Reihenfolge erscheinen die Ausgaben ? 44 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung Shell Ein reales Beispiel, bei dem ein Prozess erzeugt wird, ist die Shell. • Für jedes Kommando, das aus der Shell heraus ausgeführt wird, wird von der Shell ein eigener Prozess erzeugt. • Dabei dupliziert sich die Shell durch fork. • Im Kind (subshell) wird der Shell Code mit dem Code des auszuführenden Kommandos überlagert (exec). • Der Vater wartet (wait) bis der so erzeugte Kind-Prozess terminiert (exit). Somit kann in der Umgebung des Kindprozesses, das echo Kommando ausgeführt werden. 45 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung Shell-Programmgerüst geruest.cpp 1 2 3 4 5 7 8 9 10 11 12 13 14 15 16 17 18 void read_command ( char * com , char ** par ){ fprintf ( stdout , " $ " ); ..... return ; } int main (){ int childPid ; int status ; char command [20]; char * parameters [60]; while (1) { read_command ( command , parameters ); if (( childPid = fork ()) == -1) { <- Kind (subshell) erzeugen fprintf ( stderr , " can 't fork \ n " ); exit (1); } else if ( childPid == 0) { /* child */ execvp ( command , parameters ); <- command wird im Kind ausgeführt exit (0); <- Kind terminiert } else { /* parent process */ waitpid ( childPid , & status , WUNTRACED | WCONTINUED ); } 19 20 21 22 23 <- Vater wartet } 46 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung execvp Der execvp-Systemaufruf bewirkt, dass das Textsegment des Prozesses mit dem Kode des auszuführenden Programms überlagert wird. • Der erste Parameter ist das Stack auszuführende Programm. echo Hallo • Der zweite Parameter ist ein Array mit Zeigern auf das auszuführende Programm und die Programmargumente. DD00 parameters Heap Jenni NULL Daten execvp("echo", "Hallo", Jenni") Kode von echo • Dabei muss der letzte Eintrag CC01 Kind des Arrays NULL sein. Abbildung: execvp 47 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung exit - wait Mittels wait und exit können Vater und Kind ’kommunizieren’. • exit“ hat einen Parameter, den so genannten Exitstatus. ” • Dies ist ein Integerwert zwischen 0 und 255. • Konvention in Unix ist, dass ein Exitstatus von Null bedeutet, dass die Aktion erfolgreich ausgeführt werden konnte. Jeder andere Wert wird als Fehler angesehen. • Dieser Status wird dem Elternprozess in der Variablen status“ des wait Aufrufs mitgegeben. ” Soll z.B. eine Kommunikation zwischen Kind und Eltern stattfinden, so kann das Kind z.B. durch exit(4); dem Elternprozess die Nachricht ’4’ übergeben. Der Elternprozess wird durch child-pid = wait(&status); dann die Information in der Variablen status sehen. 48 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung Im Wert von Status sind unterschiedliche Informationen kodiert. Neben dem exit-Wert des Kindes, sind Informationen über die Terminierung des Kindes abgelegt. Um diese Informationen auszulesen existieren C-Macros. Macro WIFEXITED(status) WIFSGNALES(status) WIFSTOPPED(status) Beschreibung true, wenn status vom Kind gesetzt und das Kind normal beendet wurde. Dann kann man durch WEXITSTATUS(status) die niederwertigen 8 Bit auslesen, die den Exit-Wert des Kindes beinhalten. true, wenn status vom Kind gesetzt und das Kind abnormal beendet wurde, durch signal. Dann kann man durch WTERMSIG(status) die Signalnummer, die das Kind beendet hat, abfragen. true, wenn status vom Kind gesetzt und das Kind gerade gestoppt wurde. Dann kann man durch WSTOPSIG(status) die Signalnummer, die das Kind gestoppt hat, abfragen. Der Aufruf von wait() bewirkt, dass der Vaterprozess blockiert, bis irgend ein Kinder beendet sind (waitpid später). 49 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung Beispiel I status.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # include < stdio .h > # include < sys / wait .h > main () { int childPid ; int status ; if (( childPid = fork ()) == -1) { fprintf ( stderr , " can 't fork \ n " ); exit (1); } else if ( childPid == 0) { /* child process */ fprintf ( stdout , " child : exit 4\ n " ); sleep (20); <- Kind exit (4); } else { /* parent process */ if ( wait (& status ) != childPid ) { <- Vater fprintf ( stderr , " wait error \ n " ); exit (1); } fprintf ( stdout , " parent : status % d \ n " , status ); /* check status */ if ( WIFEXITED ( status )) { <- Macros fprintf ( stdout , " parent : normal termination of child , status % d \ n " , 50 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung Beispiel II status.c WEXITSTATUS ( status ) ); } else if ( WIFSIGNALED ( status )) { fprintf ( stdout , " parent : abnormal term . WEXITSTATUS ( status ) ); fprintf ( stdout , " parent : abnormal term . WTERMSIG ( status ) ); } else if ( WIFSTOPPED ( status )) { fprintf ( stdout , " parent : child stopped , WEXITSTATUS ( status ) ); fprintf ( stdout , " parent : child stopped , WSTOPSIG ( status ) ); } exit (0); 23 24 25 26 27 28 29 30 31 32 33 34 35 of child , signal number % d \ n " status % d \ n " , signal number % d \ n " , } 36 37 of child , status % d \ n " , } > ulab 51 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung Hörsaalübung Welche Ausgabe erzeugt das u.a. Programm? fork.c 1 2 3 4 5 6 7 8 9 # include < stdio .h > # include < unistd .h > // wg . getpid int x = 0; int main () { fork (); fork (); fork (); printf ( " pid =% d x =% d \ n " , getpid () , x ++); } → ulab 52 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung waitpid Mit wait() kann der Elternprozess nur auf die Beendigung irgend eines Kindes warten. Soll der Vater hingegen auf die Beendigung eines bestimmten Prozesses warten, dann ist waitpid() zu verwenden. Mit dem ersten Argument von waitpid(pid wpid, int *status, int options) legt man fest, worauf gewartet werden soll: pid -1 pid 0 < −1 Beschreibung auf beliebigen Prozess warten – äquivalent zu wait() auf die Beendigung von pid warten auf Beendigung warten, dessen Prozessgruppen-ID gleich der Prozessgruppen-ID des aufrufenden Prozesses ist. auf Beendigung warten, dessen Prozessgruppen-ID gleich der Prozessgruppen-ID des aufrufenden Prozesses ist. 53 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung waitpid Das dritte Argument options“ von ” waitpid(pid wpid, int *status, int options) bestimmt das Verhalten von waitpid(). Folgende Konstanten können dabei verwendet werden Konstante WNOHANG WUNTRACED WIFSTOPPED Beschreibung Der aufrufende Prozess wird nicht blockiert, wenn der Prozess ppidnnoch nicht beendet wurde bzw. noch nicht im Zombie-Status ist. (waitpid() liefert in diesem Fall 0 zurück). Status des angehaltenen Kindprozesses, der mit pid spezifiziert wurde. liefert 1 zurück, wenn es sich beim Rückgabewert um die PID des angehaltenen Kindprozesses handelt. Im folgenden Beispiel wird nicht auf die Terminierung des 1. Kindes gewartet, es wird ein zweites Kind erzeugt, auf dessen Beendigung gewartet wird. 54 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung Beispiel I waitpid.c 1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # include < unistd .h > # include ... int main ( void ) { pid_t pid1 , pid2 ; int status ; switch ( pid1 = fork ()) { case -1: perror ( " fork () " ); return EXIT_FAILURE ; case 0: // child 1 printf ( " child 1: % d \ n " , getpid ()); sleep (10); printf ( " child 1: % d terminated \ n " , getpid ()); break ; default : // parent code if ( waitpid ( pid1 , NULL , WNOHANG ) != 0) { <- wartet nicht ! perror ( " waitpid () " ); return EXIT_FAILURE ; } printf ( " --- parent will not block , creating new child - - -\ n " ); switch ( pid2 = fork ()) { case -1: 55 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Prozessverwaltung Beispiel II waitpid.c perror ( " fork () " ); return EXIT_FAILURE ; case 0: // child 2 printf ( " child 2: % d \ n " , getpid ()); sleep (5); printf ( " child 2: % d terminated \ n " , getpid ()); break ; default : // parent code if ( wait ( NULL ) != pid2 ) { <- wartet ! perror ( " waitpid () " ); return EXIT_FAILURE ; } printf ( " --- parent can continue - - -\ n " ); sleep (20); printf ( " --- parent terminated - - -\ n " ); 23 24 25 26 27 28 29 30 31 32 33 34 35 36 } } return EXIT_SUCCESS ; 37 38 39 40 } 56 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Signale Signale Signale sind das Äquivalent im Bereich Software zu Interrupts im Bereich Hardware. • Wenn ein Signal zu einem Prozess gesendet wird und der Prozess das Signal nicht annimmt, dann wird der Prozess vom Betriebssystem automatisch entfernt. • Um sich vor diesem Automatismus schützen zu können, kann sich ein Prozess durch den Systemaufruf signal“ auf das Eintreffen von ” Signalen vorbereiten. • Dazu muss er eine Signalbehandlungroutine bereitstellen. • In einem Betriebssystem gibt es mehrere Signalarten. Die meisten Signale werden durch Ereignisse, die von der Hardware ausgelöst werden, erzeugt. 57 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Signale Signale Die nachfolgende Tabelle listet die wichtigsten Signalarten auf. Nummer 1 2 3 4 5 8 9 10 11 12 13 14 15 16 Konstante SIGHUP SIGINT SIGQUIT SIGILL SIGTRAP SIGFPE SIGKILL SIBBUS SIGSEGV SIGSYS SIGPIPE SIGALARM SIGTERM frei Bedeutung Hang up, Modemunterbrechung DEL Taste Quit Signal von Tastatur Nicht erlaubte Instruktion Unterbrechung für Testzwecke Gleitkommaüberlauf Abbruch Busfehler Segmentfehler Ungültige Argumente bei Systemaufruf Ausgabe auf Pipe ohne Leser Alarm Softwareerzeugtes Endesignal frei 58 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Signale Beispiel Eine Endlosschleife wird auf das Eintreffen vom Signal SIGINT“, ” ausgelöst durch CTR-C“ reagieren, indem es einen Text ausgibt. signal.c ” 1 2 4 5 6 7 9 10 11 12 13 14 15 # include < stdio .h > # include < signal .h > void handler ( int ) { printf ( " handler \ n " ); return ; } int main () { signal ( SIGINT , handler ); /* CTR - C handled */ while (1) { printf ( " main \ n " ); sleep (2); } } Wenn ein Programm so geschrieben ist, dass es alle Signale ignoriert, könnte es nie abgebrochen werden. Deshalb gibt es das Signal SIGKILL“. ” Dieses Signal kann nicht per Signalhandler abgefangen werden. → ulab: kill -9 59 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Signale alarm Im Bereich Echtzeitanwendungen muss ein Betriebssystem in der Lage sein, Prozesse nach einer gewissen Zeit zu informieren, dass bestimmte Dinge zu erledigen sind. Der Systemaufruf alarm“ hat einen Parameter, der die Anzahl Sekunden ” angibt, nach denen das Signal SIGALARM“ erzeugt werden soll. ” timer.c 1 2 3 4 6 7 8 9 10 11 12 13 14 15 void handler ( int ) { printf ( " Bye \ n " ); exit (0); } main () { char str [80]; signal ( SIGALRM , handler ); while (1) { alarm (5); /* start timer */ printf ( " > " ); fgets ( str , 80 , stdin ); printf ( " % s \ n " , str ); } } ← ← 60 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung Dateiverwaltung - create Das nachfolgende Beispielprogramm simpleTouch.c“ demonstriert den ” Systemaufruf creat“. Das Programm legt die als Aufrufparameter ” anzugebende Datei mit den Zugriffsrechten 0640“ an. ” simpleTouch.c 1 2 3 4 5 6 7 8 9 10 11 12 # include < stdio .h > main ( int argc , char * argv []) { int fd ; if ( argc != 2) { fprintf ( stderr , " usage : % s file \ n " , argv [0]); exit (1); } if (( fd = creat ( argv [1] ,0640)) < 0) { ← fprintf ( stderr , " create error \ n " ); exit (2); } } Achtung: wenn die Datei bereits existiert, wird sie überschrieben! 61 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung open Bevor eine Datei bearbeitet werden kann, muss sie geöffnet werden. Dazu existiert der Systemaufruf open“, der neben dem Namen noch die Art ” des Zugriffs (Lesen, Schreiben oder beides) benötigt. Das folgende Programm liest die als Parameter anzugebende Datei und schreibt den Inhalt auf die Standardausgabe. cat.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # define BUFSIZE 512 main ( int argc , char ** argv ) { int fd ; ← int n ; char buf [ BUFSIZE ]; if ( argc != 2) { /* check usage */ fprintf ( stderr , " usage % s file \ n " , argv [0]); exit (1); } if (( fd = open ( argv [1] , O_RDWR )) < 0) { /* open file */ ← fprintf ( stderr , " open error \ n " ); exit (2); } while (( n = read ( fd , buf , BUFSIZE )) > 0) /* read and write file */ write (1 , buf , n ); ← } Achtung: wenn die Datei bereits existiert, wird sie uberschrieben! 62 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung Wahlfreier Zugriff - fseek Der wahlfreie Zugriff auf Dateien wird durch den Systemaufruf lseek“ ” realisiert. fseek(file, no-bytes, start); hat drei Parameter: 1 einen Filedescriptor, der die zu bearbeitende Datei definiert, 2 den Offset , der die Position des Lese/Schreibkopfes in Byte relativ zum Ausgangspunkt definiert und den Ausgangspunkt für die Positionierung des Lese/Schreibkopfes 3 • SEEK SET=Dateianfang • SEEK END=Dateiende • SEEK CUR=aktuelle Position Damit kann man ein Programm, das eine Datei (angefangen am Dateiende, d.h. rekursiv) liest einfach programmieren. 63 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung fseek revCat.c 1 2 3 4 main ( int argc , char ** argv ) { int fd ; int pos ; char buf [1]; if ( argc != 2) { /* check usage */ fprintf ( stderr , " usage % s file \ n " , argv [0]); exit (1); } if (( fd = open ( argv [1] , O_RDWR )) < 0) { /* open file */ fprintf ( stderr , " open error \ n " ); exit (2); } if (( pos = lseek ( fd , -1 , SEEK_END )) == -1) { /* pos == # bytes in file */ fprintf ( stderr , " lssek error \ n " ); exit (1); } while ( pos >=0) { /* read and write file */ read ( fd , buf , 1); write (1 , buf , 1); lseek ( fd , -- pos , SEEK_SET ); <- pos vom Anfang an } printf ( " \ n " ); 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 } 64 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung fseek Im folgenden Programm hole.c“ wird der Systemaufruf lseek“ ” ” verwendet, um ein Loch in einer Datei zu erzeugen. hole.c 1 2 3 4 int main () { int fd ; char buf1 [] = " abcde f g h i j k l m n o p " ; char buf2 [] = " ABCDE F G H I J K L M N O P " ; if (( fd = creat ( " file . hole " ,0640)) < 0) { fprintf ( stderr , " create error \ n " ); exit (1); } if (( write ( fd , buf1 , 16)) != 16) { /* offset now 16 */ fprintf ( stderr , " buf1 write error \ n " ); exit (2); } if (( lseek ( fd , 32 , SEEK_SET )) == -1) { /* offset now 32 */ fprintf ( stderr , " lseek error \ n " ); exit (3); } if (( write ( fd , buf2 , 16)) != 16) { /* offset now 48 */ fprintf ( stderr , " buf2 write error \ n " ); exit (4); } exit (0); 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ← } 65 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung fseek Ein Aufruf bewirkt: $ hole file . hole $ ls -l fil * -rw -r - - - - 1 as $ od -c file . hole 00 a b c d 20 \0 \0 \0 \0 40 A B C D 60 $ users e \0 E f \0 F 48 Nov g \0 G h \0 H i \0 I j \0 J 1 19:11 file . hole k \0 K l \0 L m \0 M n \0 N o \0 O p \0 P Loch 66 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung Dateistatus - stat Die Informationen über eine Datei, der so genannte Dateistatus, kann durch die Systemaufrufe abgefragt werden. • stat“ und fstat“ liefern Information über Dateien, ” ” lstat“ über Links. ” Alle Aufrufe geben eine Struktur vom Typ stat“ zurück. ” • 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 struct stat { dev_t ino_t mode_t nlink_t uid_t gid_t dev_t off_t blksize_t blkcnt_t time_t time_t time_t }; st_dev ; st_ino ; st_mode ; st_nlink ; st_uid ; st_gid ; st_rdev ; st_size ; st_blksize ; st_blocks ; st_atime ; st_mtime ; st_ctime ; /* /* /* /* /* /* /* /* /* /* /* /* /* ID of device containing file */ inode number */ protection */ number of hard links */ user ID of owner */ group ID of owner */ device ID ( if special file ) */ total size , in bytes */ blocksize for file system I / O */ number of 512 B blocks allocated */ time of last access */ time of last modification */ time of last status change */ 67 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung Beispiel - lstat simpleFile.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int main ( int argc , char ** argv ) { int i ; struct stat buf ; char * ptr ; if ( argc != 2) { /* check usage */ fprintf ( stderr , " usage % s file \ n " , argv [0]); exit (1); } if ( lstat ( argv [1] , & buf ) < 0) { /* get file info */ ← fprintf ( stderr , " lstat error \ n " ); exit (2); } /* print file info */ if ( S_ISREG ( buf . st_mode )) ptr = " regular " ; else if ( S_ISDIR ( buf . st_mode )) ptr = " directory " ; else if ( S_ISCHR ( buf . st_mode )) ptr = " character special " ; else if ( S_ISBLK ( buf . st_mode )) ptr = " block special " ; else if ( S_ISFIFO ( buf . st_mode )) ptr = " fifo " ; else if ( S_ISLNK ( buf . st_mode )) ptr = " link " ; else ptr = " unknown mode ! " ; printf ( " % s : % s \ n " , argv [1] , ptr ); } 68 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung Pipes Pipes sind ein Kommunikationsmedium, das es erlaubt, dass Prozesse in FIFO Manier kommunizieren. Eine Pipe ist dabei eine Pseudodatei, die die Kommunikationsdaten temporär beinhaltet. • In Unix können durch folgende Kommandofolge zwei Dateien sortiert und in einer Datei zusammengeführt werden: cat file2 file2 | sort • Hierbei werden zwei Prozesse erzeugt: der erste (cat) schreibt seine Ausgabe in die Pipe, der zweite (sort) liest die Standardeingabe aus der Pipe. cat datei sort 69 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung pipe Der Systemaufruf pipe“ erzeugt eine Pipe und gibt zwei ” Dateideskriptoren zurück, einen zum Lesen und einen zum Schreiben. Der Mechanismus wird nun am Beispiel eines Programmes gezeigt, bei dem ein Vaterprozess einem Kind Informationen über eine Pipe sendet. int p[2]; pipe(p); /* p[1]=Schreibende, p[0]=Leseende */ 70 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung Beispiel - pipe I pipe.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 /* Example : Child | Father */ # define BUFSIZE 20 main () { int pid , status ; int p [2]; char buf [ BUFSIZE ]; if ( pipe ( p ) != 0) { fprintf ( stderr , " pipe error \ n " ); exit (1); } switch ( pid = fork ()) { case -1: /* fork failed */ fprintf ( stderr , " cannot fork \ n " ); exit (2); case 0: /* child : write into pipe */ { int i ; close ( p [0]); /* close read end of pipe */ /* create example data */ for ( i = getpid (); i >0; i - -) { sprintf ( buf , " % d \ n " , i ); write ( p [1] , buf , BUFSIZE ); ← <- create pipe <- close read end <- write into pipe 71 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung Beispiel - pipe II pipe.c sleep (2); /* just to have more time to see it with " ps - el " } close ( p [1]); exit (0); 22 23 24 25 } default : /* father : read from pipe */ { int length ; close ( p [1]); /* close write end of pipe */ do { length = read ( p [0] , buf , BUFSIZE ); fprintf ( stdout , " % s " , buf ); } while ( length >0); close ( p [0]); while ( wait (& status ) != pid ); exit (0); } 26 27 28 29 30 31 32 33 34 35 36 37 <- read from pipe } 38 39 <- close write end } 72 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung named pipes Sollen zwei unabhängige Prozesse über eine Pipe kommunizieren, muss die Pipe außerhalb des Adressraums der beiden Prozesse abgebildet werden. Eine named Pipe (FIFO) wird erzeugt durch den Systemaufruf: int mknod(char *pathname, int mode, int dev); Dabei ist pathname, ein Dateiname von Unix, der Name des FIFO. Das Argument mode definiert den Zugriff (read, write mit Rechten für owner, group, others). mode wird logisch OR verknüpft mit dem Flag S IFIFO (aus < sys/stat.h >), um auszudrücken, dass mknode einen FIFO erzeugen soll. dev wird für FIFOs ignoriert (relevant für andere Objekte). FIFOs können auch durch das Unix Kommando mknod erzeugt werden: /bin/mknod name p 73 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung named pipes Sollen zwei unabhängige Prozesse über eine Pipe kommunizieren, muss die Pipe außerhalb des Adressraums der beiden Prozesse abgebildet werden. Eine named Pipe (FIFO) wird erzeugt durch den Systemaufruf: int mknod(char *pathname, int mode, int dev); Dabei ist pathname, ein Dateiname von Unix, der Name des FIFO. Das Argument mode definiert den Zugriff (read, write mit Rechten für owner, group, others). mode wird logisch OR verknüpft mit dem Flag S IFIFO (aus < sys/stat.h >), um auszudrücken, dass mknode einen FIFO erzeugen soll. dev wird für FIFOs ignoriert (relevant für andere Objekte). FIFOs können auch durch das Unix Kommando mknod erzeugt werden: /bin/mknod name p 73 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung named pipe - Beispiel Client/Server cat Eine Client-Server Anwendung, bei der ein Client einen Dateinamen von stdin einliest und den Namen auf einen Kommunikationskanal schreibt. Der Server liest den Dateinamen vom Kommunikationskanal, öffnet die Datei, liest den Inhalt und schreibt ihn über einen Kommunikationskanal zurück. Der Client erwartet den Inhalt der Datei vom Kommunikationskanal (FIFO) und gibt ihn über stdout aus. 74 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung named pipe - Beispiel Client/Server cat (Server) server.c fifo.h 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # define MAXBUFF 1024 main () { int readfd , writefd ; /* Create the FIFOs , then open them - one for reading and one for writing . */ if ( ( mknod ( FIFO1 , S_IFIFO | PERMS , 0) < 0) ← && ( errno != EEXIST )) perror ( " can 't create fifo : FIFO1 " ); if ( ( mknod ( FIFO2 , S_IFIFO | PERMS , 0) < 0) ← && ( errno != EEXIST )) { unlink ( FIFO1 ); perror ( " can 't create fifo : FIFO2 " ); } if ( ( readfd = open ( FIFO1 , 0)) < 0) perror ( " server : can 't open read fifo : FIFO1 " ); if ( ( writefd = open ( FIFO2 , 1)) < 0) perror ( " server : can 't open write fifo : FIFO2 " ); server ( readfd , writefd ); close ( readfd ); close ( writefd ); exit (0); 19 20 21 22 23 } 75 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung named pipe - Beispiel Client/Server cat (Server) 1 2 3 4 server ( int readfd , int writefd ) { char buff [ MAXBUFF ]; char errmesg [256]; int n , fd ; extern int errno ; /* Read filename from the IPC descriptor . */ if ( ( n = read ( readfd , buff , MAXBUFF )) <= 0) perror ( " server : filename read error " ); buff [ n ] = ' \0 '; /* null terminate filename */ 6 7 8 9 if ( ( fd = open ( buff , 0)) < 0) { /* Error . Format an error message and send it back to the client . */ sprintf ( errmesg , " : can 't open fifo \ n " ); strcat ( buff , errmesg ); n = strlen ( buff ); if ( write ( writefd , buff , n ) != n ) perror ( " server : errmesg write error " ); } else { /* Read the data from the file and write to the IPC descriptor . */ while ( ( n = read ( fd , buff , MAXBUFF )) > 0) if ( write ( writefd , buff , n ) != n ) perror ( " server : data write error " ); if ( n < 0) perror ( " server : read error " ); } 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 } 76 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung named pipe - Beispiel Client/Server cat (Client) client.c fifo.h 1 2 main () { int readfd , writefd ; /* Open the FIFOs . We assume the server has already created them . */ if ( ( writefd = open ( FIFO1 , 1)) < 0) perror ( " client : can 't open write fifo : FIFO1 " ); if ( ( readfd = open ( FIFO2 , 0)) < 0) perror ( " client : can 't open read fifo : FIFO2 " ); client ( readfd , writefd ); close ( readfd ); close ( writefd ); 4 5 6 7 8 9 10 11 12 /* Delete the FIFOs , now that we ' re finished . */ if ( unlink ( FIFO1 ) < 0) ← perror ( " client : can 't unlink FIFO1 " ); if ( unlink ( FIFO2 ) < 0) perror ( " client : can 't unlink FIFO2 " ); exit (0); 14 15 16 17 18 19 20 21 } 77 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Dateiverwaltung named pipe - Beispiel Client/Server cat (Client) 1 2 3 client ( int readfd , int writefd ) { char buff [ MAXBUFF ]; int n ; /* Read the filename from standard input , write it to the IPC descriptor . */ printf ( " File to print : " ); if ( fgets ( buff , MAXBUFF , stdin ) == NULL ) perror ( " client : filename read error " ); 5 6 7 8 9 n = strlen ( buff ); if ( buff [n -1] == '\ n ') n - -; /* ignore newline from fgets () */ if ( write ( writefd , buff , n ) != n ) perror ( " client : filename write error " );; 11 12 13 14 15 /* Read the data from the IPC descriptor and write to standard output . */ while ( ( n = read ( readfd , buff , MAXBUFF )) > 0) if ( write (1 , buff , n ) != n ) /* fd 1 = stdout */ perror ( " client : data write error " ); if ( n < 0) perror ( " client : data read error " ); 17 18 19 20 21 22 23 24 } 78 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Katalogverwaltung Katalogverwaltung • Durch den Systemaufruf link kann eine physische Datei unter mehreren Namen, auch in unterschiedlichen Verzeichnissen, erscheinen. • Eine Änderung über den Zugriff mit einem Namen wirkt sich immer auf das reale Dateiobjekt aus. • Um dies zu realisieren, wird eine Datei in Unix eindeutig identifiziert durch ihre inode-Zahl. • Ein Verzeichnis ist eine Datei, die eine Anzahl von Paaren (inode, Name im ASCII Code) enthält. • Durch einen Link wird dann ein neuer Eintrag im Verzeichnis erzeugt, der zum selben inode einen zusätzlichen Namen einführt. • Durch unlink kann man Links wieder löschen. Dabei wird nur der Eintrag aus dem Verzeichnis entfernt; die Datei bleibt erhalten. 79 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Katalogverwaltung sync In Unix werden die zuletzt benutzten Blöcke in einem Cache (Zwischenspeicher) abgespeichert. • Dadurch wird ein erneutes Zugreifen schneller, da dann nicht mehr auf die Festplatte zugegriffen werden muss. • Wenn ein Fehler auftaucht, bevor die Platte wirklich beschrieben (durch write Systemaufruf) wird, so gehen Daten verloren und ein inkonsistentes Dateisystem wäre die Folge. • Deshalb wird periodisch vom Betriebssystem der sync Systemaufruf ausgeführt; er schreibt die Blöcke im Cache auf die Platte. • Beim Hochfahren eines Unix Systems wird ein Programm update“ ” als Hintergrundprozess gestartet, der alle 30 Sekunden einen sync“ ” Aufruf durchführt. 80 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Katalogverwaltung fsync Während sync“ den gesamten Cache synchronisiert, kann man mit dem ” Systemaufruf fsync“ die Blöcke einer Datei im Cache synchronisieren ” (z.B. bei Datenbanksystemen bei commit“). ” fsync.c 1 2 3 4 5 6 7 8 int main ( int argc , char ** argv ) { int fd ; if ( argc != 2) { fprintf ( stderr , " usage % s file \ n " , argv [0]); exit (1); } if (( fd = open ( argv [1] , O_RDWR )) < 0) { fprintf ( stderr , " open error \ n " ); exit (2); } 10 /* manipulation of file ... */ 12 if ( fsync ( fd ) < 0) { ← fprintf ( stderr , " sync error \ n " ); exit (3); } 13 14 15 } 81 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Katalogverwaltung chdir, chroot • Um vom aktuellen Verzeichnis in ein anderes Verzeichnis zu wechseln, existiert der Systemaufruf chdir. Nachdem das aktuelle Verzeichnis mit dem Systemaufruf chdir( /home/schuette/tmp“) geändert wurde, werden die ” folgenden Aufrufe (create, open), bei denen kein vollständiger Pfadname angegeben ist, immer im tmp-Verzeichnis Dateien angelegt, bzw. geöffnet. • Ein Systemaufruf, mit dem das Root-Verzeichnis bestimmt werden kann, ist chroot“. ” Er wird verwendet, um etwa auf Webservern virtuelle Root-Verzeichnisse für unterschiedliche Benutzergruppen definieren zu können. 82 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Schutzmechanismen Schutzmechanismen In Linux besitzt eine Datei einen Besitzer und 12 Schutzbits in 4 Gruppen. Ausführungsmodi [sgd] s=setuid g=setgpid d=directory Benutzer rwx r=read w=write x=execute Gruppe rwx Rest rwx Durch den Systemaufruf chmod kann die Zugriffsmaske für eine Datei gesetzt werden. Die Maske wird dabei oktal angegeben. So bedeutet 0644 z.B.: 0 6 4 4 = = = = 000 110 100 100 Programmaufruf mit Rechten des Aufrufers rwr– r– 83 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Schutzmechanismen chmod Das folgende Programm setzt die Zugriffsrechte einer Datei (2.Parameter) so wie es die Maske (1. Parameter) angibt. simpleChmod.c 1 2 3 4 5 6 7 8 9 10 11 12 13 # include < stdio .h > main ( int argc , char ** argv ) { int mask ; if ( argc != 3) { fprintf ( stderr , " usage % s mask file \ n " , argv [0]); exit (1); } sscanf ( argv [1] , " % o " ,& mask ); if (( chmod ( argv [2] , mask )) < 0) { ← fprintf ( stderr , " chmod error \ n " ); exit (2); } } 84 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Schutzmechanismen setuid Wenn ein Programm gestartet wird, so hat es die Rechte, die der Aufrufer des Programms hat. • Deshalb kann ein Programm dem Superuser gehören (etwa das Programm rm=remove file)), aber der Aufrufer kann nur die Dateien löschen, für die er die Rechte hat. • Mit dem setuid“ ( setgid“) Bits kann man erreichen, dass ein ” ” Programm mit den Rechten des Besitzers (Gruppe) (setuid/setgid=1) abläuft und nicht wie normal mit den Rechten des Aufrufers (setuid/setgid=0). • Dies wird benötigt, um zum Beispiel die Passwort-Datei durch die Ausführung des Kommandos passwd“ abzuändern. Dazu hat das ” Kommando (=Datei) das setuid-Bit gesetzt. Beispiel: passwd 85 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Schutzmechanismen access Wird ein Programm mit dem setuid-Bit ausgestattet, so kann es nicht prüfen, ob der Aufrufer die Rechte auf eine Datei hat, da das Programm selbst ja durch das setuid-Bit alle Rechte hat. Um per Programm auf die Zugriffsrechte des realen Benutzers zugreifen zu können, existiert der Systemaufruf access. Der erste Parameter von access“ ist die zu prüfende Datei, der zweite der Zugriffsmodus, der ” geprüft werden soll. 86 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Schutzmechanismen access Das folgende setuid-Programm prüft, ob eine Datei durch den Benutzer geöffnet werden könnte; danach wird die Datei geöffnet. access.c 1 2 3 4 5 6 7 8 9 10 11 int main ( int argc , char ** argv ) { if ( argc != 2) { fprintf ( stderr , " usage % s file \ n " , argv [0]); exit (1); } if ( access ( argv [1] , R_OK ) < 0) { fprintf ( stderr , " access error \ n " ); exit (2); } if ( open ( argv [1] , O_RDONLY ) < 0) { fprintf ( stderr , " open error \ n " ); exit (3); } } $ ls -l access . txt -rw - - - - - - - 1 root root 6 24. Okt 2011 $ access access . txt access error $ access . txt 87 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Zeitverwaltung Zeitverwaltung In Unix ist Datum und Uhrzeit als Anzahl Sekunden, die seit dem Unix ” Urknall“ (1.1.1970 00:00:00) vergangen sind, abgelegt. Alle Datumsangaben, werden so gespeichert und erst in der Anzeige in lesbare Form gebracht. Dazu existiert der Systemaufruf time“, der die ” Sekundenanzahl liefert und Routinen, um diese Intergerzahl in ein lesbares Format zu konvertieren. now.c 1 2 3 4 5 6 7 # include < stdio .h > # include < time .h > main () { time_t now ; now = time ( NULL ); /* now as no . secs since ZERO */ printf ( " % s " , ctime (& now )); } 88 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Ablaufumgebung von Prozessen Ablaufumgebung von Prozessen Um die systemweite oder Shell-spezifische Ressourcenverwendung zu kontrollieren, existiert das Kommando ulimit. $ ulimit -a core file size ( blocks , -c ) data seg size ( kbytes , -d ) scheduling priority (-e) file size ( blocks , -f ) pending signals (-i) max locked memory ( kbytes , -l ) max memory size ( kbytes , -m ) open files (-n) pipe size (512 bytes , -p ) POSIX message queues ( bytes , -q ) real - time priority (-r) stack size ( kbytes , -s ) cpu time ( seconds , -t ) max user processes (-u) virtual memory ( kbytes , -v ) file locks (-x) $ 0 unlimited 0 unlimited 16001 64 unlimited 1024 8 819200 0 8192 unlimited 1024 unlimited unlimited 89 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Ablaufumgebung von Prozessen rlimit Mit den Systemaufrufen setrlimit und getrlimit kann man die Ressourcen eines Prozesses beschränken. getrlimit-cpu.c 1 2 3 5 6 # include < sys / resource .h > # include < sys / time .h > # include < unistd .h > int main () { struct rlimit rl ; getrlimit ( RLIMIT_CPU , & rl ); /* obtain the current limits . */ rl . rlim_cur = 1; /* Set a CPU limit of 1 second . */ setrlimit ( RLIMIT_CPU , & rl ); 8 9 10 /* Do busy work . */ while (1); 12 13 return 0; 15 16 /* defines and stores the limits */ } 90 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Ablaufumgebung von Prozessen fork Bomben Ein Beispiel für nichtlimitierte Ressourcen-Verwendung sind fork-Bomben: Programme, die eine Explosion von Prozessen verursachen1 : forkbomb.c 1 2 3 4 5 6 # include < unistd .h > int main ( void ){ while (1) fork (); return 0; } forkbomb.java 1 2 3 4 5 6 7 8 9 public class forkbomb implements Runnable { public static void main ( String [] args ) { new forkbomb (). run (); } public void run () { new Thread ( this ). start (); new Thread ( this ). start (); } } 1 Verhindern durch Eintrag in /etc/security/limits.conf @users soft nproc 128 @users hard nproc 50 91 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Systemaufrufe Ablaufumgebung von Prozessen fork Bomben Ein Beispiel für nichtlimitierte Ressourcen-Verwendung sind fork-Bomben: Programme, die eine Explosion von Prozessen verursachen1 : forkbomb.c 1 2 3 4 5 6 # include < unistd .h > int main ( void ){ while (1) fork (); return 0; } forkbomb.java 1 2 3 4 5 6 7 8 9 public class forkbomb implements Runnable { public static void main ( String [] args ) { new forkbomb (). run (); } public void run () { new Thread ( this ). start (); new Thread ( this ). start (); } } 1 Verhindern durch Eintrag in /etc/security/limits.conf @users soft nproc 128 @users hard nproc 50 91 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Betriebssystemstrukturen Betriebssystemstrukturen I Hier sollen verschiedene Ansätze für den inneren Aufbau eines Betriebssystems gezeigt werden. 1 Überblick 2 Was ist ein Betriebssystem 3 Historische Betrachtung 4 Grundlegende Konzepte 5 Systemaufrufe 6 Betriebssystemstrukturen Monolithische Systeme 92 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Betriebssystemstrukturen Betriebssystemstrukturen II Schichtenmodell Virtuelle Maschinen Auftraggeber-Auftragnehmer Modell 93 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Betriebssystemstrukturen Monolithische Systeme Monolithische Systeme Monolithische Systeme sind als Menge von Prozeduren realisiert. • Jede Prozedur kann jede andere aufrufen. • Eine Struktur ist nicht erkennbar. • Das Betriebssystem wird generiert, in dem alle Prozeduren übersetzt werden und zu einem ein- zigen grossen Objekt gebunden werden. 94 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Betriebssystemstrukturen Monolithische Systeme Monolithische Systeme Systemaufrufe werden dabei wie folgt abgebildet: • Bei einem Systemaufruf werden die Parameter an eine wohldefinierte Stelle (spezielle Register oder Stack) geschrieben, dann wird der Aufruf durch einen speziellen Unterbrechungsbefehl (Kernel-Aufruf, Supervisor-Aufruf) zur Ausführung gebracht. Durch diese Instruktion wird die Hardware vom User-Modus in den Kernel-Modus umgeschaltet und die Kontrolle übernimmt das Betriebssystem. • Das Betriebssystem prüft die Parameter des Aufrufs, bestimmt welcher Systemaufruf durchgeführt werden soll. • Der Systemaufruf wird vom Betriebssystem ausgeführt und das Ergebnis wird wieder in speziellen Registern oder auf dem Stack abgelegt. • Dann gibt das BS die Kontrolle an das Benutzerprogramm zurück. 95 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Betriebssystemstrukturen Monolithische Systeme Systemaufrufe • Diese Vorgehensweise wird von den meisten CPUs unterstützt. • Eine CPU kann in zwei Modi gefahren“ werden: ” • im Kernel-Modus sind alle Instruktionen zulässig, • im User-Modus nur eingeschränkte Instruktionen, hauptsächlich E/A Befehle. 96 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Betriebssystemstrukturen Schichtenmodell Schichtenmodell Ein Betriebssystem dieser Kategorie ist in Schichten eingeteilt, wobei eine Schicht auf der Basis der darunter liegenden Schicht konstruiert ist. Das klassische Beispiel ist das von Dijkstra 1968 entwickelte System THE (Technische Hogeschool Eindhoven). • Schicht 0 war für das Prozess-Scheduling verantwortlich, dadurch brauchte keine der anderen Schichten mehr zu berücksichtigen, dass es mehrere Prozesse auf der Maschine gibt. • Schicht 1 belegte für einen Prozess Platz im Speicher; war dort kein Platz wurden Speicherseiten auf eine Trommel verlagert; dadurch brauchte kein Programm der Schichten 2 und grösser sich um Speicherverwaltung zu kümmern. • Schicht 2 verwaltete die Bedienkonsole und die Kommunikation zwischen Prozessen; damit hatte ab der Schicht 3 jedes Programm seine eigene virtuelle Konsole. • Schicht 3 war für die Verwaltung der E/A-Geräte zuständig; damit konnte jedes Programm ab Ebene 4 mit logischen E/A-Geräten arbeiten. 97 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Betriebssystemstrukturen Schichtenmodell Somit hatten Benutzerprogramme eine virtuelle Sicht auf die Hardware. Diese Konzeption war eine Entwurfentscheidung. Das gesamte Betriebssystem war aber immer noch ein aus mehreren Modulen zusammengefasstes grosses Programm. 98 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Betriebssystemstrukturen Virtuelle Maschinen Virtuelle Maschinen Das IBM System VM/370 stellt einen Monitor zur Verfügung, der auf die nackte“ Hardware zugreift und Kopien der realen Maschine als virtuelle ” Maschine für darüber liegende Schichten bereitstellt. • Auf jeder solcher virtuellen Maschinen kann ein eigenes BS ablaufen. • Wenn ein Benutzerprogramm einen Systemaufruf absetzt, wird er vom BS der virtuellen 370 behandelt. Dort gibt dieses BS den Aufruf nicht an die reale Hardware weiter, sondern an den Monitor, der dann den Zugriff auf die Hardware erledigt. Diese Architektur ist noch Heute Basis der grossen“ IBM ” Betriebssysteme. 99 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Betriebssystemstrukturen Auftraggeber-Auftragnehmer Modell Auftraggeber-Auftragnehmer Modell In modernen Betriebssystemen verwendet man das Auftraggeber-Auftragnehmer Modell (Client- Server Modell). • Ein Client-Prozess beauftragt einen Server, einen Dienst auszuführen, indem er dem Server eine Nachricht sendet. • Der Server antwortet mit der Erbringung des Dienstes. • Sowohl Client als auch Server laufen im User-Modus. • Dadurch hat der Betriebssystemkern nur noch elementare Aufgaben, wie z.B. Interprozesskommunikation. Der schlanke Kern und die unabhängigen Server bewirken, dass gut skalierbare und fehlertolerante Betriebssysteme realisierbar sind: ein Absturz des Datei-Servers führt nicht zum Absturz der davon nicht betroffenen Programme. 100 / 101 Betriebssysteme - Einleitung ... [email protected] Version: (8c45d65) ARSnova 19226584 Betriebssystemstrukturen Auftraggeber-Auftragnehmer Modell Verteilte Betriebssysteme Weiterhin ist damit die Voraussetzung für verteilte Betriebssysteme gesetzt: • im Kern wird Netzfunktionalität integriert und • die Server können auf beliebigen Rechnern im Netz ablaufen. 101 / 101