From 266671c968306f28557290de75f703442b001560 Mon Sep 17 00:00:00 2001 From: Jesse Smith Date: Sun, 8 Apr 2018 22:03:07 -0300 Subject: [PATCH] Added documentation page for initctl (/run/initctl). --- doc/initctl | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 doc/initctl diff --git a/doc/initctl b/doc/initctl new file mode 100644 index 0000000..734ca74 --- /dev/null +++ b/doc/initctl @@ -0,0 +1,94 @@ +This document describes the communiction pipe set up by SysV init +at /run/initctl. This named pipe allows programs with the proper +permissions (typically programs run by root have read+write access to +the pipe) to send signals to the init program (PID 1). + +The init manual page has, up until recently, simply stated +that people wishing to understand how to send messages to init +should read the init program's source code, but that is not usually practical. + +Messages sent to the pipe to talk to init must have a special format. +This format is defined as a C structure and the technical break-down +is presented here: + +/* + * Because of legacy interfaces, "runlevel" and "sleeptime" + * aren't in a seperate struct in the union. + * + * The weird sizes are because init expects the whole + * struct to be 384 bytes. + */ +struct init_request { + int magic; /* Magic number */ + int cmd; /* What kind of request */ + int runlevel; /* Runlevel to change to */ + int sleeptime; /* Time between TERM and KILL */ + union { + struct init_request_bsd bsd; + char data[368]; + } i; +}; + + +Let's go through the init_request structure one line at a time. The +first variable, the "magic" number must be of the value 0x03091969. +The init program then knows that only programs with root access which send +this magic number are authorized to communicate with init. + +The cmd variable is a value in the range of 0-8 (currently). This cmd +variable tells init what we want it to do. Here are the possible options: + +1 - Set the current runlevel, specified by the runlevel variable. +2 - The power will fail soon (probably low battery) prepare to shutdown. +3 - The power is failing, do shutdown immediately. +4 - The power is okay, cancel shutdown. +6 - Set an environment variable to a value to be specified in + the data variable of this structure. + +Other cmd options may be added to init later. For example, command values +0, 5 and 7 are defined but currently not implemented. + +The runlevel variable will specify the runlevel to switch to (0-6). + +The sleeptime variable is to be used when we want to tell init to change +the time spent waiting between sending SIGTERM and SIGKILL during the +shutdown process. Changing this at run time is not yet implemented. + +The data variable (in the union) can be used to pass misc data which init +might need to process our request. For example, when setting environment +variables. + +When setting an environment variable through init's /run/initctl pipe, +the data variable should have the format VARIABLE=VALUE. The string +should be terminated with a NULL '\0' character. + + +The following C code example shows how to send a set environment variable +request to the init process using the /run/initctl pipe. This example +is simplified and skips the error checking. A more comlpete example can be +found in the shutdown.c program's init_setnv() function. + + +struct init_request request; /* this is the structure defined above */ +int fd; /* file descriptor for the pipe */ + +memset(&request, 0, sizeof(request)); /* initialize structure */ +request.magic = 0x03091969; /* this magic number must be included */ +request.cmd = 6; /* 6 is the command to set a variable */ +sprintf(request.data, "VARIABLE=VALUE"); /* set VARIABLE to VALUE in init */ +if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) /* open pipe for writing */ +{ + size_t s = sizeof(request); /* size of the structure to write */ + void *ptr = &request; /* temporary pointer */ + write(fd, ptr, s); /* send the structure to the pipe */ + close(fd); /* close the pipe when done */ +} + + + +Usually the /run/initctl pipe would only be used by low-level programs to +request a power-related shutdown or change the runlevel, like telinit +would do. Most of the time there is no need to talk to init directly, but +this gives us an extenable approach so init can be taught how to learn +more commands. +