Der folgende Artikel stammt aus den GUUG-Nachrichten.

SQL4txt: ein Modell für die Systemverwaltung

Informationen sind unter Unix häufig als Tabellen organisiert. Diese Tatsache ist offensichtlich, wenn die Bezeichnungen das Wort Tabelle enthalten, wie z.B. die Prozeßtabelle, die Routing-Tabelle oder die Symboltabelle. Bei Dateien wird das Vorliegen von tabellarisch strukturierter Information durch das Dateiformat oder die Wahl des Dateinamens betont. Denken Sie dabei etwa an (v)fstab, crontab oder inittab. Allerdings macht das Beispiel der Partitionstabelle mit Ihren 512 Byte binären Daten deutlich, dass die Art der Speicherung der Information für die Bezeichnung als Tabelle nicht entscheidend ist. Es kommt nicht darauf an, wie sich die nackten Daten unserem Auge darstellen, sondern wie die Daten strukturiert sind.

Neben den Konfigurationsdateien enhalten auch die Protokolldateien oder die Ausgabe von Werkzeugen wie ps, route oder ls tabellarische Daten. Bei dieser weiten Verbreitung von Tabellen auf einem Unix-System stellte sich mir daher die Frage nach einem allgemeingültigen Werkzeug mit dem sich solche Informationen verarbeiten lassen. Ein solches Werkzeug erfordert natürlich auch eine entsprechend allgemeingültige Schnittstelle - auch wenn es unter Unix fast schon zum guten Ton gehört, Schnittstellen konsequent zu vernachlässigen.

Eine Sprache, die speziell für den Umgang mit Tabellen entworfen wurde, ist die structured query language (SQL). Für diejenigen Leser, die noch keinen Kontakt mit SQL hatten, sind die wichtigsten Kommandos der Sprache in Tabelle 1 wiedergegeben. Später im Artikel wird die Anwendung der Kommandos auf verschiedenen Informationen anhand von Beispielen gezeigt.

Um Mißverständnisse im obigen Sinne zu vermeiden, werden SQL-Datenbanken relational genannt. Relational bedeutet, dass es ausnahmslos eine Beziehung (Relation) zwischen den Tabelleneinträgen einer Spalte gibt. D.h. die Tabelleneinträge lassen sich anhand von Kriterien selektieren. Gegenbeispiele sind Tabellenkalkulationen, bei denen an beliebiger Stelle eine zeilenübergreifende Grafik platziert werden kann. Die von der Grafik überdeckten Zellen lassen sich aufgrund des unterschiedlichen Datentyps nicht mit anderen Zellen vergleichen, was bei SQL-Datenbanken u.a. aus Gründen der Verarbeitungsgeschwindigkeit vermieden wurde.

SQL-Anweisung Typ Beschreibung
INSERT D Eine neue Zeile in die Tabelle einfügen.
SELECT D Zeilen selektieren ("suchen")
UPDATE D Existierende Zeilen ändern.
DELETE D Zeilen löschen
CREATE S Neue Tabelle erzeugen (definieren)
ALTER S Struktur einer Tabelle ändern
DROP S Tabelle aus der Datenbank entfernen
Tabelle 1: Die wichtigsten SQL-Kommandos

SQL ist weit verbreitet und gut dokumentiert. Aus formeller Sicht besteht die Sprache aus Kommandos zur Manipulation der Daten (data manipulation language, DML) und aus Kommandos zur Manipulation der Tabellen(struktur) (data definition language, DDL). Es ist wichtig zu verstehen, dass man zur Erlangung einer allgemeingültigen Schnittstelle unbedingt beides benötigt. Liesse man beispielsweise den DDL-Teil aus, dann benötigte man zu jeder Konfigurationsdatei, die man per SQL manipulieren wollte, eine weitere Konfigurationsdatei zur Definition (Dokumentation) der Struktur - und natürlich ein entsprechendes Werkzeug zur Manipulation der neugeschaffenen Struktur-Konfigurationsdatei: eine Schlange, die sich selbst in den Schwanz beißt.

Obwohl konventionelle relationale Datenbanken die Daten in Binärformaten ablegen, ist dies nur eine Notwendigkeit zur Steigerung der Geschwindigkeit und nicht etwa Teil der SQL-Idee. Es ist vollkommen in Ordnung eine Datenbank zu konstruieren, die ihre Daten zwar langsam, aber im Klartext ablegt. Könnte die Datenbank außerdem noch pro Tabelle ein individuelles Klartext-Format verwenden, dann liessen sich mit ihr viele Aufgaben der Systemadministration durch SQL-Anweisungen beschreiben und ausführen.

Welche Parameter würden Datenbank-intern benötigt, um das Lesen der Klartext-Information zu steuern? Dateien wie /etc/passwd und /etc/fstab unterscheiden sich im Dateinamen, in den Feldnamen und im Zeichen(muster), welches die Felder voneinander abgrenzt. Es war die die erste Arbeitshypothese für sql4txt, dass sich mit diesen Parametern die gesamte textuelle Information eines Unix-Systems beschreiben liesse. Auf dieser Annahme entwickelte ich einen Prototyp, der im Mai 1998 auf dem Linux-Kongress in Köln vorgestellt wurde. Der Prototyp ist längst überholt, aber sein Konzept ist einfacher zu verstehen, weshalb er trotzdem für das einführende Beispiel gewählt wurde.


sql4txt> CREATE TABLE fstab (
      =>   device      char(32),
      =>   mountpoint  char(32),
      =>   fstype      char(32),
      =>   options     char(32),
      =>   dump        integer,
      =>   pass        integer,
      => ) META (
      =>   filename /etc/fstab,
      =>   fields device mountpoint fstype options dump pass,
      =>   format ^([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]
+)\s*\$
      => );
Ok.

sql4txt> INSERT INTO fstab (
      =>   device, mountpoint, type, options, dump, check
      => )  VALUES (
      =>   '/dev/hda2', '/', 'ext2', 'defaults', 0, 1
      => );
Ok, 1 row affected.


sql4txt> SELECT fstype,options FROM fstab
         WHERE device = '/dev/hda2'
| fstype  | options  |
+---------+----------+
| ext2    | defaults |

sql4txt> DELETE FROM fstab
      => WHERE device = '/dev/hda2';

sql4txt> DROP fstab;
Listing 2: Lebenszyklus einer Tabelle in sql4txt

Listing 2 zeigt die Anwendung von SQL-Anweisungen auf die Konfigurationsdatei /etc/fstab. Mit der Anweisung CREATE wird eine Tabelle namens fstab definiert. Neben den konventionellen Felddefinitionen von SQL werden noch die oben genannten Metainformationen (Informationen über die Informationen) in der Tabelle abgelegt. Diese Vorgehensweise versprach die schnellsten Ergebnisse, ist aber nur schwer erweiterbar und ist nicht im SQL-Standard vorgesehen. Dass Erweiterungen im großen Stil interessant sein könnten, deuten die Stichworte Versionskontrolle (mit Rollback), Zugriffskontrolle (ACL) und Dokumentation an.

Mit der Anweisung INSERT wird eine neue Zeile in die Datei /etc/fstab aufgenommen. Um eine solche Anweisung zu formulieren, muß der Systemverwalter das konkrete Format der betroffenen Datei nicht kennen - SQL tut für jeden Zweck. Es gibt warnende Stimmen, dass Systemadministratoren auf diese Weise vollkommen abhängig von sql4txt würden, weil sie den Umgang mit den rohen Daten nicht mehr praktizierten. Allerdings müßte man dann auch konsequenterweise Werkzeuge wie fdisk als bedenklich einstufen, weil man von ihnen abhängig ist: Wer kann die Partitionstabelle schon mit einem Hex-Editor bearbeiten? Angesichts der Komplexität heutiger Unix-System glaube ich persönlich, dass man besser beraten ist (und Unix attraktiver erscheint), wenn man sich auf die wesentlichen Kenntnisse beschränkt. Angenommen das Trennzeichen in der /etc/passwd wäre nicht mehr der Doppelpunkt, sondern ein Prozentzeichen. Müßte der Systemverwalter umdenken? Nein, denn dieses Detail ändert die Struktur der Information nicht. Ich behaupte daher, dass die Erfahrung im Umgang mit entsprechenden INSERT-Anweisungen sofort zum Umgang mit der eigentlichen /etc/fstab befähigt, weil die Struktur der Information dieselbe ist.

Die nächste Anweisung in Listing 2 selektiert alle Zeilen, bei denen die Gerätedatei /dev/hda2 ist. Als Ergebnis werden Dateisystemtyp und Optionen ausgegeben. Um einen vollständigen Lebenszyklus zu beschreiten, wird die Zeile mit DELETE gelöscht und die Tabelle mit DROP aus der Datenbank entfernt. Solche Befehle könnte man in einer for-Schleife auch über einen ganzen Maschinenpark laufen lassen; z.B. wie in Listing 3 gezeigt. NIS wäre damit fast überflüssig. Eine ausführlichere Version des Skripts finden Sie unter der URL ftp://ftp.guug.de/pub/members/truemper/uufw-0.2.tar.gz (Hinweis: uu wie in UUCP).


#! /bin/sh
sqlcmd="UPDATE /etc/passwd 
        WHERE  user = winni
        SET    password = crypt('top-secret');"

for  M  in  machine1 machine2 machine3
do
    ssh $M sql4txt --command="$sqlcmd"
done
Listing 3: sql4txt in heterogenen Clustern

Nun sind nicht alle Dateien so offensichtlich als Tabelle zu modellieren, wie die /etc/fstab. Allerdings lassen sich - was später auch für die Implementation wichtig ist - die Konfigurationsdateien nach Art der Modellierung in drei große Klassen einteilen. Die Frage ist: was entspricht der Tabelle und was entspricht den Zeilen der Tabelle? Eine Übersicht der Klassen ist in Tabelle 4 enthalten.

Tabelle Zeilen Beispiel
Verzeichnis Inhalte der Dateien pam.d-Verzeichnis
Datei Bereiche (z.B. Zeilen) fstab, smbd.conf
Sektionen Regionen sendmail.cf
Tabelle 4: Zuordnung von Tabellen zu Dateien

Bei Punkt-d-Verzeichnissen wie pam.d, cron.d oder rcX.d enspricht das Verzeichnis der Tabelle und die Zeilen sind die Inhalte der Dateien. Eine Spalte enthält ggf. den Dateinamen, falls dieser sich nicht aus den anderen Daten ergibt. Tabelle 5 zeigt auszugsweise die Modellierung des Verzeichnisses rc2.d als Tabelle. Speziell die rcX.d-Verzeichnisse könnte man zu einer einzigen Tabelle zusammenfassen, indem man noch eine zusätzliche Spalte mit der X-Nummer einführt.

start/kill Sortiernummer Skriptname
S 99 xdm
S 80 httpd
S 55 named
S 10 syslogd
Tabelle 5: Modellierung des Verzeichnisses rc2.d als Tabelle

Die nächste große Klasse von Konfigurationsdateien werden durch Beispiele wie fstab, smb.conf oder passwd umrissen. Solche Dateien bestehen aus Bereichen, die im Falle von smb.conf auch mehrere Zeilen in der Datei umfassen können. Die Bereiche ergeben die -u.U. sehr langen - Zeilen der sql4txt-Tabelle.

Bereichsname comment browseable ...
global (?)   no  
homes Home-Verz. yes  
printers Drucker yes  
Tabelle 6: Die ersten von ca. 150 weiteren Spalten zur Modellierung von smb.conf

Ein scheinbar komplizierteres Beispiel ist die Datei /etc/sendmail.cf. Diese Datei läßt sich anhand des Anfangsbuchstabens der Einträge in Sektionen gliedern. Die Sektionen sind eigenständige Tabellen. Manche Sektionen wie die sendmail-Optionen ergeben entartete Tabellen, die nur eine Zeile mit Daten beinhalten. Im Prinzip stört das aber nicht weiter. Andere Sektionen ergeben dafür vollwertige Tabellen, z.B. die Regeln zum Umschreiben der E-Mail-Header. Weitere Beispiele, die in diese letztete Klasse fallen, sind XF86Config oder system.fvwmrc. Es scheint also möglich zu sein, eine Vielzahl von Dateien als Tabellen zu modellieren.

Scheinbare Gegenbeispiele sind Skripte wie setserial.sh oder network.sh (beide unter Linux zu finden), denn Informationen lassen sich aus einem Programmcode nicht zuverlässig extrahieren: Die zugehörige Parsing-Routine bräuchte eine erhebliche Menge Intelligenz, um beispielsweise die Folgen einer while-Schleife richtig einzuschätzen. Programmcode ist allerdings auch das Stichwort, denn die Idee einer Konfigurationsdatei ist ja die Trennung vom Programmcode zwecks einfacherem Upgrade desselben. Mischt man beides, wie es bei den genannten Shell-Skripten der Fall ist, dann erhält man eben keine Konfigurationsdatei. Somit sind beide auch keine Gegenbeispiele für das sql4txt-Modell, sondern Unzulänglichkeiten auf dem System, die schon aus den beschriebenen Gesichtspunkten behoben werden sollten.

Das Problem liegt darin begründet, dass die Werkzeuge install, ifconfig, route, setserial, start-stop-daemon, edquota, tunelp, hdparm, stty, ipfwadm, request-route, irqtune, losetup, rarp, 3c5x9setup, isdnctrl, rc, ipx_configure, gpm, xdm, install, q2conf, getty, iproute, klogd oder slattach über keine eigene Konfigurationsdatei verfügen. Eine solche liesse sich - als vorübergehende Lösung - schnell mit einem Wrapper-Skript einführen; etwa nach dem in Listing 7 gezeigten Muster. Aber anstatt die Parameter für den Aufruf von setserial fest in den Wrapper einzubauen, liest der Wrapper die Parameter aus einer externen Konfigurationsdatei, die ihren Namen deshalb auch verdient. Für eine etwas ausführlichere Betrachtung dieses Themas empfehle ich die Folien zu sql4txt vom Frühjahrsfachgespräch 1999.

# /etc/setserial.conf
#      ...
#--------------------------------------------------
/dev/tty0    *      *   16550A     *  
/dev/tty2   0x3eF  12   16550A   high   sak close_delay

#! /bin/sh
while read DEVICE PORT IRQ CHIP SPEED OPTIONS
do
    case $DEVICE in
        \# | "") continue;;   # Kommentarzeilen überspringen
    esac
    ...
    setserial $DEVICE $OPT_STRING
done < /etc/serial.conf

Listing 7: Konfigurationsdatei und Wrapper für setserial als Beispiel

Wie bereits eingangs erwähnt, lassen sich auch andere Informationen mit sql4txt verarbeiten. Für Beispiele wie die Prozeßtabelle liegen die Vorteile auf der Hand: anstatt eine Vielzahl von ähnlichen Kommandos zur Manipulation der Tabelle kennen zu müssen ("cluen"), arbeitet der Systemverwalter unter sql4txt nur mit der Struktur der Prozeßinformationen. Eine Gegenüberstellung ist in Tabelle 8 enthalten.

Kommando   Felder FROM WHERE
ps SELECT pid,tty,stat,time,command process-table user = current
pidof SELECT pid process-table command = ...
psgrep SELECT pid,tty,stat,time,command process-table command = ...
getpcaps SELECT capabilities process-table pid =...
kill -KILL DELETE   process-table pid =...
skill -KILL DELETE   process-table command=...
killall -KILL DELETE   process-table command=...
renice UPDATE SET nice = 19 process-table pid =...
ulimit UPDATE SET max_files = 64 process-table pid = current
Tabelle 8: Kommandozeilen-Werkzeuge und sql4txt-Äquivalente

Worum es bei sql4txt letztendlich geht, ist eine Reduzierung der "overall system complexity": Scheuklappen ausziehen und das Gesamtsystem solange betrachten, kritisieren und verbessern, damit weniger administrativer Arbeitsaufwand erforderlich wird, um dieselbe Leistungsfähigkeit mit dem System zu erbringen. Es gibt keinen Beweis dafür, daß der heutige Zustand von Unix in irgendeiner Hinsicht optimal ist. Entscheidend ist für mich dabei nicht der Vergleich mit NT, der Unix höchstens in die Mittelmäßigkeit führt, sondern die Frage: Was könnten wir erreichen, wenn wir nur wollen?

In der numerischen Mathematik reduziert man die Komplexität mithilfe von vereinfachten Modellen der Realität, die dann in den Speicher des Computers passen. Warum nicht auch in der Systemadministration?! Alle Komponenten als Tabellen anzusehen, ist sicherlich nur ein Modell des Systems - nicht etwa die Wirklichkeit. Insgeheim sagt sql4txt also: das System als ganzes ist zu kompliziert, wir brauchen etwas, was besser in die Köpfe der Systemadministratoren paßt (damit die z.B. nicht zu NT abwandern). Die nächste Frage ist dann: wie gut ist das sql4txt-Modell? Das wird sich durch den Einsatz in der Praxis noch herausstellen müssen.


Winfried Trümper ist blond und daher muß Unix für ihn einfacher werden. Sie können ihn unter der E-Mail-Adresse truemper@guug.de erreichen.