Compare commits

..

14 Commits
0.28 ... 0.30

Author SHA1 Message Date
William Hubbs
a09b8af3f9 Update ChangeLog 2017-09-06 17:31:01 -05:00
William Hubbs
382efdbfcb add quiet parameter to run_stop_schedule 2017-09-06 17:22:35 -05:00
William Hubbs
17b5cc78d3 add retry option to supervise-daemon
The --retry option for supervise-daemon defines how the supervisor will
attempt to stop the child process it is monitoring. It is defined when
the supervisor is started since stopping the supervisor just sends a
signal to the active supervisor.

This fixes #160.
2017-09-06 17:22:21 -05:00
William Hubbs
36a0ab9054 make run_stop_schedule accept a pid instead of a pid file 2017-08-25 11:36:45 -05:00
William Hubbs
27c2bd997d version 0.30 2017-08-24 11:44:32 -05:00
William Hubbs
d7938f54f2 start-stop-daemon: move --retry processing code to a shared module
This was part of start-stop-daemon; however, it needs to be shared in
order to be used by supervise-daemon.
2017-08-24 11:34:18 -05:00
William Hubbs
cfbe9c2ede move get_pid function to a shared file 2017-08-23 14:36:50 -05:00
William Hubbs
df28002b72 Update ChangeLog 2017-08-16 11:38:37 -05:00
William Hubbs
66ed8082d0 sh/openrc-run: source service script before ulimit is processed
This is needed to allow the service script author to set a default for
rc_ulimit inside the service script.
2017-08-15 17:15:14 -05:00
William Hubbs
c2d256bafb man/openrc-run.8: document fstabinfo and mountinfo
X-Gentoo-Bug: 592374
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=592374
2017-07-26 11:31:34 -05:00
William Hubbs
f48d9c33a5 man/openrc-run.8: document _pre and _post functions
Fixes https://github.com/openrc/openrc/issues/155.
2017-07-25 13:54:12 -05:00
Jason Graham
6d4e843397 fix ENT macro usage
X-Gentoo-Bug: 624796
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=624796
2017-07-24 18:24:18 -05:00
William Hubbs
0513cd3964 version 0.29 2017-07-24 17:28:54 -05:00
John R. Graham
72bb2e57de Typo fix
X-Gentoo-Bug: 624908
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=624908
2017-07-24 17:24:13 -05:00
15 changed files with 694 additions and 828 deletions

460
ChangeLog
View File

@@ -1,3 +1,111 @@
commit 382efdbfcb99703d03211efacd800c9575e64230
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
add quiet parameter to run_stop_schedule
commit 17b5cc78d35dc5fe4904e5951715c3e0d07d6343
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
add retry option to supervise-daemon
The --retry option for supervise-daemon defines how the supervisor will
attempt to stop the child process it is monitoring. It is defined when
the supervisor is started since stopping the supervisor just sends a
signal to the active supervisor.
This fixes #160.
commit 36a0ab9054512ade413226fb8e8b28060045e9a4
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
make run_stop_schedule accept a pid instead of a pid file
commit 27c2bd997d5173aa30844a16bc22dc8caab09f8c
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
version 0.30
commit d7938f54f29193251e083ad35a7d464949829096
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
start-stop-daemon: move --retry processing code to a shared module
This was part of start-stop-daemon; however, it needs to be shared in
order to be used by supervise-daemon.
commit cfbe9c2ede24dac530ef58e5c35bd57f22a788a3
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
move get_pid function to a shared file
commit df28002b728b033c00c2da64dedf2bcd4ab5e11b
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
Update ChangeLog
commit 66ed8082d0c865a0b4f4cc436cf9e13351e3d6fe
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
sh/openrc-run: source service script before ulimit is processed
This is needed to allow the service script author to set a default for
rc_ulimit inside the service script.
commit c2d256bafb9d1dfafbfd0846c035c5d26f7449c8
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
man/openrc-run.8: document fstabinfo and mountinfo
X-Gentoo-Bug: 592374
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=592374
commit f48d9c33a5c708c871d6657a39485d1c0c735548
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
man/openrc-run.8: document _pre and _post functions
Fixes https://github.com/openrc/openrc/issues/155.
commit 6d4e8433974fd8567885635ae0454031290f96b1
Author: Jason Graham <jgraha8@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
fix ENT macro usage
X-Gentoo-Bug: 624796
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=624796
commit 0513cd3964a9564e0ba39b50aa8ebd3d7e9a3920
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
version 0.29
commit 72bb2e57de935ab46ad000f97a5720265bed9342
Author: John R. Graham <john_r_graham@gentoo.org>
Commit: William Hubbs <w.d.hubbs@gmail.com>
Typo fix
X-Gentoo-Bug: 624908
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=624908
commit 84c5da30695db89d686d3c28c7cacdf172cbf429
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
Update ChangeLog
commit b35099cb707e333b6b8d30d956ffa93bcd2da0ab
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
@@ -1318,355 +1426,3 @@ Commit: William Hubbs <w.d.hubbs@gmail.com>
This reworks the logic so that the warning about configuring the
binfmt_misc module is only displayed if the module actually has to be
loaded.
commit d4d559323819c8a5279bf197d8d3ff80f1e28cdc
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
sh/openrc-run.sh: read global configuration settings first
X-Gentoo-Bug: 503134
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=503134
commit d5db5489be135ae9295e378e789b4b7b13367fdd
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
init.d/swap: do not unmount all tmpfs file systems
X-Gentoo-Bug: 568162
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=568162
commit d06db93d5954460668d09cf6ef2fc401ee9d981c
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
remove swapfiles service
The swapfiles service was basically a copy of the swap service, so this
commit consolidates the functionality into the swap service.
X-Funtoo-Bug-URL: https://bugs.funtoo.org/browse/FL-2523
X-Gentoo-Bug: 568162
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=568162
commit 8c14d0c476e06fff7598c526e26b6a13d53a4600
Author: Martin Väth <martin@mvath.de>
Commit: Martin Väth <martin@mvath.de>
Fix typo in RC_UNAME check of modules-load
The $RC_UNAME "Linux" had been misspelled as "linux".
As a consequence, entries in e.g. /etc/modules-load.d failed to
load any module succesfully under Linux(!)
commit 04debf6f25b3748a101b61cb85f78617dbe5be6e
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
another news typo fix
commit c289774b00d0d7dc38fdc1f0f623569bd184a4b1
Author: Doug Freed <dwfreed@mtu.edu>
Commit: Doug Freed <dwfreed@mtu.edu>
modules-load: handle comments better
This handles comments without a trailing space after the comment
character.
Reported-By: josef64
commit 9dd8ee330d8a4449c937bc95fc8393a55913c8d1
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
typo fix
commit 5d5856c193768d24f11d5f0533e48c39526aef5c
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
Update news file
Add information on modules-load service and more explanation about
dealing with the rc -> openrc and runscript -> openrc-run transitions.
commit 686e172207ac9e23560da18a6f877be777ded935
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
init.d: add modules-load to ignore patterns
commit fef6268f8d03e3ab3e2564cbf3634d0db2bcd99e
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
modules-load.d: cleanups
Move list of directories to a local variable and create the fn variable
to use for an individual file name rather than using path.
commit 556dbff99d53cdcc00e6b1ec67e1679f72b6f284
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
Add modules-load.d support
commit 69ac78d76a31d843c004717eb6aa6a77bb4c9a8e
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
openrc-run: make runscript warning respect quiet option
X-Gentoo-Bug: 591414
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=591414
commit 4018dfc8de4818101c336ff8bcf0f4762b318c6a
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
init.d/hostname: do not use localhost as a default hostname
This allows the operating system default hostname to be used if no
hostname is configured.
commit 353bb9bc9a0ab3c6650d72d2ceb14c990762a2a0
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
init.d/hostname: add support for /etc/hostname
commit 73cdf10f1f513be7b5dec4f1cc91e0c68cda689b
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
Deprecate automatic loading of modules
In the hwclock, procfs and sysfs service scripts, we automatically
attempt to load the kernel modules we need before we take any action. We
shouldn't do this, because there are systems which do not use kernel
modules and do not have the kmod package installed.
With this change, we continue to load the modules ourselves, but we warn
the admin that they need to be added to /etc/conf.d/modules or built
into the kernel.
In the future, this automatic loading will be dropped.
X-Gentoo-Bug: 342313
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=342313
commit 1a55d46645b376cd27f394796934150120a08387
Author: Raymond Jennings <shentino@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
local.d/README: typo fix
X-Gentoo-Bug: 591258
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=591258
commit cae3976ef1276ce33aa7e49474f13499a48a3fe6
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
init.d: Add runsvdir to ignore patterns
commit da28a3d367b6078deda6bc205806b43b971e67a9
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
init.d: initial service adjustments for docker support
Add -docker keyword to the same scripts that have -lxc keyword.
commit ca8c29ee60b0e8ca89091aaf801725bd71e28001
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
librc: fix Docker auto detection
The original auto detection of Docker containers assumed the presence of
a container environment variable. However, Docker-1.12 does not
implement this, and I'm not sure which versions of docker implemented
it.
The new test is for the presence of a file named .dockerenv in the
root directory.
commit f62253b8334a85dac4671e42817b96a3bedd1881
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
Add support for runit
X-Gentoo-Bug: 501364
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=501364
commit f2c2e2dd5a5e0a22da4dcabea6615d0f4697a962
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
init.d/sysctl.in: typo fix
commit 94b98430cb83a8f4e62d837100fc357e9eb12ca6
Author: Kenneth Lakin <kennethlakin@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
start-stop-daemon: Add SSD_IONICELEVEL
This is the disk IO counterpart to SSD_NICELEVEL.
Modified by William Hubbs to add the variable to the start-stop-daemon
man page.
This fixes #69.
commit b19d0a40d7f20987323d5af91469c720ead39561
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
init.d/loopback: remove unnecessary stop function
commit 0c229faf7e6a57bcff70f2143b83cb69a34c89f4
Author: Martin Väth <martin@mvath.de>
Commit: William Hubbs <w.d.hubbs@gmail.com>
tmpfiles.sh: Support lines with q Q h H
btrfs support is not implemented yet (for q Q v), but at least tmpfiles.sh
no longer chokes about tmpfiles.d lines of recent systemd versions
This fixes #87.
commit 3092e310acd376fc626cc051549e02bcd7697aed
Author: Mike Gilbert <floppym@gentoo.org>
Commit: William Hubbs <w.d.hubbs@gmail.com>
tmpfiles: Accept filenames as command line arguments
This brings us closer to being able to use tmpfiles.sh as a full
replacement for systemd-tmpfiles.
This closes #83.
commit 671911762d1bcd90c10d8ac0eb30fe10be4a65f6
Author: Mike Gilbert <floppym@gentoo.org>
Commit: William Hubbs <w.d.hubbs@gmail.com>
tmpfiles: Process command line before gathering config files
This is part of #83.
commit 7d68839e9ea89b0a92aef69a9b4fd298554bb9b1
Author: Mike Gilbert <floppym@gentoo.org>
Commit: William Hubbs <w.d.hubbs@gmail.com>
tmpfiles: Make unrecognized options fatal
This is part of #83.
commit 5341a925c15934674031aebb97533b0adcd10236
Author: Jakub Jirutka <jakub@jirutka.cz>
Commit: William Hubbs <w.d.hubbs@gmail.com>
s6-guide: fix typo
This fixes #92.
commit 3adb8fb389caaafbed1be13c5ac4d96214c8eed3
Author: Doug Freed <dwfreed@mtu.edu>
Commit: Doug Freed <dwfreed@mtu.edu>
rc-logger: refuse to cat TMPLOG into itself
This prevents an infinite loop in case somebody decides to set
rc_log_path to match TMPLOG.
commit 8927a37fb790e718c956376242a532ab9d1755e7
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
etc: remove rc.conf.* file fragments
commit b085b2cda58bc884acb959e48f14fb044c983042
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
etc: create default rc.conf
Before now, /etc/rc.conf was created by the build system from multiple
rc.conf.* file fragments and there was no reason for this.
commit daf93977641201f16c477b075ce9055a1da8f7b3
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
init.d: combine sysctl scripts
We had separate sysctl scripts for each operating system. However, there
is no need to do this since we can detect the operating system at
runtime with $RC_UNAME.
commit 2984504c887afc9a36610eb7c20b097f7d1e70d0
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
conf.d: remove staticroute file fragments
commit 35e8386c24df6483f2918979dae150421f7151df
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
conf.d: makestaticroute file static
commit 2108285d64e2ee8cc03fbe544efc3752fe349bdd
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
conf.d: remove network file fragnents
commit a3133fec250eca3cdfb460c2ce26c707fd593c09
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
conf.d: make network file static
commit 314ae3dc781d7ae8fc26c276a85b0dc6ab6bc326
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
modules: add support for FreeBSD
This is based on a patch submitted by
Joe Maloney <pkgdemonteam@gmail.com>.
This fixes #91.
commit 695be59083cdf0d2ff9296f2c210e591c51bdf40
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
rc-status: add -m/--manual option to show manually started services
X-Gentoo-Bug: 585906
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=585906
commit c962678dd6ab1314b55c2a3bcdae03902bda39b8
Author: Doug Freed <dwfreed@mtu.edu>
Commit: Doug Freed <dwfreed@mtu.edu>
rc: Rename some static variables to kill warnings
commit 3a1262703fd20d2e8288d13d908fb282c77d1793
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
Remove the DEBUG_MEMORY macro
This fixes #43.
commit 20035210bdf5d5729734457f35f5f32a53a5b3ad
Author: William Hubbs <w.d.hubbs@gmail.com>
Commit: William Hubbs <w.d.hubbs@gmail.com>
make variable aflag a boolean show_all

View File

@@ -1,3 +1,3 @@
NAME= openrc
VERSION= 0.28
VERSION= 0.30
PKG= ${NAME}-${VERSION}

View File

@@ -3,7 +3,7 @@
#no_umounts="/dir1:/var/dir2"
#
# Mark certain mount points as critical.
# This contains aspace separated list of mount points which should be
# This contains a space separated list of mount points which should be
# considered critical. If one of these mount points cannot be mounted,
# localmount will fail.
# By default, this is empty.

View File

@@ -284,6 +284,18 @@ system.
To see how to influence dependencies in configuration files, see the
.Sx FILES
section below.
.Sh _pre AND _post FUNCTIONS
Any command defined in extra_commands, extra_started_commands or
extra_stopped_commands can have _pre and _post functions in the service
script. If the command function is called foo, the_pre and _post
functions for it should be called foo_pre and foo_post.
.Pp
These functions should be used to perform preparation before the
command is run and cleanup after the command completes. In order for
.Nm
to record the command as being run successfully, the _pre
function, command function itself and the _post function should all exit
with a zero return code.
.Sh BUILTINS
.Nm
defines some builtin functions that you can use inside your service scripts:
@@ -433,6 +445,42 @@ Also, the -d, -f or -p options should not be specified along with this option.
.Pp
The -q option suppresses all informational output. If it is specified
twice, all error messages are suppressed as well.
.Ic fstabinfo
.Op Fl M , -mount
.Op Fl R , -remount
.Op Fl b , -blockdevice
.Op Fl m , -mountargs
.Op Fl o , -options
.Op Fl p , -passno Ar passno
.Op Fl t , -type Ar fstype
.Ar path
.Xc
If -b, -m, -o, -p or -t is specified,the appropriate information is
extracted from fstab. If -M or -R are given, file systems are mounted or
remounted.
.Pp
The -q option suppresses all informational output. If it is specified
twice, all error messages are suppressed as well.
.Ic mountinfo
.Op Fl f, -fstype-regex Ar regex
.Op Fl F, -skip-fstype-regex Ar regex
.Op Fl n, -node-regex Ar regex
.Op Fl N, -skip-node-regex Ar regex
.Op Fl o, -options-regex Ar regex
.Op Fl O, -skip-options-regex Ar regex
.Op Fl p, -point-regex Ar regex
.Op Fl P, -skip-point-regex Ar regex
.Op Fl e, -netdev
.Op Fl E, -nonetdev
.Op Fl i, -options
.Op Fl s, -fstype
.Op Fl t, -node
.Ar mount1 mount2 ...
.Xc
The f, F, n, N, o, O, p, P, e and E options specify what you want to
search for or skip in the mounted file systems. The i, s and t options
specify what you want to display. If no mount points are given, all
mount points will be considered.
.It Ic yesno Ar value
If
.Ar value

View File

@@ -36,6 +36,8 @@
.Ar pidfile
.Fl P , -respawn-period
.Ar seconds
.Fl R , -retry
.Ar arg
.Fl r , -chroot
.Ar chrootpath
.Fl u , -user
@@ -115,6 +117,9 @@ Modifies the scheduling priority of the daemon.
.It Fl P , -respawn-period Ar seconds
Sets the length of a respawn period. The default is 10 seconds. See the
description of --respawn-max for more information.
.It Fl R , -retry Ar timeout | Ar signal Ns / Ns Ar timeout
The retry specification can be either a timeout in seconds or multiple
signal/timeout pairs (like SIGTERM/5).
.It Fl r , -chroot Ar path
chroot to this directory before starting the daemon. All other paths, such
as the path to the daemon, chdir and pidfile, should be relative to the chroot.

View File

@@ -243,6 +243,9 @@ sourcex "@LIBEXECDIR@/sh/s6.sh"
sourcex "@LIBEXECDIR@/sh/start-stop-daemon.sh"
sourcex "@LIBEXECDIR@/sh/supervise-daemon.sh"
# Load our script
sourcex "$RC_SERVICE"
# Set verbose mode
if yesno "${rc_verbose:-$RC_VERBOSE}"; then
EINFO_VERBOSE=yes
@@ -272,9 +275,6 @@ for _cmd; do
fi
done
# Load our script
sourcex "$RC_SERVICE"
eval "printf '%s\n' $required_dirs" | while read _d; do
if [ -n "$_d" ] && [ ! -d "$_d" ]; then
eerror "$RC_SVCNAME: \`$_d' is not a directory"

View File

@@ -23,6 +23,7 @@ supervise_start()
# command_args="this \"is a\" test"
# to work properly.
eval supervise-daemon --start \
${retry:+--retry} $retry \
${chroot:+--chroot} $chroot \
${pidfile:+--pidfile} $pidfile \
${respawn_delay:+--respawn-delay} $respawn_delay \

View File

@@ -71,5 +71,6 @@ bool _rc_can_find_pids(void);
RC_SERVICE lookup_service_state(const char *service);
void from_time_t(char *time_string, time_t tv);
time_t to_time_t(char *timestring);
pid_t get_pid(const char *applet, const char *pidfile);
#endif

View File

@@ -156,10 +156,10 @@ rc-service service: rc-service.o _usage.o rc-misc.o
rc-update: rc-update.o _usage.o rc-misc.o
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
start-stop-daemon: start-stop-daemon.o _usage.o rc-misc.o
start-stop-daemon: start-stop-daemon.o _usage.o rc-misc.o rc-schedules.o
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
supervise-daemon: supervise-daemon.o _usage.o rc-misc.o
supervise-daemon: supervise-daemon.o _usage.o rc-misc.o rc-schedules.o
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
service_get_value service_set_value get_options save_options: do_value.o rc-misc.o

View File

@@ -35,11 +35,11 @@
# define GET_ENT getmntent (fp)
# define GET_ENT_FILE(_name) getmntfile (_name)
# define END_ENT endmntent (fp)
# define ENT_BLOCKDEVICE(_ent) ent->mnt_fsname
# define ENT_FILE(_ent) ent->mnt_dir
# define ENT_TYPE(_ent) ent->mnt_type
# define ENT_OPTS(_ent) ent->mnt_opts
# define ENT_PASS(_ent) ent->mnt_passno
# define ENT_BLOCKDEVICE(_ent) (_ent)->mnt_fsname
# define ENT_FILE(_ent) (_ent)->mnt_dir
# define ENT_TYPE(_ent) (_ent)->mnt_type
# define ENT_OPTS(_ent) (_ent)->mnt_opts
# define ENT_PASS(_ent) (_ent)->mnt_passno
#else
# define HAVE_GETFSENT
# include <fstab.h>
@@ -48,11 +48,11 @@
# define GET_ENT getfsent ()
# define GET_ENT_FILE(_name) getfsfile (_name)
# define END_ENT endfsent ()
# define ENT_BLOCKDEVICE(_ent) ent->fs_spec
# define ENT_TYPE(_ent) ent->fs_vfstype
# define ENT_FILE(_ent) ent->fs_file
# define ENT_OPTS(_ent) ent->fs_mntops
# define ENT_PASS(_ent) ent->fs_passno
# define ENT_BLOCKDEVICE(_ent) (_ent)->fs_spec
# define ENT_TYPE(_ent) (_ent)->fs_vfstype
# define ENT_FILE(_ent) (_ent)->fs_file
# define ENT_OPTS(_ent) (_ent)->fs_mntops
# define ENT_PASS(_ent) (_ent)->fs_passno
#endif
#include "einfo.h"
@@ -114,24 +114,24 @@ do_mount(struct ENT *ent, bool remount)
argv[0] = UNCONST("mount");
argv[1] = UNCONST("-o");
argv[2] = ENT_OPTS(*ent);
argv[2] = ENT_OPTS(ent);
argv[3] = UNCONST("-t");
argv[4] = ENT_TYPE(*ent);
argv[4] = ENT_TYPE(ent);
if (!remount) {
argv[5] = ENT_BLOCKDEVICE(*ent);
argv[6] = ENT_FILE(*ent);
argv[5] = ENT_BLOCKDEVICE(ent);
argv[6] = ENT_FILE(ent);
argv[7] = NULL;
} else {
#ifdef __linux__
argv[5] = UNCONST("-o");
argv[6] = UNCONST("remount");
argv[7] = ENT_BLOCKDEVICE(*ent);
argv[8] = ENT_FILE(*ent);
argv[7] = ENT_BLOCKDEVICE(ent);
argv[8] = ENT_FILE(ent);
argv[9] = NULL;
#else
argv[5] = UNCONST("-u");
argv[6] = ENT_BLOCKDEVICE(*ent);
argv[7] = ENT_FILE(*ent);
argv[6] = ENT_BLOCKDEVICE(ent);
argv[7] = ENT_FILE(ent);
argv[8] = NULL;
#endif
}

View File

@@ -474,3 +474,27 @@ time_t to_time_t(char *timestring)
}
return result;
}
pid_t get_pid(const char *applet,const char *pidfile)
{
FILE *fp;
pid_t pid;
if (! pidfile)
return -1;
if ((fp = fopen(pidfile, "r")) == NULL) {
ewarnv("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
return -1;
}
if (fscanf(fp, "%d", &pid) != 1) {
ewarnv("%s: no pid found in `%s'", applet, pidfile);
fclose(fp);
return -1;
}
fclose(fp);
return pid;
}

419
src/rc/rc-schedules.c Normal file
View File

@@ -0,0 +1,419 @@
/*
* The functions in this file control the stopping of daemons by
* start-stop-daemon and supervise-daemon.
*/
/*
* Copyright (c) 2015 The OpenRC Authors.
* See the Authors file at the top-level directory of this distribution and
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
*
* This file is part of OpenRC. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file.
*/
/* nano seconds */
#define POLL_INTERVAL 20000000
#define WAIT_PIDFILE 500000000
#define ONE_SECOND 1000000000
#define ONE_MS 1000000
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "einfo.h"
#include "queue.h"
#include "rc.h"
#include "rc-misc.h"
#include "rc-schedules.h"
#include "helpers.h"
typedef struct scheduleitem {
enum {
SC_TIMEOUT,
SC_SIGNAL,
SC_GOTO,
SC_FOREVER,
} type;
int value;
struct scheduleitem *gotoitem;
TAILQ_ENTRY(scheduleitem) entries;
} SCHEDULEITEM;
static TAILQ_HEAD(, scheduleitem) schedule;
void initialize_schedulelist(void)
{
TAILQ_INIT(&schedule);
}
void free_schedulelist(void)
{
SCHEDULEITEM *s1 = TAILQ_FIRST(&schedule);
SCHEDULEITEM *s2;
while (s1) {
s2 = TAILQ_NEXT(s1, entries);
free(s1);
s1 = s2;
}
TAILQ_INIT(&schedule);
}
int parse_signal(const char *applet, const char *sig)
{
typedef struct signalpair
{
const char *name;
int signal;
} SIGNALPAIR;
#define signalpair_item(name) { #name, SIG##name },
static const SIGNALPAIR signallist[] = {
signalpair_item(HUP)
signalpair_item(INT)
signalpair_item(QUIT)
signalpair_item(ILL)
signalpair_item(TRAP)
signalpair_item(ABRT)
signalpair_item(BUS)
signalpair_item(FPE)
signalpair_item(KILL)
signalpair_item(USR1)
signalpair_item(SEGV)
signalpair_item(USR2)
signalpair_item(PIPE)
signalpair_item(ALRM)
signalpair_item(TERM)
signalpair_item(CHLD)
signalpair_item(CONT)
signalpair_item(STOP)
signalpair_item(TSTP)
signalpair_item(TTIN)
signalpair_item(TTOU)
signalpair_item(URG)
signalpair_item(XCPU)
signalpair_item(XFSZ)
signalpair_item(VTALRM)
signalpair_item(PROF)
#ifdef SIGWINCH
signalpair_item(WINCH)
#endif
#ifdef SIGIO
signalpair_item(IO)
#endif
#ifdef SIGPWR
signalpair_item(PWR)
#endif
signalpair_item(SYS)
{ "NULL", 0 },
};
unsigned int i = 0;
const char *s;
if (!sig || *sig == '\0')
return -1;
if (sscanf(sig, "%u", &i) == 1) {
if (i < NSIG)
return i;
eerrorx("%s: `%s' is not a valid signal", applet, sig);
}
if (strncmp(sig, "SIG", 3) == 0)
s = sig + 3;
else
s = NULL;
for (i = 0; i < ARRAY_SIZE(signallist); ++i)
if (strcmp(sig, signallist[i].name) == 0 ||
(s && strcmp(s, signallist[i].name) == 0))
return signallist[i].signal;
eerrorx("%s: `%s' is not a valid signal", applet, sig);
/* NOTREACHED */
}
static SCHEDULEITEM *parse_schedule_item(const char *applet, const char *string)
{
const char *after_hyph;
int sig;
SCHEDULEITEM *item = xmalloc(sizeof(*item));
item->value = 0;
item->gotoitem = NULL;
if (strcmp(string,"forever") == 0)
item->type = SC_FOREVER;
else if (isdigit((unsigned char)string[0])) {
item->type = SC_TIMEOUT;
errno = 0;
if (sscanf(string, "%d", &item->value) != 1)
eerrorx("%s: invalid timeout value in schedule `%s'",
applet, string);
} else if ((after_hyph = string + (string[0] == '-')) &&
((sig = parse_signal(applet, after_hyph)) != -1))
{
item->type = SC_SIGNAL;
item->value = (int)sig;
} else
eerrorx("%s: invalid schedule item `%s'", applet, string);
return item;
}
void parse_schedule(const char *applet, const char *string, int timeout)
{
char buffer[20];
const char *slash;
int count = 0;
SCHEDULEITEM *repeatat = NULL;
size_t len;
SCHEDULEITEM *item;
if (string)
for (slash = string; *slash; slash++)
if (*slash == '/')
count++;
free_schedulelist();
if (count == 0) {
item = xmalloc(sizeof(*item));
item->type = SC_SIGNAL;
item->value = timeout;
item->gotoitem = NULL;
TAILQ_INSERT_TAIL(&schedule, item, entries);
item = xmalloc(sizeof(*item));
item->type = SC_TIMEOUT;
item->gotoitem = NULL;
TAILQ_INSERT_TAIL(&schedule, item, entries);
if (string) {
if (sscanf(string, "%d", &item->value) != 1)
eerrorx("%s: invalid timeout in schedule",
applet);
} else
item->value = 5;
return;
}
while (string != NULL) {
if ((slash = strchr(string, '/')))
len = slash - string;
else
len = strlen(string);
if (len >= (ptrdiff_t)sizeof(buffer))
eerrorx("%s: invalid schedule item, far too long",
applet);
memcpy(buffer, string, len);
buffer[len] = 0;
string = slash ? slash + 1 : NULL;
item = parse_schedule_item(applet, buffer);
TAILQ_INSERT_TAIL(&schedule, item, entries);
if (item->type == SC_FOREVER) {
if (repeatat)
eerrorx("%s: invalid schedule, `forever' "
"appears more than once", applet);
repeatat = item;
continue;
}
}
if (repeatat) {
item = xmalloc(sizeof(*item));
item->type = SC_GOTO;
item->value = 0;
item->gotoitem = repeatat;
TAILQ_INSERT_TAIL(&schedule, item, entries);
}
return;
}
/* return number of processes killed, -1 on error */
int do_stop(const char *applet, const char *exec, const char *const *argv,
pid_t pid, uid_t uid,int sig, bool test)
{
RC_PIDLIST *pids;
RC_PID *pi;
RC_PID *np;
bool killed;
int nkilled = 0;
if (pid)
pids = rc_find_pids(NULL, NULL, 0, pid);
else
pids = rc_find_pids(exec, argv, uid, pid);
if (!pids)
return 0;
LIST_FOREACH_SAFE(pi, pids, entries, np) {
if (test) {
einfo("Would send signal %d to PID %d", sig, pi->pid);
nkilled++;
} else {
ebeginv("Sending signal %d to PID %d", sig, pi->pid);
errno = 0;
killed = (kill(pi->pid, sig) == 0 ||
errno == ESRCH ? true : false);
eendv(killed ? 0 : 1,
"%s: failed to send signal %d to PID %d: %s",
applet, sig, pi->pid, strerror(errno));
if (!killed) {
nkilled = -1;
} else {
if (nkilled != -1)
nkilled++;
}
}
free(pi);
}
free(pids);
return nkilled;
}
int run_stop_schedule(const char *applet,
const char *exec, const char *const *argv,
pid_t pid, uid_t uid,
bool test, bool progress, bool quiet)
{
SCHEDULEITEM *item = TAILQ_FIRST(&schedule);
int nkilled = 0;
int tkilled = 0;
int nrunning = 0;
long nloops, nsecs;
struct timespec ts;
const char *const *p;
bool progressed = false;
if (exec)
einfov("Will stop %s", exec);
if (pid > 0)
einfov("Will stop PID %d", pid);
if (uid)
einfov("Will stop processes owned by UID %d", uid);
if (argv && *argv) {
einfovn("Will stop processes of `");
if (rc_yesno(getenv("EINFO_VERBOSE"))) {
for (p = argv; p && *p; p++) {
if (p != argv)
printf(" ");
printf("%s", *p);
}
printf("'\n");
}
}
while (item) {
switch (item->type) {
case SC_GOTO:
item = item->gotoitem;
continue;
case SC_SIGNAL:
nrunning = 0;
nkilled = do_stop(applet, exec, argv, pid, uid, item->value, test);
if (nkilled == 0) {
if (tkilled == 0) {
if (progressed)
printf("\n");
eerror("%s: no matching processes found", applet);
}
return tkilled;
}
else if (nkilled == -1)
return 0;
tkilled += nkilled;
break;
case SC_TIMEOUT:
if (item->value < 1) {
item = NULL;
break;
}
ts.tv_sec = 0;
ts.tv_nsec = POLL_INTERVAL;
for (nsecs = 0; nsecs < item->value; nsecs++) {
for (nloops = 0;
nloops < ONE_SECOND / POLL_INTERVAL;
nloops++)
{
if ((nrunning = do_stop(applet, exec, argv,
pid, uid, 0, test)) == 0)
return 0;
if (nanosleep(&ts, NULL) == -1) {
if (progressed) {
printf("\n");
progressed = false;
}
if (errno == EINTR)
eerror("%s: caught an"
" interrupt", applet);
else {
eerror("%s: nanosleep: %s",
applet, strerror(errno));
return 0;
}
}
}
if (progress) {
printf(".");
fflush(stdout);
progressed = true;
}
}
break;
default:
if (progressed) {
printf("\n");
progressed = false;
}
eerror("%s: invalid schedule item `%d'",
applet, item->type);
return 0;
}
if (item)
item = TAILQ_NEXT(item, entries);
}
if (test || (tkilled > 0 && nrunning == 0))
return nkilled;
if (progressed)
printf("\n");
if (! quiet)
if (nrunning == 1)
eerror("%s: %d process refused to stop", applet, nrunning);
else
eerror("%s: %d process(es) refused to stop", applet, nrunning);
return -nrunning;
}

27
src/rc/rc-schedules.h Normal file
View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2017 The OpenRC Authors.
* See the Authors file at the top-level directory of this distribution and
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
*
* This file is part of OpenRC. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file.
*/
#ifndef __RC_SCHEDULES_H
#define __RC_SCHEDULES_H
void initialize_schedulelist(void);
void free_schedulelist(void);
int parse_signal(const char *applet, const char *sig);
void parse_schedule(const char *applet, const char *string, int timeout);
int do_stop(const char *applet, const char *exec, const char *const *argv,
pid_t pid, uid_t uid,int sig, bool test);
int run_stop_schedule(const char *applet,
const char *exec, const char *const *argv,
pid_t pid, uid_t uid,
bool test, bool progress, bool quiet);
#endif

View File

@@ -19,10 +19,6 @@
* except according to the terms contained in the LICENSE file.
*/
/* nano seconds */
#define POLL_INTERVAL 20000000
#define WAIT_PIDFILE 500000000
#define ONE_SECOND 1000000000
#define ONE_MS 1000000
#include <sys/types.h>
@@ -63,6 +59,7 @@ static struct pam_conv conv = { NULL, NULL};
#include "queue.h"
#include "rc.h"
#include "rc-misc.h"
#include "rc-schedules.h"
#include "_usage.h"
#include "helpers.h"
@@ -130,20 +127,6 @@ const char * const longopts_help[] = {
};
const char *usagestring = NULL;
typedef struct scheduleitem
{
enum
{
SC_TIMEOUT,
SC_SIGNAL,
SC_GOTO,
SC_FOREVER
} type;
int value;
struct scheduleitem *gotoitem;
TAILQ_ENTRY(scheduleitem) entries;
} SCHEDULEITEM;
TAILQ_HEAD(, scheduleitem) schedule;
static char **nav;
static char *changeuser, *ch_root, *ch_dir;
@@ -166,20 +149,6 @@ static inline int ioprio_set(int which _unused,
}
#endif
static void
free_schedulelist(void)
{
SCHEDULEITEM *s1 = TAILQ_FIRST(&schedule);
SCHEDULEITEM *s2;
while (s1) {
s2 = TAILQ_NEXT(s1, entries);
free(s1);
s1 = s2;
}
TAILQ_INIT(&schedule);
}
static void
cleanup(void)
{
@@ -188,385 +157,6 @@ cleanup(void)
free_schedulelist();
}
static int
parse_signal(const char *sig)
{
typedef struct signalpair
{
const char *name;
int signal;
} SIGNALPAIR;
#define signalpair_item(name) { #name, SIG##name },
static const SIGNALPAIR signallist[] = {
signalpair_item(HUP)
signalpair_item(INT)
signalpair_item(QUIT)
signalpair_item(ILL)
signalpair_item(TRAP)
signalpair_item(ABRT)
signalpair_item(BUS)
signalpair_item(FPE)
signalpair_item(KILL)
signalpair_item(USR1)
signalpair_item(SEGV)
signalpair_item(USR2)
signalpair_item(PIPE)
signalpair_item(ALRM)
signalpair_item(TERM)
signalpair_item(CHLD)
signalpair_item(CONT)
signalpair_item(STOP)
signalpair_item(TSTP)
signalpair_item(TTIN)
signalpair_item(TTOU)
signalpair_item(URG)
signalpair_item(XCPU)
signalpair_item(XFSZ)
signalpair_item(VTALRM)
signalpair_item(PROF)
#ifdef SIGWINCH
signalpair_item(WINCH)
#endif
#ifdef SIGIO
signalpair_item(IO)
#endif
#ifdef SIGPWR
signalpair_item(PWR)
#endif
signalpair_item(SYS)
{ "NULL", 0 },
};
unsigned int i = 0;
const char *s;
if (!sig || *sig == '\0')
return -1;
if (sscanf(sig, "%u", &i) == 1) {
if (i < NSIG)
return i;
eerrorx("%s: `%s' is not a valid signal", applet, sig);
}
if (strncmp(sig, "SIG", 3) == 0)
s = sig + 3;
else
s = NULL;
for (i = 0; i < ARRAY_SIZE(signallist); ++i)
if (strcmp(sig, signallist[i].name) == 0 ||
(s && strcmp(s, signallist[i].name) == 0))
return signallist[i].signal;
eerrorx("%s: `%s' is not a valid signal", applet, sig);
/* NOTREACHED */
}
static SCHEDULEITEM *
parse_schedule_item(const char *string)
{
const char *after_hyph;
int sig;
SCHEDULEITEM *item = xmalloc(sizeof(*item));
item->value = 0;
item->gotoitem = NULL;
if (strcmp(string,"forever") == 0)
item->type = SC_FOREVER;
else if (isdigit((unsigned char)string[0])) {
item->type = SC_TIMEOUT;
errno = 0;
if (sscanf(string, "%d", &item->value) != 1)
eerrorx("%s: invalid timeout value in schedule `%s'",
applet, string);
} else if ((after_hyph = string + (string[0] == '-')) &&
((sig = parse_signal(after_hyph)) != -1))
{
item->type = SC_SIGNAL;
item->value = (int)sig;
} else
eerrorx("%s: invalid schedule item `%s'", applet, string);
return item;
}
static void
parse_schedule(const char *string, int timeout)
{
char buffer[20];
const char *slash;
int count = 0;
SCHEDULEITEM *repeatat = NULL;
size_t len;
SCHEDULEITEM *item;
if (string)
for (slash = string; *slash; slash++)
if (*slash == '/')
count++;
free_schedulelist();
if (count == 0) {
item = xmalloc(sizeof(*item));
item->type = SC_SIGNAL;
item->value = timeout;
item->gotoitem = NULL;
TAILQ_INSERT_TAIL(&schedule, item, entries);
item = xmalloc(sizeof(*item));
item->type = SC_TIMEOUT;
item->gotoitem = NULL;
TAILQ_INSERT_TAIL(&schedule, item, entries);
if (string) {
if (sscanf(string, "%d", &item->value) != 1)
eerrorx("%s: invalid timeout in schedule",
applet);
} else
item->value = 5;
return;
}
while (string != NULL) {
if ((slash = strchr(string, '/')))
len = slash - string;
else
len = strlen(string);
if (len >= (ptrdiff_t)sizeof(buffer))
eerrorx("%s: invalid schedule item, far too long",
applet);
memcpy(buffer, string, len);
buffer[len] = 0;
string = slash ? slash + 1 : NULL;
item = parse_schedule_item(buffer);
TAILQ_INSERT_TAIL(&schedule, item, entries);
if (item->type == SC_FOREVER) {
if (repeatat)
eerrorx("%s: invalid schedule, `forever' "
"appears more than once", applet);
repeatat = item;
continue;
}
}
if (repeatat) {
item = xmalloc(sizeof(*item));
item->type = SC_GOTO;
item->value = 0;
item->gotoitem = repeatat;
TAILQ_INSERT_TAIL(&schedule, item, entries);
}
return;
}
static pid_t
get_pid(const char *pidfile)
{
FILE *fp;
pid_t pid;
if (! pidfile)
return -1;
if ((fp = fopen(pidfile, "r")) == NULL) {
ewarnv("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
return -1;
}
if (fscanf(fp, "%d", &pid) != 1) {
ewarnv("%s: no pid found in `%s'", applet, pidfile);
fclose(fp);
return -1;
}
fclose(fp);
return pid;
}
/* return number of processed killed, -1 on error */
static int
do_stop(const char *exec, const char *const *argv,
pid_t pid, uid_t uid,int sig, bool test)
{
RC_PIDLIST *pids;
RC_PID *pi;
RC_PID *np;
bool killed;
int nkilled = 0;
if (pid)
pids = rc_find_pids(NULL, NULL, 0, pid);
else
pids = rc_find_pids(exec, argv, uid, pid);
if (!pids)
return 0;
LIST_FOREACH_SAFE(pi, pids, entries, np) {
if (test) {
einfo("Would send signal %d to PID %d", sig, pi->pid);
nkilled++;
} else {
ebeginv("Sending signal %d to PID %d", sig, pi->pid);
errno = 0;
killed = (kill(pi->pid, sig) == 0 ||
errno == ESRCH ? true : false);
eendv(killed ? 0 : 1,
"%s: failed to send signal %d to PID %d: %s",
applet, sig, pi->pid, strerror(errno));
if (!killed) {
nkilled = -1;
} else {
if (nkilled != -1)
nkilled++;
}
}
free(pi);
}
free(pids);
return nkilled;
}
static int
run_stop_schedule(const char *exec, const char *const *argv,
const char *pidfile, uid_t uid,
bool test, bool progress)
{
SCHEDULEITEM *item = TAILQ_FIRST(&schedule);
int nkilled = 0;
int tkilled = 0;
int nrunning = 0;
long nloops, nsecs;
struct timespec ts;
pid_t pid = 0;
const char *const *p;
bool progressed = false;
if (exec)
einfov("Will stop %s", exec);
if (pidfile)
einfov("Will stop PID in pidfile `%s'", pidfile);
if (uid)
einfov("Will stop processes owned by UID %d", uid);
if (argv && *argv) {
einfovn("Will stop processes of `");
if (rc_yesno(getenv("EINFO_VERBOSE"))) {
for (p = argv; p && *p; p++) {
if (p != argv)
printf(" ");
printf("%s", *p);
}
printf("'\n");
}
}
if (pidfile) {
pid = get_pid(pidfile);
if (pid == -1)
return 0;
}
while (item) {
switch (item->type) {
case SC_GOTO:
item = item->gotoitem;
continue;
case SC_SIGNAL:
nrunning = 0;
nkilled = do_stop(exec, argv, pid, uid, item->value, test);
if (nkilled == 0) {
if (tkilled == 0) {
if (progressed)
printf("\n");
eerror("%s: no matching processes found", applet);
}
return tkilled;
}
else if (nkilled == -1)
return 0;
tkilled += nkilled;
break;
case SC_TIMEOUT:
if (item->value < 1) {
item = NULL;
break;
}
ts.tv_sec = 0;
ts.tv_nsec = POLL_INTERVAL;
for (nsecs = 0; nsecs < item->value; nsecs++) {
for (nloops = 0;
nloops < ONE_SECOND / POLL_INTERVAL;
nloops++)
{
if ((nrunning = do_stop(exec, argv,
pid, uid, 0, test)) == 0)
return 0;
if (nanosleep(&ts, NULL) == -1) {
if (progressed) {
printf("\n");
progressed = false;
}
if (errno == EINTR)
eerror("%s: caught an"
" interrupt", applet);
else {
eerror("%s: nanosleep: %s",
applet, strerror(errno));
return 0;
}
}
}
if (progress) {
printf(".");
fflush(stdout);
progressed = true;
}
}
break;
default:
if (progressed) {
printf("\n");
progressed = false;
}
eerror("%s: invalid schedule item `%d'",
applet, item->type);
return 0;
}
if (item)
item = TAILQ_NEXT(item, entries);
}
if (test || (tkilled > 0 && nrunning == 0))
return nkilled;
if (progressed)
printf("\n");
if (nrunning == 1)
eerror("%s: %d process refused to stop", applet, nrunning);
else
eerror("%s: %d process(es) refused to stop", applet, nrunning);
return -nrunning;
}
static void
handle_signal(int sig)
{
@@ -707,7 +297,6 @@ int main(int argc, char **argv)
unsigned int start_wait = 0;
applet = basename_c(argv[0]);
TAILQ_INIT(&schedule);
atexit(cleanup);
signal_setup(SIGINT, handle_signal);
@@ -876,7 +465,7 @@ int main(int argc, char **argv)
break;
case 's': /* --signal <signal> */
sig = parse_signal(optarg);
sig = parse_signal(applet, optarg);
break;
case 't': /* --test */
@@ -1062,13 +651,13 @@ int main(int argc, char **argv)
if (!stop)
oknodo = true;
if (retry)
parse_schedule(retry, sig);
parse_schedule(applet, retry, sig);
else if (test || oknodo)
parse_schedule("0", sig);
parse_schedule(applet, "0", sig);
else
parse_schedule(NULL, sig);
i = run_stop_schedule(exec, (const char *const *)margv,
pidfile, uid, test, progress);
parse_schedule(applet, NULL, sig);
i = run_stop_schedule(applet, exec, (const char *const *)margv,
get_pid(applet, pidfile), uid, test, progress, false);
if (i < 0)
/* We failed to stop something */
@@ -1090,11 +679,11 @@ int main(int argc, char **argv)
}
if (pidfile)
pid = get_pid(pidfile);
pid = get_pid(applet, pidfile);
else
pid = 0;
if (do_stop(exec, (const char * const *)margv, pid, uid,
if (do_stop(applet, exec, (const char * const *)margv, pid, uid,
0, test) > 0)
eerrorx("%s: %s is already running", applet, exec);
@@ -1365,7 +954,7 @@ int main(int argc, char **argv)
alive = true;
} else {
if (pidfile) {
pid = get_pid(pidfile);
pid = get_pid(applet, pidfile);
if (pid == -1) {
eerrorx("%s: did not "
"create a valid"
@@ -1374,7 +963,7 @@ int main(int argc, char **argv)
}
} else
pid = 0;
if (do_stop(exec, (const char *const *)margv,
if (do_stop(applet, exec, (const char *const *)margv,
pid, uid, 0, test) > 0)
alive = true;
}

View File

@@ -61,12 +61,13 @@ static struct pam_conv conv = { NULL, NULL};
#include "queue.h"
#include "rc.h"
#include "rc-misc.h"
#include "rc-schedules.h"
#include "_usage.h"
#include "helpers.h"
const char *applet = NULL;
const char *extraopts = NULL;
const char *getoptstring = "D:d:e:g:I:Kk:m:N:p:r:Su:1:2:" \
const char *getoptstring = "D:d:e:g:I:Kk:m:N:p:R:r:Su:1:2:" \
getoptstring_COMMON;
const struct option longopts[] = {
{ "respawn-delay", 1, NULL, 'D'},
@@ -80,6 +81,7 @@ const struct option longopts[] = {
{ "nicelevel", 1, NULL, 'N'},
{ "pidfile", 1, NULL, 'p'},
{ "respawn-period", 1, NULL, 'P'},
{ "retry", 1, NULL, 'R'},
{ "chroot", 1, NULL, 'r'},
{ "start", 0, NULL, 'S'},
{ "user", 1, NULL, 'u'},
@@ -99,6 +101,7 @@ const char * const longopts_help[] = {
"Set a nicelevel when starting",
"Match pid found in this file",
"Set respawn time period",
"Retry schedule to use when stopping",
"Chroot to this directory",
"Start daemon",
"Change the process user",
@@ -147,30 +150,6 @@ static void cleanup(void)
free(changeuser);
}
static pid_t get_pid(const char *pidfile)
{
FILE *fp;
pid_t pid;
if (! pidfile)
return -1;
if ((fp = fopen(pidfile, "r")) == NULL) {
ewarnv("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
return -1;
}
if (fscanf(fp, "%d", &pid) != 1) {
ewarnv("%s: no pid found in `%s'", applet, pidfile);
fclose(fp);
return -1;
}
fclose(fp);
return pid;
}
static void child_process(char *exec, char **argv, char *svcname,
int start_count)
{
@@ -434,6 +413,9 @@ int main(int argc, char **argv)
bool stop = false;
char *exec = NULL;
char *pidfile = NULL;
char *retry = NULL;
int nkilled;
int sig = SIGTERM;
char *home = NULL;
int tid = 0;
pid_t child_pid, pid;
@@ -558,6 +540,9 @@ int main(int argc, char **argv)
pidfile = optarg;
break;
case 'R': /* --retry <schedule>|timeout */
retry = optarg;
break;
case 'r': /* --chroot /new/root */
ch_root = optarg;
break;
@@ -629,6 +614,10 @@ int main(int argc, char **argv)
"than %d to avoid infinite respawning", applet,
respawn_delay * respawn_max);
}
if (retry)
parse_schedule(applet, retry, sig);
else
parse_schedule(applet, NULL, sig);
}
/* Expand ~ */
@@ -673,15 +662,19 @@ int main(int argc, char **argv)
*exec_file ? exec_file : exec);
if (stop) {
pid = get_pid(pidfile);
pid = get_pid(applet, pidfile);
if (pid == -1)
i = pid;
else
i = kill(pid, SIGTERM);
if (i != 0)
/* We failed to stop something */
/* We failed to send the signal */
exit(EXIT_FAILURE);
/* wait for the supervisor to go down */
while (kill(pid, 0) == 0)
sleep(1);
/* Even if we have not actually killed anything, we should
* remove information about it as it may have unexpectedly
* crashed out. We should also return success as the end
@@ -697,7 +690,7 @@ int main(int argc, char **argv)
exit(EXIT_SUCCESS);
}
pid = get_pid(pidfile);
pid = get_pid(applet, pidfile);
if (pid != -1)
if (kill(pid, 0) == 0)
eerrorx("%s: %s is already running", applet, exec);
@@ -761,7 +754,10 @@ int main(int argc, char **argv)
wait(&i);
if (exiting) {
syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
kill(child_pid, SIGTERM);
nkilled = run_stop_schedule(applet, exec, NULL, child_pid,
0, false, false, true);
if (nkilled > 0)
syslog(LOG_INFO, "killed %d processes", nkilled);
} else {
sleep(respawn_delay);
if (respawn_max > 0 && respawn_period > 0) {