From 01ca5252e8884640a14d2df677c1d8bab10c62ac Mon Sep 17 00:00:00 2001 From: Jesse Smith Date: Sat, 14 Apr 2018 19:16:12 -0300 Subject: [PATCH] Added new manual page for the initctl named pipe. This provides information on how to send messages to the init command. --- man/initctl.5 | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 man/initctl.5 diff --git a/man/initctl.5 b/man/initctl.5 new file mode 100644 index 0000000..d8a435c --- /dev/null +++ b/man/initctl.5 @@ -0,0 +1,138 @@ +'\" -*- 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" + * 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 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 +.RE +.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. +.RE +.SH FILES +/run/initctl +/sbin/init +.SH AUTHOR +Jesse Smith +.SH "SEE ALSO" +init(8)