4.4 Kernel-Informationen
Viele Einträge im /proc-Verzeichnis geben auch Informationen zum laufenden Kernel aus. Der Ort der Kernel-Informationen ist unterschiedlich, viele liegen im /proc-Verzeichnis selbst und weitere in den Unterverzeichnissen wie /proc/sys oder /proc/sys/kernel.
Hierzu einige häufig benötigte Informationen, die in viele Anwendungen integriert sind:
$ cat /proc/sys/kernel/ostype
Linux
$ cat /proc/sys/kernel/osrelease
2.6.4-HX
$ cat /proc/sys/kernel/version
#14 Mon May 31 12:13:37 CEST 2004
$ cat /proc/sys/kernel/ctrl-alt-del
0
Zuerst wurde abgefragt, was für ein Betriebssystem genau hier läuft (ostype), dann die Version des Kernels (osrelease) und wann dieser Kernel kompiliert wurde (version). Bei der letzten Abfrage wird überprüft, ob ctrl-alt-del gesetzt ist. Damit können Sie beeinflussen, ob init bei der Tastenkombination (STR)+(ALT)+(DEL) eine Aktion ausführen soll. Steht »ctrl-alt-del« auf 1, wird bei Tastendruck sofort ein BIOS-Reboot angeordnet. Steht »ctrl-alt-del« allerdings auf 0, wird init dazu angehalten, das System ordentlich herunterzufahren Wollen Sie diesen Parameter verändern, müssen Sie sich schnell als Superuser darstellen:
$ su
Password:********
# echo 1 >> /proc/sys/kernel/ctrl-alt-del
# exit
exit
$ cat /proc/sys/kernel/ctrl-alt-del
1
Ein weiteres Beispiel. Sie haben eine CD-ROM eingelegt und gemountet. Nachdem Sie die Daten von der CD-ROM gelesen haben, werfen Sie die CD-ROM ordnungsgemäß mit umount wieder aus und fahren anschließend das System herunter. Jetzt benötigen Sie aber die CD-ROM für einen Bekannten. Somit müssen Sie den PC leider nochmals anschalten. Wäre doch nett, wenn beim Ausgeben der CD-ROM die CD ausgeworfen wird. Für solche Fälle ist der Eintrag in /proc/sys/dev/cdrom/autoeject zuständig. Der Wert ist mit der Voreinstellung 0 versehen. Folgendermaßen können Sie dabei vorgehen, um den Wert auf 1 zu setzen:
$ mount /media/cdrom
$ cat /proc/sys/dev/cdrom/autoeject
0
$ su
Password:********
# echo 1 >> /proc/sys/dev/cdrom/autoeject
# exit
exit
$ cat /proc/sys/dev/cdrom/autoeject
1
$ umount /media/cdrom
Beim Aushängen des CD-ROM-Laufwerkes müsste jetzt die CD ausgeworfen werden. Dieses nette Feature zeigt allerdings schon recht früh seine Schattenseiten, z. B. wenn die Hardwareerkennung oder das Installationsprogramm das Device mehrmals öffnet und schließt. Besonders fies auf engem Raum, wo Ihr CD-Laufwerk leiden wird, wenn es sich nicht vollständig öffnen kann.
Sie hacken übrigens damit nicht im System herum. Viele dieser Kernel-Parameter wurden bewusst so implementiert, damit Sie den Bedürfnissen der Anwender angepasst werden können, um ein höchstes Maß an Flexibilität zu erreichen. Da dabei in der Regel Superuser-Rechte benötigt werden, sind diese Einstellungen meistens für den Systemadministrator vorgesehen. Daher macht es relativ wenig Sinn, wenn Sie in Ihrer Anwendung, die Sie schreiben, versuchen, die Kernel-Parameter zu verändern. Dies würde bedeuten, dass Ihre Anwendung im Superuser-Modus laufen müsste. Bedenken Sie, dass dies nicht immer möglich ist – und auch nicht sein sollte.
Für administrative Zwecke soll hierfür jedoch eine solche Anwendung erstellt werden. Aber wie schon erwähnt, Sie benötigen Superuser- Rechte (bzw. root-Rechte) für dieses Programm, sollten Sie etwas verändern wollen. Versucht der normale Anwender, etwas zu verändern, bekommt er ein »Permission denied« zurückgegeben. Hier das Beispiel mit anschließender Erläuterung.
/* kernelinf.c */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd. h.>
#include <string.h>
#define BUF 4096
enum { EJECT, FILE_MAX, SHARED_MAX };
enum { CDINFO, OS, RELEASE, VERSION };
static const char *sys[] = {
/* Bei umount CD auswerfen */
"/proc/sys/dev/cdrom/autoeject",
/* max. Anzahl geöffneter Dateien pro Prozess */
"/proc/sys/fs/file-max",
/*max. Größe geteilter Speicher (Shared Memory) */
"/proc/sys/kernel/shmmax"
};
static const char *info[] = {
"/proc/sys/dev/cdrom/info", /* Infos zur CD-ROM */
"/proc/sys/kernel/ostype", /* Welches Betriebssystem */
"/proc/sys/kernel/osrelease" /* Kernel-Version */
"/proc/sys/kernel/version" /* Kernel von wann */
};
static char *get_info (const char *inf) {
FILE *fp;
static char buffer[BUF];
size_t bytes_read;
fp = fopen (inf, "r");
if (fp == NULL) {
perror("fopen()");
return NULL; /* Fehler beim Öffnen */
}
bytes_read = fread (buffer, 1, sizeof (buffer), fp);
fclose (fp);
if (bytes_read == 0 || bytes_read == sizeof (buffer))
return NULL;
buffer[bytes_read] = '\0';
return buffer;
}
static void set_sys (const char *sys, unsigned long set) {
FILE *fp;
char buf[32];
fp = fopen (sys, "w");
if (fp == NULL) {
perror ("fopen()");
printf ("Weiter mit ENTER\n");
getchar ();
return;
}
sprintf(buf, "%ld", set);
fprintf (fp, "%s", buf);
fclose (fp);
return;
}
int main (int argc, char **argv) {
int auswahl;
unsigned int file_max;
unsigned long shared_max;
do {
printf ("Aktueller Zustand\n");
printf ("Betriebssystem : %s", get_info (info[OS]));
printf ("Kernel-Version : %s",
get_info (info[RELEASE]));
printf ("Datum : %s",
get_info (info[VERSION]));
printf ("------------------------------------\n");
printf ("Verändern können Sie Folgendes ...\n");
printf ("-0- Bei \"umount\" CD auswerfen"
" Aktuell:%s", get_info (sys[EJECT]));
printf ("-1- Max. Anzahl geöffneter Dateien pro"
" Prozess Aktuell:%s",
get_info (sys[FILE_MAX]));
printf ("-2- Max. Größe des geteilten Speichers"
" (KB) Aktuell %s",
get_info (sys[SHARED_MAX]));
printf ("------------------------------------\n");
printf ("Informationen bekommen Sie zu ...\n");
printf ("-3- CD-ROM\n");
printf ("------------------------------------\n");
printf ("-4- ENDE\n");
printf ("Ihre Auswahl bitte (0–4) : ");
do { scanf ("%d", &auswahl); } while (getchar ()!='\n');
switch (auswahl) {
case EJECT:
if (strncmp ("0", get_info (sys[EJECT]),1) == 0)
set_sys (sys[EJECT], 1); /* Setzen */
else /* Zurücksetzen */
set_sys (sys[EJECT], 0);
break;
case FILE_MAX:
printf ("Welcher Wert soll gesetzt werden : ");
do{ scanf("%d", &file_max); } while (getchar()!='\n');
set_sys (sys[FILE_MAX], file_max);
break;
case SHARED_MAX:
printf ("Welcher Wert soll gesetzt werden : ");
do { scanf("%ld", &shared_max); }
while (getchar()!='\n');
set_sys (sys[SHARED_MAX], shared_max);
break;
case 3:
printf ("%s", get_info (info[CDINFO]));
printf ("Weiter mit ENTER\n");
getchar ();
break;
case 4:
printf("Programm wird beendet\n");
break;
default:
printf ("Unbekannte Eingabe\n");
}
} while (auswahl != 4);
return EXIT_SUCCESS;
}
Das Programm bei der Ausführung:
$ gcc -o kernelinf kernelinf.c
$ ./kernelinf
Aktueller Zustand
Betriebssystem : Linux
Kernel-Version : 2.4.20–4GB
Datum : #1 Mon Mar 17 17:54:44 UTC 2003
------------------------------------
Verändern können Sie Folgendes ...
-0- Bei "umount" CD auswerfen Aktuell:1
-1- Max. Anzahl geöffneter Dateien pro Prozess Aktuell:32000
-2- Max. Größe des geteilten Speichers (KB) Aktuell 30000000
------------------------------------
Informationen bekommen Sie zu ...
-3- CD-ROM
------------------------------------
-4- ENDE
Ihre Auswahl bitte (0–4) :
Neben dem Auswerfen der CD-ROM bei umount können hier noch die maximale Anzahl gleichzeitig geöffneter Dateien pro Prozess und die maximale Größe des geteilten Speichers (Shared Memory) verändert werden. Diese Veränderungen können aber wie bereits erwähnt nur mit speziellen Rechten vorgenommen werden. Informationen zum CD-ROM-Laufwerk, was es alles kann, können wieder für alle Anwender aufgelistet werden.
Bitte beachten Sie, dass diese Art von Veränderungen der Kernel-Parameter nur für den laufenden Betrieb gültig ist. Sobald Sie das System herunterfahren und wieder starten, sind die Werte wieder auf ihren Ursprungszustand gestellt. Wollen Sie eine dauerhafte Veränderung bewirken, müssen Sie sich die Datei sysctl.conf im Verzeichnis /etc vornehmen. Diese Datei können Sie auch mit dem gleichnamigen Kommando sysctl verändern. Wollen Sie z. B. mit sysctl autoeject verändern, gehen Sie wie folgt vor (root-Rechte):
# sysctl -w dev.cdrom.autoeject=0
dev.cdrom.autoeject = 0
# sysctl -w dev.cdrom.autoeject=1
dev.cdrom.autoeject = 1
Auf die Angaben von /proc/sys können Sie dabei verzichten, und anstelle eines Slashs wird ein Punkt verwendet.
Wollen Sie wissen, mit welchem Befehl der Kernel beim Booten gestartet wurde, können Sie ihn mit cmdline erfragen:
$ cat /proc/cmdline
root=/dev/hda6 vga=0x0314 hdc=ide-scsi hdclun=0 splash=silent
Oder Linux 2.6 mit LILO 22.3.4:
auto BOOT_IMAGE=2.6.4-HX ro root=301
Zu den verschiedenen Bootoptionen sei hier der Verweis auf die bootparam(7) Manual Page gegeben. Es gibt noch weitaus mehr zu den Kernel-Informationen zu sagen, aber das würde den Rahmen des Buches bei weitem sprengen und am Thema der Linux-Programmierung vorbeigehen.
4.4.1 /proc/locks
Mit dieser Datei werden alle Dateien angezeigt, die im Augenblick vom Kernel gesperrt werden (vgl. Kapitel 2 über flock() und lockf()). Diese Ausgabe enthält interne Kernel-Debugging-Daten und kann daher logischerweise je nach System stark variieren.
1: FLOCK ADVISORY WRITE 807 03:05:308731 0 EOF c2ac0 c0248 c2a220
2: POSIX ADVISORY WRITE 708 03:05:308720 0 EOF c2a1c c2ac4 c02548
In der ersten Spalte besitzt jeder Lock eine einmalige Zahl gefolgt vom Typ des Locks. Mögliche Ausgaben sind hier FLOCK (meist bei älteren UNIX-Datei-Locks mit dem Systemaufruf flock()) und POSIX (bei neueren POSIX-Locks mit dem Systemaufruf lockf()).
Der Wert ADVISORY der dritten Spalte bedeutet, dass ein weiterer Datenzugriff für andere Benutzer möglich ist, aber keine weiteren Lock-Versuche mehr erlaubt sind. Ein anderer Wert hierfür wäre MANDATORY, was bedeutet, dass hier keine Datenzugriffe mehr möglich sind, solange der Lock vorhanden ist. In der vierten Spalte befinden sich die Lese- oder Schreibrechte (READ, WRITE) des Eigentümers. Die fünfte Spalte enthält die PID des Lock-Eigentümers. Die ID der gelockten Datei finden Sie in der sechsten Spalte mit folgendem Format:
MAJOR-DEVICE:MINOR-DEVICE:INODE-NUMBER
Die Spalten sechs und sieben zeigen Anfang und Ende der gelockten Region. Im Beispiel gilt die Sperre vom Anfang 0 bis zum Ende (EOF) der Datei. Die letzten Spalten zeigen auf Kernel-interne Datenstrukturen für spezielle Debugging-Funktionen.
4.4.2 /proc/modules
In /proc/modules finden Sie eine Liste von allen Modulen, die vom System geladen wurden. Auch hierbei hängt die Ausgabe von den Einstellungen des Systems ab.
ide-cd 27008 0 (autoclean)
cdrom 28960 0 (autoclean) [ide-cd]
soundcore 4100 0 (autoclean)
agpgart 31072 0 (unused)
iscsi 32672 0 (unused)
scsi_mod 94424 1 [iscsi]
autofs 10628 0 (autoclean) (unused)
In der ersten Spalte befindet sich jeweils der Name des geladenen Moduls, gefolgt von der Speichergröße in Bytes. In der dritten Spalte wird angezeigt, wie oft das Modul gerade benutzt wird (usage count). In der letzten Spalte finden Sie die Module, die benötigt werden, damit andere Module funktionieren. Z. B. benötigt das Modul cdrom das Modul ide-cd, um ordentlich ausgeführt zu werden. »autoclean« gibt an, ob sich das Modul nach einer gewissen Zeit selbst deaktiviert, »unused«, dass es nicht benutzt wird.
/proc/modules in 2.6
In 2.6 sieht /proc/modules etwas anders aus; die Ausgabe von lsmod hat sich hingegen nicht geändert. Zunächst verschwunden sind autoclean und unused; modules selbst sieht in etwa so aus:
usb_storage 62400 0 - Live 0xd092e000
usbcore 85340 5 ehci_hcd,ohci_hcd,usb_storage, Live 0xd096c000
scsi_mod 58492 3 sd_mod,sg,usb_storage, Live 0xd0942000
ide_cd 34500 1 - Live 0xd0924000
cdrom 36128 1 ide_cd, Live 0xd091a000
Ähnlich wie in 2.4 finden sich hier Name des Moduls, Größe, der Usage Count, basierende Module, der Zustand (Loading, Unloading, Live = geladen) und die Adresse, wo das Modul geladen ist.
|