Added documentation page for initctl (/run/initctl).
This commit is contained in:
parent
a4508479f5
commit
266671c968
94
doc/initctl
Normal file
94
doc/initctl
Normal file
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user