aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/pies.texi193
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile.am8
-rw-r--r--src/cmdline.opt6
-rw-r--r--src/pies.h2
-rw-r--r--src/sysvinit.c28
-rw-r--r--src/telinit.opt89
7 files changed, 268 insertions, 59 deletions
diff --git a/doc/pies.texi b/doc/pies.texi
index ae4a56a..1f162a2 100644
--- a/doc/pies.texi
+++ b/doc/pies.texi
@@ -1647,12 +1647,17 @@ component @var{tag} @{
# @xref{Prerequisites, dependents}.
dependents (@var{compnames});
# @r{List of flags.}
# @xref{flags}.
flags (@var{flags});
+
+ # @r{For @i{init} components: runlevels in which to start this}
+ # @r{component.}
+ # @xref{Runlevels}.
+ runlevels @var{string};
# @r{Listen on the given url.}
# @xref{Inetd-Style Components}.
socket @var{url};
# @r{Set socket type.}
@@ -1701,20 +1706,20 @@ component @var{tag} @{
# @r{For @samp{inetd} components:}
# @r{Text to send back if access is denied by ACL.}
# @xref{Inetd-Style Components, access-denied-message}.
access-denied-message @var{text};
- # @r{ACL for administrative access to this component.}
- # @FIXME-xref{Access to Components}.
+ # @r{ACL for administrative (read-write) access to this component.}
+ # @xref{Visibility}.
admin-acl @var{name};
# @r{or:}
admin-acl @{ @dots{} @}
# @r{ACL for read-only access to this component.}
- # @FIXME-xref{Access to Components}.
+ # @xref{Visibility}.
list-acl @var{name};
# @r{or:}
list-acl @{ @dots{} @}
# @r{ACL for this component.}
# @xref{ACL}.
@@ -2146,35 +2151,46 @@ seconds. This statement is reserved for use in the future. Currently
(as of version @value{VERSION}) it is a no-op.
@end deffn
The control interface is protected by three access control lists
(@xref{ACL}, for a discussion of their syntax).
-@deffn {Config: control} acl
- Controls who can connect to the control interface.
+@deffn {Config: control} acl @var{name}
+@deffnx {Config: control} acl @{ @dots{} @}
+ Controls who can connect to the interface. The first form refers to
+a named ACL that must have been defined earlier by @code{defacl}
+statement (@pxref{defacl}). Use the second form to define a new ACL
+in place.
@end deffn
-@deffn {Config: control} user-acl
+@deffn {Config: control} user-acl @var{name}
+@deffnx {Config: control} user-acl @{ @dots{} @}
Control interface provides two kinds of operations: @dfn{read-only}
(such as getting information about running components) and @dfn{write}
operations (such as stopping or restarting components).
- The @code{user-acl} controls read access to components that don't
-have per-component @code{user-acl} (@FIXME-pxref{per-component user-acl}).
+ The @code{user-acl} controls read access. Access to particular
+components can also be controlled individually, using the
+per-component @code{list-acl} statement (@pxref{Visibility, list-acl}).
@end deffn
-@deffn {Config: control} admin-acl
- Defines access control list for write access to the @command{pies}
-instance itself and to the components for which no specific
-@code{admin-acl} statements are supplied (@FIXME-pxref{per-component
-admin-acl}).
+@deffn {Config: control} admin-acl @var{name}
+@deffnx {Config: control} admin-acl @{ @dots{} @}
+ Controls write access to the @command{pies} instance itself and to
+the components for which no specific @code{admin-acl} statements are
+supplied (@pxref{Visibility, admin-acl}).
In particular, whoever passes @code{admin-acl} can issue commands
for stopping the instance and reloading its configuration.
@end deffn
+ When checking whether the user has a particular kind of access to a
+component, first the corresponding ACL from the @code{control} section
+is checked. If it allows access, then the per-component ACL is tried.
+If it allows access too, then the operation is permitted.
+
@deffn {Config: control} realm @var{name}
Defines the realm for basic authentication. Default value is @samp{pies}.
@end deffn
@node inetd
@section Using @command{inetd} Configuration Files
@@ -2451,12 +2467,21 @@ Sets the PID file name.
@end deffn
@deffn {Config} qotd-file @var{file-name}
Sets the name of the @samp{quotation-of-the-day} file.
@end deffn
+The following statements are retained for compatibility with earlier
+@command{pies} versions. They are silently ignored:
+
+@deffn {Config} control-file @var{arg}
+@end deffn
+
+@deffn {Config} stat-file @var{arg}
+@end deffn
+
@node Pies Debugging
@chapter Pies Debugging
@xopindex{debug, described}
The amount of debugging information produced by @command{pies} is configured
by the following statements:
@@ -2570,14 +2595,15 @@ UNIX socket for communication using @command{piesctl}.
@end table
@menu
* Runlevels::
* Init Process Configuration::
* Init Command Line::
-* piesctl telinit::
* Init Environment::
+* piesctl telinit::
+* telinit command::
@end menu
@node Runlevels
@section Runlevels
Runlevel determines the set of components to be run in normal state.
@@ -2596,13 +2622,13 @@ Multiuser mode.
Multiuser with X11.
@end table
@anchor{Ondemand runlevels}
Additionally, three special runlevels @samp{a}, @samp{b} and @samp{c}
can be used to start @dfn{on-demand} components without actually
-changing the runlevel. Once started, on-demain components persist
+changing the runlevel. Once started, on-demain components persist
through eventual runlevel changes.
@node Init Process Configuration
@section Init Process Configuration
@anchor{inittab}
The two configuration files are read in this order:
@@ -2753,24 +2779,45 @@ The default set up is equivalent to specifying
Stop parsing after this line. The remaining material is ignored.
@end table
Both the traditional @file{/etc/inittab} and pies-native
@file{/etc/pies.init} files are entirely equivalent, excepting that,
naturally, the latter is more flexible and gives much more
-possibilities in defining the system behavior. The inittab entry
-discussed above is equivalent to the following statement in
-@file{pies.init} file:
+possibilities in defining the system behavior. The declaration of a
+component in @file{/etc/pies.init} can contain all the statements
+discussed in @ref{Component Statement}. The only difference is that
+runlevels to start the component is must be specified:
+
+@deffn {Config: component} runlevels @var{string}
+Specifies the runlevel to start the component in. The @var{string}
+argument is a string of runlevel characters.
+@end deffn
+
+For example, the inittab entry discussed above is equivalent to the
+following statement in @file{pies.init} file:
@example
component @var{id} @{
mode @var{mode};
runlevels @var{runlevels};
command @var{command};
@}
@end example
+The default runlevel is specified in @file{/etc/pies.init} using
+the following construct:
+
+@deffn {Config} initdefault @var{rl}
+Declare the default runlevel. The argument is the runlevel name.
+E.g.
+
+@example
+initdefault 3;
+@end example
+@end deffn
+
If both @file{/etc/inittab} and @file{/etc/pies.init} are present, the
latter can declare components with the same @var{id} as the ones
declared in the former. In that case, the two entries will be merged,
the latter one overriding the former. Thus, @file{/etc/pies.init} can
be used to complement definitions in @file{inittab}. Consider, for
example the following inittab entry:
@@ -2819,12 +2866,38 @@ Initialize default runlevel @samp{S}.
@item -b
@itemx emergency
Run emergency shell @command{/sbin/sulogin}, prior to initialization.
@end table
+@node Init Environment
+@section Init Environment
+
+Programs run from @command{pies} init process inherit a basic
+environment consisting of the following variables:
+
+@table @option
+@item PREVLEVEL=@var{L}
+Previous runlevel, or letter @samp{N} if the runlevel hasn't been
+changed since startup.
+
+@item RUNLEVEL=@var{L}
+Current runlevel.
+
+@item CONSOLE=@var{device}
+Pathname of the console device file.
+
+@item INIT_VERSION="GNU Pies @value{VERSION}"
+Version of @command{pies}.
+
+@item PATH=/bin:/usr/bin:/sbin:/usr/sbin
+@end table
+
+Once the system is booted up, the environment can be controlled using
+the @command{piesctl telinit environ} (or @command{pies -T -e}) command.
+
@node piesctl telinit
@section piesctl telinit
@deffn {Telnit Runlevel} piesctl telinit runlevel
Report the runlevel and state of the process 1.
@end deffn
@@ -2844,37 +2917,78 @@ hold at most 32 variables.
@end deffn
@deffn {Telinit Env} piesctl telinit environ unset @var{NAME}
Unset variable @var{NAME}.
@end deffn
-@node Init Environment
-@section Init Environment
+@node telinit command
+@section The Telinit Command
-Programs run from @command{pies} init process inherit a basic
-environment consisting of the following variables:
+@xopindex{telinit option, introduced}
+ When given the @option{-T} (@option{--telinit}) option,
+@command{pies} emulates the behavior of the traditional
+@command{telinit} command. This is a legacy way of communicating with
+the init process. The commands are sent via named pipe
+@file{/dev/initctl}. When the @option{-T} option is given, the rest
+of command line after it is handled as @command{telinit} options. The
+following command:
-@table @option
-@item PREVLEVEL=@var{L}
-Previous runlevel, or letter @samp{N} if the runlevel hasn't been
-changed since startup.
+@example
+pies -T [-t @var{n}] @var{r}
+@end example
-@item RUNLEVEL=@var{L}
-Current runlevel.
+@noindent
+tells init process to switch to runlevel @var{r}. Possible values for
+@var{r} are:
-@item CONSOLE=@var{device}
-Pathname of the console device file.
+@table @asis
+@item 0 to 9
+Instructs init to switch to the specified runlevel.
+@item S or s
+Tells init to switch to the single user mode.
+@item a, b, or c
+Tells init to enable on-demand components with the specified
+runlevel. The actual runlevel is not changed.
+@item Q or q
+Tells init to rescan configuration files.
+@end table
-@item INIT_VERSION="GNU Pies @value{VERSION}"
-Version of @command{pies}.
+The @option{-t} (@option{--timeout}) option sets the time to wait
+for processes to terminate after sending them the SIGTERM signal. Any
+processes that remain running after @var{n} seconds will be sent the
+SIGKILL signal. The default value is 5 seconds.
-@item PATH=/bin:/usr/bin:/sbin:/usr/sbin
-@end table
+This usage is equivalent to the @command{piesctl telinit runlevel}
+command (@pxref{piesctl telinit}).
-Once the system is booted up, the environment can be controlled using
-the @command{piesctl telinit environ} command.
+The @option{-e} (@option{--environment}) option modifies the init
+process environment. Its argument is either a variable assignment
+@samp{@var{name}=@var{value}} to set a variable, or the name of a
+variable to unset it. Several @option{-e} options can be given to
+process multiple variables in a single command. Note, however, that
+given @var{n} @option{-e} options, the total length of their arguments
+is limited to 367 - @var{n} bytes.
+
+This option provides a limited subset of the functionality offered by
+the @command{piesctl telinit environ} command.
+
+The table below summarizes all options available in @option{telinit}
+mode:
+
+@table @option
+@item -t @var{n}
+Wait @var{n} seconds for processes to terminate after sending them the
+SIGTERM signal. Any processes that remain running after that time
+will be sent the SIGKILL signal. The default value is 5 seconds.
+
+@item -e @var{var}=@var{value}
+Define environment variable @var{var} as having value @var{value}.
+
+@item -e @var{var}
+Unset environment variable @var{var}.
+@end table
@node Configuration Examples
@chapter Configuration Examples
In this section we provide several examples of working @command{pies}
configuration files.
@@ -3240,12 +3354,19 @@ arguments, dependencies for each component are listed. @xref{trace-depend}.
@opsummary{trace-prereq}
@item --trace-prereq
List prerequisites for components named in the command line. Without
arguments, prerequisites for each component are listed. @xref{trace-prereq}.
+@opsummary{telinit}
+@item --telinit
+@item -T
+Emulate the @command{telinit} legacy interface. The rest of command
+line following this option is processed as @command{telinit} options.
+@xref{telinit command}, for a detailed description of these.
+
@item -E
Preprocess configuration file and exit. @xref{Preprocessor}.
@opsummary{force}
@item --force
Force startup even if another instance may be running.
diff --git a/src/.gitignore b/src/.gitignore
index a83b9ab..3bf90ef 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -5,6 +5,7 @@ meta1gram.h
meta1gram.output
meta1lex.c
pies
pies.rc
piesctl
piesctl-cl.h
+telinit.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 6515804..b0e9b6f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,26 +38,28 @@ pies_SOURCES = \
noinst_HEADERS = \
acl.h\
cmdline.h\
meta1parse.h\
pies.h\
prog.h\
- piesctl-cl.h
+ piesctl-cl.h\
+ telinit.h
-BUILT_SOURCES=cmdline.h piesctl-cl.h
+BUILT_SOURCES=cmdline.h piesctl-cl.h telinit.h
incdir=$(pkgdatadir)/$(VERSION)/include
inc_DATA = pp-setup
-EXTRA_DIST = cmdline.opt piesctl-cl.opt pp-setup inetd.in
+EXTRA_DIST = cmdline.opt piesctl-cl.opt telinit.opt pp-setup inetd.in
SUFFIXES=.opt .c .h
.opt.h:
$(AM_V_GEN)m4 -s $(top_srcdir)/@GRECS_SUBDIR@/build-aux/getopt.m4 $< > $@
cmdline.h: cmdline.opt
piesctl-cl.h: piesctl-cl.opt
+telinit.h: telinit.opt
pies_LDADD = \
../ident/libident.a\
../lib/libpies.a\
@GRECS_LDADD@\
../gnu/libgnu.a\
diff --git a/src/cmdline.opt b/src/cmdline.opt
index 7d6f7d4..d8bd02f 100644
--- a/src/cmdline.opt
+++ b/src/cmdline.opt
@@ -109,17 +109,17 @@ OPTION(lint,t,,
[<parse configuration file and exit>])
BEGIN
log_to_stderr_only = 1;
lint_mode = 1;
END
-OPTION(telinit,T,RUNLEVEL,
- [<emulate telinit command>])
+OPTION(telinit,T,,
+ [<telinit command: run "pies -T --help" for help>])
BEGIN
log_to_stderr_only = 1;
- exit (telinit (optarg));
+ exit (telinit (argc - (optind - 1), argv + (optind - 1)));
END
GROUP(Preprocessor)
OPTION(include-directory,I,DIR,
[<add include directory>])
diff --git a/src/pies.h b/src/pies.h
index 4eb2aca..b0cc746 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -532,13 +532,13 @@ struct inetd_builtin *inetd_builtin_lookup (const char *service, int socktype);
/* sysvinit.c */
void sysvinit_begin (void);
int is_comp_wait (struct component *comp);
int is_valid_runlevel (int c);
int console_open (int mode);
-int telinit (const char *arg);
+int telinit (int argc, char **argv);
int inittab_parse (const char *file);
int sysvinit_sigtrans (int sig, int *pact);
void sysvinit_runlevel_setup (int mask);
void sysvinit_sysdep_begin (void);
void sysvinit_power (void);
diff --git a/src/sysvinit.c b/src/sysvinit.c
index a150058..9043619 100644
--- a/src/sysvinit.c
+++ b/src/sysvinit.c
@@ -526,12 +526,14 @@ sysvinit_fifo_handler (int fd, void *data)
if (buf.req.magic != INIT_MAGIC)
logmsg (LOG_ERR, _("got invalid initreq"));
else
{
debug (1, ("INITREQ: cmd=%d, runlevel=%d, sleeptime=%d",
buf.req.cmd, buf.req.runlevel, buf.req.sleeptime));
+ if (buf.req.sleeptime > 0)
+ shutdown_timeout = buf.req.sleeptime;
switch (buf.req.cmd)
{
case INIT_CMD_RUNLVL:
buf.req.runlevel = toupper (buf.req.runlevel);
switch (buf.req.runlevel)
{
@@ -904,49 +906,43 @@ is_comp_wait (struct component *comp)
return 1;
default:
break;
}
return 0;
}
-
+
+#include "telinit.h"
+
int
-telinit (const char *arg)
+telinit (int argc, char **argv)
{
int fd;
struct sysvinit_request req;
-
- if (arg[1] || !is_valid_runlevel (*arg))
- {
- logmsg (LOG_CRIT, "invalid argument");
- exit (EX_USAGE);
- }
+
memset (&req, 0, sizeof (req));
req.magic = INIT_MAGIC;
- req.cmd = INIT_CMD_RUNLVL;
- req.runlevel = *arg;
-#if 0
- req.sleeptime = sltime;
-#endif
+
+ telinit_parser (&req, argc, argv);
signal (SIGALRM, SIG_DFL);
alarm (5);
fd = open (init_fifo, O_WRONLY);
if (fd < 0)
{
logmsg (LOG_ERR, _("cannot open %s: %s"), init_fifo, strerror (errno));
- exit (EX_UNAVAILABLE);
+ return EX_UNAVAILABLE;
}
if (write (fd, &req, sizeof (req)) != sizeof (req))
{
logmsg (LOG_ERR, _("error writing to %s: %s"),
init_fifo, strerror (errno));
- exit (EX_UNAVAILABLE);
+ return EX_UNAVAILABLE;
}
alarm (0);
close (fd);
- exit (0);
+ return 0;
}
static char *
getfld (char *str, char **endp)
{
char *p;
diff --git a/src/telinit.opt b/src/telinit.opt
new file mode 100644
index 0000000..f052a53
--- /dev/null
+++ b/src/telinit.opt
@@ -0,0 +1,89 @@
+/* This file is part of GNU Pies. -*- c -*-
+ Copyright (C) 2016 Sergey Poznyakoff
+
+ GNU Pies 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 3, or (at your option)
+ any later version.
+
+ GNU Pies 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 GNU Pies. If not, see <http://www.gnu.org/licenses/>. */
+
+OPTIONS_COMMAND_BEGIN("pies",
+ [<>],
+ [<send command to init process via the legacy interface>],
+ [<[RUNLEVEL]>],
+ [<gnu>],
+ [<noversion>])
+
+OPTION(timeout,t,[<SECONDS>],
+ [<set interval between sending TERM and KILL signals>])
+BEGIN
+ char *p;
+ errno = 0;
+ shutdown_timeout = strtoul (optarg, &p, 0);
+ if (*p || errno)
+ {
+ logmsg (LOG_ERR, _("invalid number: %s"), optarg);
+ exit (EX_USAGE);
+ }
+END
+
+OPTION(environment,e,[<VAR=[VAL]>],[<change environment>])
+BEGIN
+ size_t len = strlen (optarg);
+ if (envsize + len + 2 > sizeof(req->data))
+ {
+ logmsg (LOG_ERR, _("-e argument too long"));
+ exit (EX_USAGE);
+ }
+ memcpy (req->data + envsize, optarg, len);
+ envsize += len;
+ req->data[envsize++] = 0;
+END
+
+OPTIONS_END
+
+static void
+telinit_parser (struct sysvinit_request *req, int argc, char *argv[])
+{
+ int i;
+ char *cmds[] = { "-T", NULL };
+ size_t envsize = 0;
+
+ proginfo.subcmd = cmds;
+ GETOPT(argc, argv, i);
+ argc -= i;
+ argv += i;
+ if (envsize)
+ {
+ req->data[envsize++] = 0;
+ req->cmd = INIT_CMD_SETENV;
+ if (argc)
+ {
+ logmsg (LOG_ERR, _("too many arguments"));
+ exit (EX_USAGE);
+ }
+ }
+ else
+ {
+ if (argc != 1)
+ {
+ logmsg (LOG_ERR, _("bad number of arguments"));
+ exit (EX_USAGE);
+ }
+ if (argv[0][1] || !is_valid_runlevel (argv[0][0]))
+ {
+ logmsg (LOG_ERR, _("invalid runlevel: %s"), argv[0]);
+ exit (EX_USAGE);
+ }
+ req->cmd = INIT_CMD_RUNLVL;
+ req->runlevel = argv[0][0];
+ req->sleeptime = shutdown_timeout;
+ }
+}

Return to:

Send suggestions and report system problems to the System administrator.