2018-04-15 03:46:12 +05:30
|
|
|
'\" -*- coding: UTF-8 -*-
|
|
|
|
.\" Copyright (C) 2018 Jesse Smith
|
|
|
|
.\"
|
|
|
|
.\" This program is free software; you can redistribute it and/or modify
|
|
|
|
.\" it under the terms of the GNU General Public License as published by
|
|
|
|
.\" the Free Software Foundation; either version 2 of the License.
|
|
|
|
.\"
|
|
|
|
.\" This program is distributed in the hope that it will be useful,
|
|
|
|
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
.\" GNU General Public License for more details.
|
|
|
|
.\"
|
|
|
|
.\" You should have received a copy of the GNU General Public License
|
|
|
|
.\" along with this program; if not, write to the Free Software
|
|
|
|
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
.\"
|
|
|
|
.TH INITCTL 5 "April 13, 2018" "" "Linux System Administrator's Manual"
|
|
|
|
.SH NAME
|
|
|
|
initctl \- /run/initctl is a named pipe which passes commands to SysV init.
|
|
|
|
.SH SYNOPSIS
|
|
|
|
/run/initctl
|
|
|
|
.SH DESCRIPTION
|
|
|
|
|
|
|
|
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"
|
2020-11-18 06:01:37 +05:30
|
|
|
* aren't in a separate struct in the union.
|
2018-04-15 03:46:12 +05:30
|
|
|
*
|
|
|
|
* 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 character.
|
|
|
|
|
|
|
|
.SH EXAMPLES
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
.nf
|
|
|
|
struct init_request request; /* structure defined above */
|
|
|
|
int fd; /* file descriptor for pipe */
|
|
|
|
|
|
|
|
memset(&request, 0, sizeof(request)); /* initialize structure */
|
|
|
|
request.magic = 0x03091969; /* magic number required */
|
|
|
|
request.cmd = 6; /* 6 is to set a variable */
|
|
|
|
sprintf(request.data, "VARIABLE=VALUE"); /* set VAR to VALUE in init */
|
|
|
|
|
|
|
|
if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) /* open pipe for writing */
|
|
|
|
{
|
|
|
|
size_t s = sizeof(request); /* size of structure to write */
|
|
|
|
void *ptr = &request; /* temporary pointer */
|
|
|
|
write(fd, ptr, s); /* send structure to the pipe */
|
|
|
|
close(fd); /* close the pipe when done */
|
|
|
|
}
|
|
|
|
.fi
|
|
|
|
|
|
|
|
.sp
|
|
|
|
.SH NOTES
|
|
|
|
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.
|
|
|
|
.PP
|
|
|
|
The commands passed through the /run/initctl pipe must be sent in a specific
|
|
|
|
binary format and be of a specific length. Larger data structures or ones
|
|
|
|
not using the proper format will be ignored. Typically, only root has the
|
|
|
|
ability to write to the initctl pipe for security reasons.
|
2018-04-18 04:14:50 +05:30
|
|
|
.PP
|
|
|
|
The /run/initctl pipe can be closed by sending init (PID 1) the SIGUSR2
|
|
|
|
signal. This closes the pipe and leaves it closed. This may be useful
|
|
|
|
for making sure init is not keeping any files open. However, when the
|
|
|
|
pipe is closed, init no longer receives signals, such as those sent by
|
|
|
|
shutdown or telinit. In other words if we close the pipe, init cannot
|
|
|
|
change its runlevel directly. The pipe may be re-opened by sending init (PID 1)
|
|
|
|
the SIGUSR1 signal.
|
|
|
|
.PP
|
|
|
|
If the /run/initctl pipe is closed then it may still be possible to bring
|
|
|
|
down the system using the shutdown command's -n flag, but this is not
|
|
|
|
always clean and not recommended.
|
2018-04-15 03:46:12 +05:30
|
|
|
.SH FILES
|
|
|
|
/run/initctl
|
|
|
|
/sbin/init
|
|
|
|
.SH AUTHOR
|
|
|
|
Jesse Smith <jsmith@resonatingmedia.com>
|
|
|
|
.SH "SEE ALSO"
|
|
|
|
init(8)
|