INITCTL(5)

BEZEICHNUNG
initctl - /run/initctl ist eine benannte Pipe, die Befehle an SysV-Init übergibt

ÜBERSICHT
/run/initctl

BESCHREIBUNG
Dieses Dokument beschreibt die durch SysV init unter /run/initctl eingerichtete Kommunikations-Pipe. Diese benannte Pipe erlaubt es Programmen mit geeigneten Berechtigungen (typischerweise haben Programme, die durch Root ausgeführt werden, Lese- und Schreibberechtigungen auf die Pipe), Signale an das init-Programm (PID 1) zu senden. In der Handbuchseite von init wurde bis vor kurzem noch empfohlen, dass Benutzer, die verstehen wollen, wie Meldungen an init gesendet werden, doch den Quellcode von init lesen sollten. Dies ist aber nicht wirklich praxistauglich. Nachrichten, die an die Pipe zur Kommunikation mit init gesandt werden, müssen einem bestimmten Format folgen. Dieses Format ist als eine C-Struktur definiert und die technische Detailansicht wird im Folgenden dargestellt: /*
 * Aufgrund veralteter Schnittstellen sind »runlevel« und »sleeptime«
 * nicht im gleichen Struct in der Union.
 *
 * Die komischen Größen stammen daher, dass Init erwartet, dass die
 * gesamte Struct 384 byte groß ist.
 */ struct init_request {
        int magic; /* Magische Zahl */
        int cmd; /* Art der Anfrage */
        int runlevel; /* Ziel-Runlevel */
        int sleeptime; /* Zeit zwischen TERM und KILL */
        union {
                struct init_request_bsd bsd;
                char data[368];
        } i; }; Lassen Sie uns die init_request-Struktur zeilenweise betrachten. Die erste Variable (die »magische« Zahl) muss den Wert 0x03091969 haben. Das Programm init weiß dann, dass nur Programme mit Root-Zugriff, die diese magische Zahl senden, zur Kommunikation mit Init autorisiert sind. Die Variable cmd ist (derzeit) ein Wert im Bereich 0-8. Diese Variable cmd teilt init mit, was getan werden soll. Hier sind die möglichen Optionen: 1 - Den aktuellen Runlevel setzen, festgelegt durch die Variable »runlevel«. 2 - Der Strom wird bald ausfallen (möglicherweise wegen eines niedrigen Akkustandes), vorbereiten zum Herunterfahren. 3 - Der Strom fällt aus, sofort herunterfahren. 4 - Die Stromversorgung ist ok, Herunterfahren abbrechen. 6 - Setzt eine Umgebungsvariable auf einen Wert, der in der Variablen
    data in dieser Struktur festgelegt ist. Andere Optionen cmd können später zu init hinzugefügt werden. Beispielsweise sind die Befehlswerte 0, 5 und 7 definiert, derzeit aber nicht implementiert. Die Variable runlevel legt den Runlevel fest, zu dem gewechselt werden soll (0-6). Die Variable sleeptime wird verwandt, wenn init mitgeteilt werden soll, die Wartezeit zwischen dem Senden von SIGTERM and SIGKILL während des Herunterfahrprozesses zu ändern. Eine Änderung zur Laufzeit ist noch nicht implementiert. Die Variable data (in der Union) kann zur Übergabe verschiedener Daten, die init benötigen könnte, um die Anfrage zu bearbeiten, verwandt werden. Beispielsweise zum Setzen von Umgebungsvariablen. Beim Setzen einer Umgebungsvariablen mittels der Pipe /run/initctl von init sollte die Variable data das Format VARIABLE=WERT haben. Die Zeichenkette sollte mit einem NULL-Zeichen beendet werden.

BEISPIELE
Das folgende C-Code-Beispiel zeigt, wie eine Umgebungsvariablen-Anfrage mittels der Pipe /run/initctl an den init-Prozess gesandt wird. Dieses Beispiel ist vereinfacht und überspringt die Fehlerprüfung. Ein vollständigeres Beispiel kann in der Funktion init_setnv() im Programm shutdown.c gefunden werden.
struct init_request     request;           /* oben definierte Struktur */
int                     fd;                /* Dateideskriptor für die Pipe */
memset(&request, 0, sizeof(request));      /* Struktur initialisieren */
request.magic = 0x03091969;                /* benötigte magische Zahl */
request.cmd = 6;                           /* 6 ist zum Setzen einer Variablen */
sprintf(request.data, "VARIABLE=WERT");   /* setzt VAR auf WERT in init */
if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) /* Pipe zum Schreiben öffnen */
{
    size_t s  = sizeof(request);           /* Größe der zu schreibenden Struktur */
    void *ptr = &request;                  /* temporärer Zeiger */
    write(fd, ptr, s);                     /* Struktur an die Pipe schicken */
    close(fd);                             /* Pipe schließen, wenn fertig */
}

ANMERKUNGEN
Normalerweise würde die Pipe /run/initctl nur von systemnahen Programmen zur Anfrage von durch die Stromversorgung ausgelöstem Herunterfahren oder Änderungen des Runlevels verwandt, wie bei telinit. Meistens ist es nicht notwendig, direkt mit init zu kommunizieren. Dies ermöglicht aber einen erweiterbaren Ansatz, so dass init beigebracht werden kann, weitere Befehle zu lernen.

Die über die Pipe /run/initctl gesandten Befehle müssen in einem bestimmten Binärformat und mit einer bestimmten Länge gesandt werden. Größere Datenstrukturen oder solche, die nicht das korrekte Format verwenden, werden ignoriert. Typischerweise hat aus Sicherheitsgründen nur der Systemverwalter die Möglichkeit, in die initctl-Pipe zu schreiben.

Die Pipe /run/initctl kann durch Senden des Signals SIGUSR2 an init (PID 1) geschlossen werden. Damit wird die Pipe geschlossen und verbleibt geschlossen. Das ist nützlich, um sicherzustellen, dass init keine Dateien offenbehält. Wenn die Pipe allerdings geschlossen ist, dann empfängt init keine Signale mehr, wie die von shutdown(8) oder telinit(8) gesandten. Mit anderen Worten: Wird die Pipe geschlossen, kann init seinen Runlevel nicht mehr direkt ändern. Die Pipe kann wieder geöffnet werden, indem init (PID 1) das Signal SIGUSR1 gesandt wird.

Falls die Pipe /run/initctl geschlossen ist, könnte das System immer noch über den Schalter -n von shutdown(8) heruntergefahren werden; dies ist aber nicht sauber und wird nicht empfohlen.

DATEIEN
/run/initctl /sbin/init

AUTOR
Jesse Smith (jsmith@resonatingmedia.com)

SIEHE AUCH
init(8)