Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66651180a7 | ||
|
|
7d63dc928c | ||
|
|
8e16828bd3 | ||
|
|
3a30710916 | ||
|
|
290a91e8e9 | ||
|
|
04d94be766 | ||
|
|
fa6707e5b3 | ||
|
|
3286a98fe6 | ||
|
|
dc0ab571a2 | ||
|
|
fb37e1aa96 | ||
|
|
8769cca710 | ||
|
|
506f2887e1 | ||
|
|
83223a6e97 | ||
|
|
2747f40f82 | ||
|
|
933972da53 | ||
|
|
dbcb8ba3fe | ||
|
|
e462c3223e | ||
|
|
06f195ce37 |
@@ -38,7 +38,7 @@ Who:
|
|||||||
|
|
||||||
When: 1.0
|
When: 1.0
|
||||||
|
|
||||||
Why: Deprecated in favor of extra_commands, extra_started_commands
|
Why: Depprecated in favor of extra_commands, extra_started_commands
|
||||||
and extra_stopped_commands.
|
and extra_stopped_commands.
|
||||||
|
|
||||||
Who:
|
Who:
|
||||||
@@ -47,7 +47,7 @@ Who:
|
|||||||
|
|
||||||
When: 1.0
|
When: 1.0
|
||||||
|
|
||||||
Why: Deprecated in favor of executable scripts in @SYSCONFDIR@/local.d
|
Why: Depprecated in favor of executable scripts in @SYSCONFDIR@/local.d
|
||||||
|
|
||||||
Who:
|
Who:
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
NAME= openrc
|
NAME= openrc
|
||||||
VERSION= 0.21.4
|
VERSION= 0.20.3
|
||||||
PKG= ${NAME}-${VERSION}
|
PKG= ${NAME}-${VERSION}
|
||||||
|
|||||||
27
NEWS.md
27
NEWS.md
@@ -3,33 +3,6 @@
|
|||||||
This file will contain a list of notable changes for each release. Note
|
This file will contain a list of notable changes for each release. Note
|
||||||
the information in this file is in reverse order.
|
the information in this file is in reverse order.
|
||||||
|
|
||||||
## OpenRC-0.21
|
|
||||||
|
|
||||||
This version adds a daemon supervisor which can start daemons and
|
|
||||||
restart them if they crash. See supervise-daemon-guide.md in the
|
|
||||||
distribution for details on its use.
|
|
||||||
|
|
||||||
It is now possible to mark certain mount points as critical. If these
|
|
||||||
mount points are unable to be mounted, localmount or netmount will fail.
|
|
||||||
This is handled in /etc/conf.d/localmount and /etc/conf.d/netmount. See
|
|
||||||
these files for the setup.
|
|
||||||
|
|
||||||
The deprecation messages in 0.13.x for runscript and rc are now
|
|
||||||
made visible in preparation for the removal of these binaries in 1.0.
|
|
||||||
|
|
||||||
The steps you should take to get rid of these warnings is to run openrc
|
|
||||||
in initialization steps instead of rc and change the shebang lines in
|
|
||||||
service scripts to refer to "openrc-run" instead of "runscript".
|
|
||||||
|
|
||||||
In 0.21.4, a modules-load service was added. This works like the
|
|
||||||
equivalent service in systemd. It looks for files named *.conf first in
|
|
||||||
/usr/lib/modules-load.d, then /run/modules-load.d, then
|
|
||||||
/etc/modules-lload.d. These files contain, a list of modules, one per
|
|
||||||
line, which should be loaded into the kernel. If a file name appears in
|
|
||||||
/run/modules-load.d, it overrides a file of the same name in
|
|
||||||
/usr/lib/modules-load.d. A file appearing in /etc/modules-load.d
|
|
||||||
overrides a file of the same name in both previous directories.
|
|
||||||
|
|
||||||
## OpenRC-0.19
|
## OpenRC-0.19
|
||||||
|
|
||||||
This version adds a net-online service. By default, this
|
This version adds a net-online service. By default, this
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ wipe_tmp="YES"
|
|||||||
# This may be useful if you need the kernel boot log afterwards
|
# This may be useful if you need the kernel boot log afterwards
|
||||||
log_dmesg="YES"
|
log_dmesg="YES"
|
||||||
|
|
||||||
# Save the previous dmesg log to dmesg.old
|
# Save the previous dmesg log to dmesc.old
|
||||||
# This may be useful if you need to compare the current boot to the
|
# This may be useful if you need to compare the current boot to the
|
||||||
# previous one.
|
# previous one.
|
||||||
#previous_dmesg=no
|
#previous_dmesg=no
|
||||||
|
|||||||
@@ -2,9 +2,8 @@
|
|||||||
# This could be useful for some NFS related work.
|
# This could be useful for some NFS related work.
|
||||||
#no_umounts="/dir1:/var/dir2"
|
#no_umounts="/dir1:/var/dir2"
|
||||||
#
|
#
|
||||||
# Mark certain mount points as critical.
|
# Ignore errors when mounting local file systems.
|
||||||
# This contains aspace separated list of mount points which should be
|
# This should be left alone unless you know what you are doing. If it is
|
||||||
# considered critical. If one of these mount points cannot be mounted,
|
# set to yes, not only will we allow mount failures, but we will ignore
|
||||||
# localmount will fail.
|
# syntax errors in fstab.
|
||||||
# By default, this is empty.
|
#ignore_mount_errors="NO"
|
||||||
#critical_mounts="/home /var"
|
|
||||||
|
|||||||
@@ -38,10 +38,3 @@
|
|||||||
# other words, please change it to be more suited to your system.
|
# other words, please change it to be more suited to your system.
|
||||||
#
|
#
|
||||||
rc_need="net"
|
rc_need="net"
|
||||||
#
|
|
||||||
# Mark certain mount points as critical.
|
|
||||||
# This contains aspace separated list of mount points which should be
|
|
||||||
# considered critical. If one of these mount points cannot be mounted,
|
|
||||||
# netmount will fail.
|
|
||||||
# By default, this is empty.
|
|
||||||
#critical_mounts="/home /var"
|
|
||||||
|
|||||||
251
guide.md
251
guide.md
@@ -1,251 +0,0 @@
|
|||||||
# Purpose and description
|
|
||||||
|
|
||||||
OpenRC is an init system for Unixoid operating systems. It takes care of
|
|
||||||
startup and shutdown of the whole system, including services.
|
|
||||||
|
|
||||||
It evolved out of the Gentoo "Baselayout" package which was a custom pure-shell
|
|
||||||
startup solution. (This was both hard to maintain and debug, and not very
|
|
||||||
performant)
|
|
||||||
|
|
||||||
Most of the core parts are written in C99 for performance and flexibility
|
|
||||||
reasons, while everything else is posix sh.
|
|
||||||
The License is 2-clause BSD
|
|
||||||
|
|
||||||
Current size is about 10k LoC C, and about 4k LoC shell.
|
|
||||||
|
|
||||||
OpenRC is known to work on Linux, many BSDs (FreeBSD, OpenBSD, DragonFlyBSD at
|
|
||||||
least) and HURD.
|
|
||||||
|
|
||||||
Services are stateful (i.e. start; start will lead to "it's already started")
|
|
||||||
|
|
||||||
# Startup
|
|
||||||
|
|
||||||
Usually PID1 (aka. init) calls the OpenRC binary ("/sbin/openrc" by default).
|
|
||||||
(The default setup assumes sysvinit for this)
|
|
||||||
|
|
||||||
openrc scans the runlevels (default: "/etc/runlevels") and builds a dependency
|
|
||||||
graph, then starts the needed service scripts, either serialized (default) or in
|
|
||||||
parallel.
|
|
||||||
|
|
||||||
When all the init scripts are started openrc terminates. There is no persistent
|
|
||||||
daemon. (Integration with tools like monit, runit or s6 can be done)
|
|
||||||
|
|
||||||
# Shutdown
|
|
||||||
|
|
||||||
On change to runlevel 0/6 or running "reboot", "halt" etc., openrc stops all
|
|
||||||
services that are started and runs the services in the "shutdown" runlevel.
|
|
||||||
|
|
||||||
# Modifying Service Scripts
|
|
||||||
|
|
||||||
Any service can, at any time, be started/stopped/restarted by executing
|
|
||||||
"rc-service someservice start", "rc-service someservice stop", etc.
|
|
||||||
Another, less preferred method, is to run the service script directly,
|
|
||||||
e.g. "/etc/init.d/service start", "/etc/init.d/service stop", etc.
|
|
||||||
|
|
||||||
OpenRC will take care of dependencies, e.g starting apache will start network
|
|
||||||
first, and stopping network will stop apache first.
|
|
||||||
|
|
||||||
There is a special command "zap" that makes OpenRC 'forget' that a service is
|
|
||||||
started; this is mostly useful to reset a crashed service to stopped state
|
|
||||||
without invoking the (possibly broken) stop function of the service script.
|
|
||||||
|
|
||||||
Calling "openrc" without any arguments will try to reset all services so
|
|
||||||
that the current runlevel is satisfied; if you manually started apache it will be
|
|
||||||
stopped, and if squid died but is in the current runlevel it'll be restarted.
|
|
||||||
|
|
||||||
There is a "service" helper that emulates the syntax seen on e.g. older Redhat
|
|
||||||
and Ubuntu ("service nginx start" etc.)
|
|
||||||
|
|
||||||
# Runlevels
|
|
||||||
|
|
||||||
OpenRC has a concept of runlevels, similar to what sysvinit historically
|
|
||||||
offered. A runlevel is basically a collection of services that needs to be
|
|
||||||
started. Instead of random numbers they are named, and users can create their
|
|
||||||
own if needed. This allows, for example, to have a default runlevel with
|
|
||||||
"everything" enabled, and a "powersaving" runlevel where some services are
|
|
||||||
disabled.
|
|
||||||
|
|
||||||
The "rc-status" helper will print all currently active runlevels and the state
|
|
||||||
of init scripts in them:
|
|
||||||
|
|
||||||
# rc-status
|
|
||||||
* Caching service dependencies ... [ ok ]
|
|
||||||
Runlevel: default
|
|
||||||
modules [ started ]
|
|
||||||
lvm [ started ]
|
|
||||||
|
|
||||||
All runlevels are represented as folders in /etc/runlevels/ with symlinks to
|
|
||||||
the actual init scripts.
|
|
||||||
|
|
||||||
Calling openrc with an argument ("openrc default") will switch to that
|
|
||||||
runlevel; this will start and stop services as needed.
|
|
||||||
|
|
||||||
Managing runlevels is usually done through the "rc-update" helper, but could of
|
|
||||||
course be done by hand if desired.
|
|
||||||
e.g. "rc-update add nginx default" - add nginx to the default runlevel
|
|
||||||
Note: This will not auto-start nginx! You'd still have to trigger "rc" or run
|
|
||||||
the initscript by hand.
|
|
||||||
|
|
||||||
FIXME: Document stacked runlevels
|
|
||||||
|
|
||||||
The default startup uses the runlevels "boot", "sysinit" and "default", in that
|
|
||||||
order. Shutdown uses the "shutdown" runlevel.
|
|
||||||
|
|
||||||
|
|
||||||
# Syntax of Service Scripts
|
|
||||||
|
|
||||||
Service scripts are shell scripts. OpenRC aims at using only the standardized
|
|
||||||
POSIX sh subset for portability reasons. The default interpreter (build-time
|
|
||||||
toggle) is /bin/sh, so using for example mksh is not a problem.
|
|
||||||
|
|
||||||
OpenRC has been tested with busybox sh, ash, dash, bash, mksh, zsh and possibly
|
|
||||||
others. Using busybox sh has been difficult as it replaces commands with
|
|
||||||
builtins that don't offer the expected features.
|
|
||||||
|
|
||||||
The interpreter for initscripts is #!/sbin/openrc-run
|
|
||||||
Not using this interpreter will break the use of dependencies and is not
|
|
||||||
supported. (iow: if you insist on using #!/bin/sh you're on your own)
|
|
||||||
|
|
||||||
A "depend" function declares the dependencies of this service script.
|
|
||||||
All scripts must have start/stop/status functions, but defaults are provided.
|
|
||||||
Extra functions can be added easily:
|
|
||||||
|
|
||||||
extra_commands="checkconfig"
|
|
||||||
checkconfig() {
|
|
||||||
doSomething
|
|
||||||
}
|
|
||||||
|
|
||||||
This exports the checkconfig function so that "/etc/init.d/someservice
|
|
||||||
checkconfig" will be available, and it "just" runs this function.
|
|
||||||
|
|
||||||
While commands defined in extra_commands are always available, commands
|
|
||||||
defined in extra_started_commands will only work when the service is started
|
|
||||||
and those defined in extra_stopped_commands will only work when the service is
|
|
||||||
stopped. This can be used for implementing graceful reload and similar
|
|
||||||
behaviour.
|
|
||||||
|
|
||||||
Adding a restart function will not work, this is a design decision within
|
|
||||||
OpenRC. Since there may be dependencies involved (e.g. network -> apache) a
|
|
||||||
restart function is in general not going to work.
|
|
||||||
restart is internally mapped to stop() + start() (plus handling dependencies).
|
|
||||||
If a service needs to behave differently when it is being restarted vs
|
|
||||||
started or stopped, it should test the $RC_CMD variable, for example:
|
|
||||||
|
|
||||||
[ "$RC_CMD" = restart ] && do_something
|
|
||||||
|
|
||||||
|
|
||||||
# The Depend Function
|
|
||||||
|
|
||||||
This function declares the dependencies for a service script. This
|
|
||||||
determines the order the service scripts start.
|
|
||||||
|
|
||||||
depend() {
|
|
||||||
need net
|
|
||||||
use dns logger netmount
|
|
||||||
want coolservice
|
|
||||||
}
|
|
||||||
|
|
||||||
"need" declares a hard dependency - net always needs to be started before this
|
|
||||||
service does
|
|
||||||
"use" is a soft dependency - if dns, logger or netmount is in this runlevel
|
|
||||||
start it before, but we don't care if it's not in this runlevel.
|
|
||||||
"want" is between need and use - try to start coolservice if it is
|
|
||||||
installed on the system, regardless of whether it is in the
|
|
||||||
runlevel, but we don't care if it starts.
|
|
||||||
"before" declares that we need to be started before another service
|
|
||||||
"after" declares that we need to be started after another service, without
|
|
||||||
creating a dependency (so on calling stop the two are independent)
|
|
||||||
"provide" allows multiple implementations to provide one service type, e.g.:
|
|
||||||
'provide cron' is set in all cron-daemons, so any one of them started
|
|
||||||
satisfies a cron dependency
|
|
||||||
"keyword" allows platform-specific overrides, e.g. "keyword -lxc" makes this
|
|
||||||
service script a noop in lxc containers. Useful for things like keymaps,
|
|
||||||
module loading etc. that are either platform-specific or not available
|
|
||||||
in containers/virtualization/...
|
|
||||||
|
|
||||||
FIXME: Anything missing in this list?
|
|
||||||
|
|
||||||
# The Default Functions
|
|
||||||
|
|
||||||
All service scripts are assumed to have the following functions:
|
|
||||||
|
|
||||||
start()
|
|
||||||
stop()
|
|
||||||
status()
|
|
||||||
|
|
||||||
There are default implementations in rc/sh/openrc-run.sh - this allows very
|
|
||||||
compact service scripts. These functions can be overridden per service script as
|
|
||||||
needed.
|
|
||||||
|
|
||||||
The default functions assume the following variables to be set in the service
|
|
||||||
script:
|
|
||||||
|
|
||||||
command=
|
|
||||||
command_args=
|
|
||||||
pidfile=
|
|
||||||
|
|
||||||
Thus the 'smallest' service scripts can be half a dozen lines long
|
|
||||||
|
|
||||||
# The Magic of Conf.d
|
|
||||||
|
|
||||||
Most service scripts need default values. It would be fragile to
|
|
||||||
explicitly source some arbitrary files. By convention openrc-run will source
|
|
||||||
the matching file in /etc/conf.d/ for any script in /etc/init.d/
|
|
||||||
|
|
||||||
This allows you to set random startup-related things easily. Example:
|
|
||||||
|
|
||||||
conf.d/foo:
|
|
||||||
START_OPTS="--extraparameter sausage"
|
|
||||||
|
|
||||||
init.d/foo:
|
|
||||||
start() {
|
|
||||||
/usr/sbin/foo-daemon ${STARTOPTS}
|
|
||||||
}
|
|
||||||
|
|
||||||
The big advantage of this split is that most of the time editing of the init
|
|
||||||
script can be avoided.
|
|
||||||
|
|
||||||
# Start-Stop-Daemon
|
|
||||||
|
|
||||||
OpenRC has its own modified version of s-s-d, which is historically related and
|
|
||||||
mostly syntax-compatible to Debian's s-s-d, but has been rewritten from scratch.
|
|
||||||
|
|
||||||
It helps with starting daemons, backgrounding, creating PID files and many
|
|
||||||
other convenience functions related to managing daemons.
|
|
||||||
|
|
||||||
# /etc/rc.conf
|
|
||||||
|
|
||||||
This file manages the default configuration for OpenRC, and it has examples of
|
|
||||||
per-service-script variables.
|
|
||||||
|
|
||||||
Among these are rc_parallel (for parallelized startup), rc_log (logs all boot
|
|
||||||
messages to a file), and a few others.
|
|
||||||
|
|
||||||
# ulimit and CGroups
|
|
||||||
|
|
||||||
Setting ulimit and nice values per service can be done through the rc_ulimit
|
|
||||||
variable.
|
|
||||||
|
|
||||||
Under Linux, OpenRC can optionally use CGroups for process management.
|
|
||||||
By default each service script's processes are migrated to their own CGroup.
|
|
||||||
|
|
||||||
By changing certain values in the conf.d file limits can be enforced per
|
|
||||||
service. It is easy to find orphan processes of a service that persist after
|
|
||||||
stop(), but by default these will NOT be terminated.
|
|
||||||
To change this add rc_cgroup_cleanup="yes" in the conf.d files for services
|
|
||||||
where you desire this functionality.
|
|
||||||
|
|
||||||
# Caching
|
|
||||||
|
|
||||||
For performance reasons OpenRC keeps a cache of pre-parsed initscript metadata
|
|
||||||
(e.g. depend). The default location for this is /${RC_SVCDIR}/cache.
|
|
||||||
|
|
||||||
The cache uses mtime to check for file staleness. Should any service script
|
|
||||||
change it'll re-source the relevant files and update the cache
|
|
||||||
|
|
||||||
# Convenience functions
|
|
||||||
|
|
||||||
OpenRC has wrappers for many common output tasks in libeinfo.
|
|
||||||
This allows to print colour-coded status notices and other things.
|
|
||||||
To make the output consistent the bundled initscripts all use ebegin/eend to
|
|
||||||
print nice messages.
|
|
||||||
1
init.d/.gitignore
vendored
1
init.d/.gitignore
vendored
@@ -1,5 +1,4 @@
|
|||||||
binfmt
|
binfmt
|
||||||
modules-load
|
|
||||||
bootmisc
|
bootmisc
|
||||||
fsck
|
fsck
|
||||||
hostname
|
hostname
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ SRCS-FreeBSD= hostid.in moused.in newsyslog.in pf.in rarpd.in rc-enabled.in \
|
|||||||
rpcbind.in savecore.in syslogd.in
|
rpcbind.in savecore.in syslogd.in
|
||||||
# These are FreeBSD specific
|
# These are FreeBSD specific
|
||||||
SRCS-FreeBSD+= adjkerntz.in devd.in dumpon.in encswap.in ipfw.in \
|
SRCS-FreeBSD+= adjkerntz.in devd.in dumpon.in encswap.in ipfw.in \
|
||||||
modules.in modules-load.in mixer.in nscd.in powerd.in syscons.in
|
mixer.in nscd.in powerd.in syscons.in
|
||||||
|
|
||||||
SRCS-Linux= binfmt.in devfs.in dmesg.in hwclock.in consolefont.in keymaps.in \
|
SRCS-Linux= binfmt.in devfs.in dmesg.in hwclock.in consolefont.in keymaps.in \
|
||||||
killprocs.in modules.in modules-load.in mount-ro.in mtab.in numlock.in \
|
killprocs.in modules.in mount-ro.in mtab.in numlock.in \
|
||||||
procfs.in net-online.in sysfs.in termencoding.in tmpfiles.dev.in
|
procfs.in net-online.in sysfs.in termencoding.in tmpfiles.dev.in
|
||||||
|
|
||||||
# Generic BSD scripts
|
# Generic BSD scripts
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ depend()
|
|||||||
{
|
{
|
||||||
after procfs
|
after procfs
|
||||||
use modules devfs
|
use modules devfs
|
||||||
keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
|
keyword -openvz -prefix -systemd-nspawn -vserver -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ depend()
|
|||||||
{
|
{
|
||||||
need localmount termencoding
|
need localmount termencoding
|
||||||
after hotplug bootmisc modules
|
after hotplug bootmisc modules
|
||||||
keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
|
keyword -openvz -prefix -systemd-nspawn -uml -vserver -xenu -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ depend()
|
|||||||
{
|
{
|
||||||
provide dev-mount
|
provide dev-mount
|
||||||
before dev
|
before dev
|
||||||
keyword -docker -lxc -prefix -systemd-nspawn -vserver
|
keyword -prefix -systemd-nspawn -vserver -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
mount_dev()
|
mount_dev()
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ description="Set the dmesg level for a cleaner boot"
|
|||||||
depend()
|
depend()
|
||||||
{
|
{
|
||||||
before dev modules
|
before dev modules
|
||||||
keyword -docker -lxc -prefix -systemd-nspawn -vserver
|
keyword -lxc -prefix -systemd-nspawn -vserver
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ _IFS="
|
|||||||
depend()
|
depend()
|
||||||
{
|
{
|
||||||
use dev clock modules
|
use dev clock modules
|
||||||
keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -timeout -vserver -uml
|
keyword -jail -openvz -prefix -systemd-nspawn -timeout -vserver -lxc -uml
|
||||||
}
|
}
|
||||||
|
|
||||||
_abort() {
|
_abort() {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
description="Sets the hostname of the machine."
|
description="Sets the hostname of the machine."
|
||||||
|
|
||||||
depend() {
|
depend() {
|
||||||
keyword -docker -lxc -prefix -systemd-nspawn
|
keyword -prefix -systemd-nspawn -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ depend()
|
|||||||
else
|
else
|
||||||
before *
|
before *
|
||||||
fi
|
fi
|
||||||
keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
|
keyword -openvz -prefix -systemd-nspawn -uml -vserver -xenu -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
setupopts()
|
setupopts()
|
||||||
@@ -69,16 +69,6 @@ _hwclock()
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
get_noadjfile()
|
|
||||||
{
|
|
||||||
if ! yesno $clock_adjfile; then
|
|
||||||
# Some implementations don't handle adjustments
|
|
||||||
if LC_ALL=C hwclock --help 2>&1 | grep -q "\-\-noadjfile"; then
|
|
||||||
echo --noadjfile
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
start()
|
start()
|
||||||
{
|
{
|
||||||
local retval=0 errstr=""
|
local retval=0 errstr=""
|
||||||
@@ -101,16 +91,16 @@ start()
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Always set the kernel's time zone.
|
# Always set the kernel's time zone.
|
||||||
_hwclock --systz $utc_cmd $(get_noadjfile) $clock_args
|
_hwclock --systz $utc_cmd $clock_args
|
||||||
: $(( retval += $? ))
|
: $(( retval += $? ))
|
||||||
|
|
||||||
if [ -e /etc/adjtime ] && yesno $clock_adjfile; then
|
if [ -e /etc/adjtime ] && yesno $clock_adjfile; then
|
||||||
_hwclock --adjust $utc_cmd $(get_noadjfile)
|
_hwclock --adjust $utc_cmd
|
||||||
: $(( retval += $? ))
|
: $(( retval += $? ))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if yesno ${clock_hctosys:-YES}; then
|
if yesno ${clock_hctosys:-YES}; then
|
||||||
_hwclock --hctosys $utc_cmd $(get_noadjfile) $clock_args
|
_hwclock --hctosys $utc_cmd $clock_args
|
||||||
: $(( retval += $? ))
|
: $(( retval += $? ))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -132,7 +122,14 @@ stop()
|
|||||||
|
|
||||||
ebegin "Setting hardware clock using the system clock" "[$utc]"
|
ebegin "Setting hardware clock using the system clock" "[$utc]"
|
||||||
|
|
||||||
_hwclock --systohc $utc_cmd $(get_noadjfile) $clock_args
|
if ! yesno $clock_adjfile; then
|
||||||
|
# Some implementations don't handle adjustments
|
||||||
|
if LC_ALL=C hwclock --help 2>&1 | grep -q "\-\-noadjfile"; then
|
||||||
|
utc_cmd="$utc_cmd --noadjfile"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
_hwclock --systohc $utc_cmd $clock_args
|
||||||
retval=$?
|
retval=$?
|
||||||
|
|
||||||
eend $retval "Failed to sync clocks"
|
eend $retval "Failed to sync clocks"
|
||||||
@@ -147,5 +144,5 @@ save()
|
|||||||
show()
|
show()
|
||||||
{
|
{
|
||||||
setupopts
|
setupopts
|
||||||
hwclock --show "$utc_cmd" $(get_noadjfile) $clock_args
|
hwclock --show "$utc_cmd" $clock_args
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ depend()
|
|||||||
{
|
{
|
||||||
need localmount termencoding
|
need localmount termencoding
|
||||||
after bootmisc
|
after bootmisc
|
||||||
keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
|
keyword -openvz -prefix -systemd-nspawn -uml -vserver -xenu -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ start()
|
|||||||
{
|
{
|
||||||
ebegin "Terminating remaining processes"
|
ebegin "Terminating remaining processes"
|
||||||
killall5 -15 ${killall5_opts}
|
killall5 -15 ${killall5_opts}
|
||||||
|
sleep 1
|
||||||
eend 0
|
eend 0
|
||||||
ebegin "Killing remaining processes"
|
ebegin "Killing remaining processes"
|
||||||
killall5 -9 ${killall5_opts}
|
killall5 -9 ${killall5_opts}
|
||||||
|
sleep 1
|
||||||
eend 0
|
eend 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ depend()
|
|||||||
need fsck
|
need fsck
|
||||||
use lvm modules mtab
|
use lvm modules mtab
|
||||||
after lvm modules
|
after lvm modules
|
||||||
keyword -docker -jail -lxc -prefix -systemd-nspawn -vserver
|
keyword -jail -prefix -systemd-nspawn -vserver -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
{
|
{
|
||||||
# Mount local filesystems in /etc/fstab.
|
# Mount local filesystems in /etc/fstab.
|
||||||
local critical= types="noproc" x= no_netdev= rc=
|
local types="noproc" x= no_netdev= rc=
|
||||||
for x in $net_fs_list $extra_net_fs_list; do
|
for x in $net_fs_list $extra_net_fs_list; do
|
||||||
types="${types},no${x}"
|
types="${types},no${x}"
|
||||||
done
|
done
|
||||||
@@ -37,17 +37,13 @@ start()
|
|||||||
mount -at "$types" $no_netdev
|
mount -at "$types" $no_netdev
|
||||||
eend $? "Some local filesystem failed to mount"
|
eend $? "Some local filesystem failed to mount"
|
||||||
rc=$?
|
rc=$?
|
||||||
if [ -z "$critical_mounts" ]; then
|
if [ "$RC_UNAME" != Linux ]; then
|
||||||
rc=0
|
rc=0
|
||||||
else
|
elif yesno "${ignore_mount_errors:-NO}"; then
|
||||||
for x in ${critical_mounts}; do
|
if [ $rc -ne 0 ]; then
|
||||||
fstabinfo -q $x || continue
|
ewarn "localmount: errors detected, but ignored"
|
||||||
if ! mountinfo -q $x; then
|
|
||||||
critical=x
|
|
||||||
eerror "Failed to mount $x"
|
|
||||||
fi
|
fi
|
||||||
done
|
rc=0
|
||||||
[ -z "$critical" ] && rc=0
|
|
||||||
fi
|
fi
|
||||||
return $rc
|
return $rc
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
#!@SBINDIR@/openrc-run
|
|
||||||
# Copyright (c) 2016 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.
|
|
||||||
|
|
||||||
description="Loads a list of modules from systemd-compatible locations."
|
|
||||||
|
|
||||||
depend()
|
|
||||||
{
|
|
||||||
keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
|
|
||||||
}
|
|
||||||
|
|
||||||
find_modfiles()
|
|
||||||
{
|
|
||||||
local dirs="/usr/lib/modules-load.d /run/modules-load.d /etc/modules-load.d"
|
|
||||||
local basenames files fn x y
|
|
||||||
for x in $dirs; do
|
|
||||||
[ ! -d $x ] && continue
|
|
||||||
for y in $x/*.conf; do
|
|
||||||
[ -f $y ] && basenames="${basenames}\n${y##*/}"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
basenames=$(printf "$basenames" | sort -u)
|
|
||||||
for x in $basenames; do
|
|
||||||
for y in $dirs; do
|
|
||||||
[ -r $y/$x ] &&
|
|
||||||
fn=$y/$x
|
|
||||||
done
|
|
||||||
files="$files $fn"
|
|
||||||
done
|
|
||||||
echo $files
|
|
||||||
}
|
|
||||||
|
|
||||||
load_modules()
|
|
||||||
{
|
|
||||||
local file m modules rc x
|
|
||||||
file=$1
|
|
||||||
[ -z "$file" ] && return 0
|
|
||||||
while read m x; do
|
|
||||||
case $m in
|
|
||||||
\;) continue ;;
|
|
||||||
\#) continue ;;
|
|
||||||
*) modules="$modules $m"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done < $file
|
|
||||||
for x in $modules; do
|
|
||||||
ebegin "Loading module $x"
|
|
||||||
case "$RC_UNAME" in
|
|
||||||
FreeBSD) kldload "$x"; rc=$? ;;
|
|
||||||
linux) modprobe -q "$x"; rc=$? ;;
|
|
||||||
*) ;;
|
|
||||||
esac
|
|
||||||
eend $rc "Failed to load $x"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
start()
|
|
||||||
{
|
|
||||||
local x
|
|
||||||
files=$(find_modfiles)
|
|
||||||
for x in $files; do
|
|
||||||
load_modules $x
|
|
||||||
done
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
@@ -14,8 +14,7 @@ description="Loads a user defined list of kernel modules."
|
|||||||
depend()
|
depend()
|
||||||
{
|
{
|
||||||
use isapnp
|
use isapnp
|
||||||
want modules-load
|
keyword -openvz -prefix -systemd-nspawn -vserver -lxc
|
||||||
keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ description="Re-mount filesytems read-only for a clean reboot."
|
|||||||
depend()
|
depend()
|
||||||
{
|
{
|
||||||
need killprocs savecache
|
need killprocs savecache
|
||||||
keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
|
keyword -openvz -prefix -systemd-nspawn -vserver -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ depend()
|
|||||||
{
|
{
|
||||||
after modules
|
after modules
|
||||||
need sysfs
|
need sysfs
|
||||||
keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -uml -vserver
|
keyword -jail -lxc -openvz -prefix -systemd-nspawn -uml -vserver
|
||||||
}
|
}
|
||||||
|
|
||||||
get_interfaces()
|
get_interfaces()
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ depend()
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
config /etc/fstab
|
config /etc/fstab
|
||||||
want $mywant
|
want $mywant
|
||||||
use afc-client amd openvpn
|
use afc-client amd openvpn
|
||||||
use dns
|
use dns
|
||||||
keyword -docker -jail -lxc -prefix -systemd-nspawn -vserver
|
keyword -jail -prefix -systemd-nspawn -vserver -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
@@ -37,22 +37,13 @@ start()
|
|||||||
ebegin "Mounting network filesystems"
|
ebegin "Mounting network filesystems"
|
||||||
mount -at $fs
|
mount -at $fs
|
||||||
rc=$?
|
rc=$?
|
||||||
if [ "$RC_UNAME" = Linux ] && [ $rc = 0 ]; then
|
if [ "$RC_UNAME" = Linux ]; then
|
||||||
mount -a -O _netdev
|
mount -a -O _netdev
|
||||||
rc=$?
|
rc=$?
|
||||||
fi
|
fi
|
||||||
ewend $rc "Could not mount all network filesystems"
|
ewend $rc "Could not mount all network filesystems"
|
||||||
if [ -z "$critical_mounts" ]; then
|
if [ "$RC_UNAME" != Linux ]; then
|
||||||
rc=0
|
rc=0
|
||||||
else
|
|
||||||
for x in ${critical_mounts}; do
|
|
||||||
fstabinfo -q $x || continue
|
|
||||||
if ! mountinfo -q $x; then
|
|
||||||
critical=x
|
|
||||||
eerror "Failed to mount $x"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
[ -z "$critical" ] && rc=0
|
|
||||||
fi
|
fi
|
||||||
return $rc
|
return $rc
|
||||||
}
|
}
|
||||||
@@ -81,7 +72,7 @@ stop()
|
|||||||
retval=$?
|
retval=$?
|
||||||
|
|
||||||
eoutdent
|
eoutdent
|
||||||
if [ "$RC_UNAME" = Linux ] && [ $retval = 0 ]; then
|
if [ "$RC_UNAME" = Linux ]; then
|
||||||
umount -a -O _netdev
|
umount -a -O _netdev
|
||||||
retval=$?
|
retval=$?
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ ttyn=${rc_tty_number:-${RC_TTY_NUMBER:-12}}
|
|||||||
depend()
|
depend()
|
||||||
{
|
{
|
||||||
need localmount
|
need localmount
|
||||||
keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
|
keyword -openvz -prefix -systemd-nspawn -vserver -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
_setleds()
|
_setleds()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ depend()
|
|||||||
{
|
{
|
||||||
use modules devfs
|
use modules devfs
|
||||||
need localmount
|
need localmount
|
||||||
keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
|
keyword -openvz -prefix -systemd-nspawn -vserver -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ description="Mount the root fs read/write"
|
|||||||
depend()
|
depend()
|
||||||
{
|
{
|
||||||
need fsck
|
need fsck
|
||||||
keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -vserver
|
keyword -jail -openvz -prefix -systemd-nspawn -vserver -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ start()
|
|||||||
fi
|
fi
|
||||||
ebegin "Saving dependency cache"
|
ebegin "Saving dependency cache"
|
||||||
local rc=0 save=
|
local rc=0 save=
|
||||||
for x in deptree depconfig shutdowntime softlevel rc.log; do
|
for x in deptree depconfig shutdowntime softlevel nettree rc.log; do
|
||||||
[ -e "$RC_SVCDIR/$x" ] && save="$save $RC_SVCDIR/$x"
|
[ -e "$RC_SVCDIR/$x" ] && save="$save $RC_SVCDIR/$x"
|
||||||
done
|
done
|
||||||
if [ -n "$save" ]; then
|
if [ -n "$save" ]; then
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
depend()
|
depend()
|
||||||
{
|
{
|
||||||
before localmount
|
before localmount
|
||||||
keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -vserver
|
keyword -jail -openvz -prefix -systemd-nspawn -vserver -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
depend()
|
depend()
|
||||||
{
|
{
|
||||||
need localmount
|
need localmount
|
||||||
keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -vserver
|
keyword -jail -openvz -prefix -systemd-nspawn -vserver -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ depend()
|
|||||||
{
|
{
|
||||||
before *
|
before *
|
||||||
provide clock
|
provide clock
|
||||||
keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
|
keyword -openvz -prefix -systemd-nspawn -uml -vserver -xenu -lxc
|
||||||
}
|
}
|
||||||
|
|
||||||
# swclock is an OpenRC built in
|
# swclock is an OpenRC built in
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ sysfs_opts=nodev,noexec,nosuid
|
|||||||
|
|
||||||
depend()
|
depend()
|
||||||
{
|
{
|
||||||
keyword -docker -lxc -prefix -systemd-nspawn -vserver
|
keyword -lxc -prefix -systemd-nspawn -vserver
|
||||||
}
|
}
|
||||||
|
|
||||||
mount_sys()
|
mount_sys()
|
||||||
@@ -88,15 +88,6 @@ mount_misc()
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Setup Kernel Support for persistent storage
|
|
||||||
if [ -d /sys/fs/pstore ] && ! mountinfo -q /sys/fs/pstore; then
|
|
||||||
if grep -qs 'pstore$' /proc/filesystems; then
|
|
||||||
ebegin "Mounting persistent storage (pstore) filesystem"
|
|
||||||
mount -t pstore pstore -o ${sysfs_opts} /sys/fs/pstore
|
|
||||||
eend $?
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# setup up kernel support for efivarfs
|
# setup up kernel support for efivarfs
|
||||||
# slightly complicated, as if it's build as a module but NOT yet loaded,
|
# slightly complicated, as if it's build as a module but NOT yet loaded,
|
||||||
# it will NOT appear in /proc/filesystems yet
|
# it will NOT appear in /proc/filesystems yet
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ ttyn=${rc_tty_number:-${RC_TTY_NUMBER:-12}}
|
|||||||
|
|
||||||
depend()
|
depend()
|
||||||
{
|
{
|
||||||
keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
|
keyword -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
|
||||||
use root
|
use root
|
||||||
after bootmisc
|
after bootmisc
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ description="Initializes the random number generator."
|
|||||||
depend()
|
depend()
|
||||||
{
|
{
|
||||||
need localmount
|
need localmount
|
||||||
keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn
|
keyword -jail -lxc -openvz -prefix -systemd-nspawn
|
||||||
}
|
}
|
||||||
|
|
||||||
save_seed()
|
save_seed()
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ MAN3= einfo.3 \
|
|||||||
rc_config.3 rc_deptree.3 rc_find_pids.3 rc_plugin_hook.3 \
|
rc_config.3 rc_deptree.3 rc_find_pids.3 rc_plugin_hook.3 \
|
||||||
rc_runlevel.3 rc_service.3 rc_stringlist.3
|
rc_runlevel.3 rc_service.3 rc_stringlist.3
|
||||||
MAN8= rc-service.8 rc-status.8 rc-update.8 openrc.8 openrc-run.8 \
|
MAN8= rc-service.8 rc-status.8 rc-update.8 openrc.8 openrc-run.8 \
|
||||||
service.8 start-stop-daemon.8 supervise-daemon.8
|
service.8 start-stop-daemon.8
|
||||||
|
|
||||||
ifeq (${OS},Linux)
|
ifeq (${OS},Linux)
|
||||||
MAN8 += rc-sstat.8
|
MAN8 += rc-sstat.8
|
||||||
|
|||||||
@@ -95,17 +95,10 @@ String describing the service.
|
|||||||
.It Ar description_$command
|
.It Ar description_$command
|
||||||
String describing the extra command.
|
String describing the extra command.
|
||||||
.It Ar supervisor
|
.It Ar supervisor
|
||||||
Supervisor to use to monitor this daemon. If this is unset or invalid,
|
Supervisor to use to monitor this daemon. If this is unset,
|
||||||
start-stop-daemon will be used.
|
start-stop-daemon will be used. The only alternate supervisor we support
|
||||||
Currently, we support s6 from scarnet software, and supervise-daemon
|
in this release is S6 from Skarnet software. To use this, set
|
||||||
which is a light-weight supervisor internal to OpenRC.
|
|
||||||
To use s6, set
|
|
||||||
supervisor=s6.
|
supervisor=s6.
|
||||||
or set
|
|
||||||
supervisor=supervise-daemon
|
|
||||||
to use supervise-daemon.
|
|
||||||
Note that supervise-daemon is still in early development, so it is
|
|
||||||
considered experimental.
|
|
||||||
.It Ar s6_service_path
|
.It Ar s6_service_path
|
||||||
The path to the s6 service directory if you are monitoring this service
|
The path to the s6 service directory if you are monitoring this service
|
||||||
with S6. The default is /var/svc.d/${RC_SVCNAME}.
|
with S6. The default is /var/svc.d/${RC_SVCNAME}.
|
||||||
@@ -119,16 +112,10 @@ List of arguments passed to start-stop-daemon when starting the daemon.
|
|||||||
.It Ar command
|
.It Ar command
|
||||||
Daemon to start or stop via
|
Daemon to start or stop via
|
||||||
.Nm start-stop-daemon
|
.Nm start-stop-daemon
|
||||||
or
|
|
||||||
.Nm supervise-daemon
|
|
||||||
if no start or stop function is defined by the service.
|
if no start or stop function is defined by the service.
|
||||||
.It Ar command_args
|
.It Ar command_args
|
||||||
List of arguments to pass to the daemon when starting via
|
List of arguments to pass to the daemon when starting via
|
||||||
.Nm start-stop-daemon .
|
.Nm start-stop-daemon .
|
||||||
.It Ar command_args_foreground
|
|
||||||
List of arguments to pass to the daemon when starting via
|
|
||||||
.Nm supervise-daemon .
|
|
||||||
to force the daemon to stay in the foreground
|
|
||||||
.It Ar command_background
|
.It Ar command_background
|
||||||
Set this to "true", "yes" or "1" (case-insensitive) to force the daemon into
|
Set this to "true", "yes" or "1" (case-insensitive) to force the daemon into
|
||||||
the background. This implies the "--make-pidfile" and "--pidfile" option of
|
the background. This implies the "--make-pidfile" and "--pidfile" option of
|
||||||
@@ -136,8 +123,6 @@ the background. This implies the "--make-pidfile" and "--pidfile" option of
|
|||||||
so the pidfile variable must be set.
|
so the pidfile variable must be set.
|
||||||
.It Ar chroot
|
.It Ar chroot
|
||||||
.Xr start-stop-daemon 8
|
.Xr start-stop-daemon 8
|
||||||
and
|
|
||||||
.Xr supervise-daemon 8
|
|
||||||
will chroot into this path before writing the pid file or starting the daemon.
|
will chroot into this path before writing the pid file or starting the daemon.
|
||||||
.It Ar pidfile
|
.It Ar pidfile
|
||||||
Pidfile to use for the above defined command.
|
Pidfile to use for the above defined command.
|
||||||
@@ -187,9 +172,9 @@ The service will start after these services and stop before these services.
|
|||||||
The service will start before these services and stop after these services.
|
The service will start before these services and stop after these services.
|
||||||
.It Ic provide
|
.It Ic provide
|
||||||
The service provides this virtual service. For example, named provides dns.
|
The service provides this virtual service. For example, named provides dns.
|
||||||
Note that it is not legal to have a virtual and real service with the
|
Virtual services take precedence over real services, so it is highly
|
||||||
same name. If you do this, you will receive an error message, and you
|
recommended that you do not have a real service that has the same name
|
||||||
must rename either the real or virtual service.
|
as a virtual service.
|
||||||
.It Ic config
|
.It Ic config
|
||||||
We should recalculate our dependencies if the listed files have changed.
|
We should recalculate our dependencies if the listed files have changed.
|
||||||
.It Ic keyword
|
.It Ic keyword
|
||||||
|
|||||||
@@ -20,14 +20,6 @@
|
|||||||
.Ar service cmd
|
.Ar service cmd
|
||||||
.Op Ar ...
|
.Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl I , -ifinactive
|
|
||||||
.Ar service cmd
|
|
||||||
.Op Ar ...
|
|
||||||
.Nm
|
|
||||||
.Op Fl N , -ifnotstarted
|
|
||||||
.Ar service cmd
|
|
||||||
.Op Ar ...
|
|
||||||
.Nm
|
|
||||||
.Fl e , -exists
|
.Fl e , -exists
|
||||||
.Ar service
|
.Ar service
|
||||||
.Nm
|
.Nm
|
||||||
@@ -44,13 +36,6 @@ If
|
|||||||
is given then
|
is given then
|
||||||
.Nm
|
.Nm
|
||||||
returns 0 even if the service does not exist.
|
returns 0 even if the service does not exist.
|
||||||
If
|
|
||||||
.Fl I , -ifinactive
|
|
||||||
or
|
|
||||||
.Fl N , -ifnotstarted
|
|
||||||
is given then
|
|
||||||
.Nm
|
|
||||||
returns 0 if the service exists but is in the wrong state.
|
|
||||||
.Pp
|
.Pp
|
||||||
If given the
|
If given the
|
||||||
.Fl l , -list
|
.Fl l , -list
|
||||||
|
|||||||
@@ -1,142 +0,0 @@
|
|||||||
.\" Copyright (c) 2007-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.
|
|
||||||
.\"
|
|
||||||
.Dd April 27, 2016
|
|
||||||
.Dt supervise-DAEMON 8 SMM
|
|
||||||
.Os OpenRC
|
|
||||||
.Sh NAME
|
|
||||||
.Nm supervise-daemon
|
|
||||||
.Nd starts a daemon and restarts it if it crashes
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.Nm
|
|
||||||
.Fl d , -chdir
|
|
||||||
.Ar path
|
|
||||||
.Fl e , -env
|
|
||||||
.Ar var=value
|
|
||||||
.Fl g , -group
|
|
||||||
.Ar group
|
|
||||||
.Fl I , -ionice
|
|
||||||
.Ar arg
|
|
||||||
.Fl k , -umask
|
|
||||||
.Ar value
|
|
||||||
.Fl N , -nicelevel
|
|
||||||
.Ar level
|
|
||||||
.Fl p , -pidfile
|
|
||||||
.Ar pidfile
|
|
||||||
.Fl u , -user
|
|
||||||
.Ar user
|
|
||||||
.Fl r , -chroot
|
|
||||||
.Ar chrootpath
|
|
||||||
.Fl 1 , -stdout
|
|
||||||
.Ar logfile
|
|
||||||
.Fl 2 , -stderr
|
|
||||||
.Ar logfile
|
|
||||||
.Fl S , -start
|
|
||||||
.Ar daemon
|
|
||||||
.Op Fl -
|
|
||||||
.Op Ar arguments
|
|
||||||
.Nm
|
|
||||||
.Fl K , -stop
|
|
||||||
.Ar daemon
|
|
||||||
.Fl p , -pidfile
|
|
||||||
.Ar pidfile
|
|
||||||
.Fl r , -chroot
|
|
||||||
.Ar chrootpath
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
.Nm
|
|
||||||
provides a consistent method of starting, stopping and restarting
|
|
||||||
daemons. If
|
|
||||||
.Fl K , -stop
|
|
||||||
is not provided, then we assume we are starting the daemon.
|
|
||||||
.Nm
|
|
||||||
only works with daemons which do not fork. Also, it uses its own pid
|
|
||||||
file, so the daemon should not write a pid file, or the pid file passed
|
|
||||||
to
|
|
||||||
.Nm
|
|
||||||
should not be the one the daemon writes.
|
|
||||||
.Pp
|
|
||||||
Here are the options to specify the daemon and how it should start or stop:
|
|
||||||
.Bl -tag -width indent
|
|
||||||
.It Fl p , -pidfile Ar pidfile
|
|
||||||
When starting, we write a
|
|
||||||
.Ar pidfile
|
|
||||||
so we know which supervisor to stop. When stopping we only stop the pid(s)
|
|
||||||
listed in the
|
|
||||||
.Ar pidfile .
|
|
||||||
.It Fl u , -user Ar user Ns Op : Ns Ar group
|
|
||||||
Start the daemon as the
|
|
||||||
.Ar user
|
|
||||||
and update $HOME accordingly or stop daemons
|
|
||||||
owned by the user. You can optionally append a
|
|
||||||
.Ar group
|
|
||||||
name here also.
|
|
||||||
.It Fl v , -verbose
|
|
||||||
Print the action(s) that are taken just before doing them.
|
|
||||||
.Pp
|
|
||||||
The options are as follows:
|
|
||||||
.Bl -tag -width indent
|
|
||||||
.It Fl d , -chdir Ar path
|
|
||||||
chdir to this directory before starting the daemon.
|
|
||||||
.It Fl e , -env Ar VAR=VALUE
|
|
||||||
Set the environment variable VAR to VALUE.
|
|
||||||
.It Fl g , -group Ar group
|
|
||||||
Start the daemon as in the group.
|
|
||||||
.It Fl I , -ionice Ar class Ns Op : Ns Ar data
|
|
||||||
Modifies the IO scheduling priority of the daemon.
|
|
||||||
Class can be 0 for none, 1 for real time, 2 for best effort and 3 for idle.
|
|
||||||
Data can be from 0 to 7 inclusive.
|
|
||||||
.It Fl k , -umask Ar mode
|
|
||||||
Set the umask of the daemon.
|
|
||||||
.It Fl N , -nicelevel Ar level
|
|
||||||
Modifies the scheduling priority of the daemon.
|
|
||||||
.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.
|
|
||||||
.It Fl u , -user Ar user
|
|
||||||
Start the daemon as the specified user.
|
|
||||||
.It Fl 1 , -stdout Ar logfile
|
|
||||||
Redirect the standard output of the process to logfile.
|
|
||||||
Must be an absolute pathname, but relative to the path optionally given with
|
|
||||||
.Fl r , -chroot .
|
|
||||||
The logfile can also be a named pipe.
|
|
||||||
.It Fl 2 , -stderr Ar logfile
|
|
||||||
The same thing as
|
|
||||||
.Fl 1 , -stdout
|
|
||||||
but with the standard error output.
|
|
||||||
.El
|
|
||||||
.Sh ENVIRONMENT
|
|
||||||
.Va SSD_NICELEVEL
|
|
||||||
can also set the scheduling priority of the daemon, but the command line
|
|
||||||
option takes precedence.
|
|
||||||
.Sh NOTE
|
|
||||||
.Nm
|
|
||||||
uses
|
|
||||||
.Xr getopt 3
|
|
||||||
to parse its options, which allows it to accept the `--' option which will
|
|
||||||
cause it to stop processing options at that point. Any subsequent arguments
|
|
||||||
are passed as arguments to the daemon to start and used when finding a daemon
|
|
||||||
to stop or signal.
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr chdir 2 ,
|
|
||||||
.Xr chroot 2 ,
|
|
||||||
.Xr getopt 3 ,
|
|
||||||
.Xr nice 2 ,
|
|
||||||
.Xr rc_find_pids 3
|
|
||||||
.Sh BUGS
|
|
||||||
.Nm
|
|
||||||
cannot stop an interpreted daemon that no longer exists without a pidfile.
|
|
||||||
.Sh HISTORY
|
|
||||||
.Nm
|
|
||||||
first appeared in Debian.
|
|
||||||
.Pp
|
|
||||||
This is a complete re-implementation with the process finding code in the
|
|
||||||
OpenRC library (librc, -lrc) so other programs can make use of it.
|
|
||||||
.Sh AUTHORS
|
|
||||||
.An William Hubbs <w.d.hubbs@gmail.com>
|
|
||||||
@@ -3,6 +3,4 @@
|
|||||||
|
|
||||||
ifeq (${MKPREFIX},yes)
|
ifeq (${MKPREFIX},yes)
|
||||||
CPPFLAGS+= -DPREFIX
|
CPPFLAGS+= -DPREFIX
|
||||||
PKG_PREFIX?= $(PREFIX)/usr
|
|
||||||
SED_EXTRA= -e '/_PATH=.*usr.bin/d'
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
2
mk/os.mk
2
mk/os.mk
@@ -13,7 +13,7 @@
|
|||||||
_OS_SH= uname -s | tr '/' '-'
|
_OS_SH= uname -s | tr '/' '-'
|
||||||
_OS:= $(shell ${_OS_SH})
|
_OS:= $(shell ${_OS_SH})
|
||||||
OS?= ${_OS}
|
OS?= ${_OS}
|
||||||
include ${MK}/os-prefix.mk
|
|
||||||
include ${MK}/os-${OS}.mk
|
include ${MK}/os-${OS}.mk
|
||||||
|
include ${MK}/os-prefix.mk
|
||||||
|
|
||||||
RC_LIB= /$(LIBNAME)/rc
|
RC_LIB= /$(LIBNAME)/rc
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
AR?= ar
|
AR?= ar
|
||||||
CP?= cp
|
CP?= cp
|
||||||
PKG_CONFIG?= pkg-config
|
|
||||||
ECHO?= echo
|
ECHO?= echo
|
||||||
INSTALL?= install
|
INSTALL?= install
|
||||||
RANLIB?= ranlib
|
RANLIB?= ranlib
|
||||||
@@ -27,7 +26,7 @@ ifeq (${MKPREFIX},yes)
|
|||||||
UPREFIX= ${PREFIX}/usr
|
UPREFIX= ${PREFIX}/usr
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
LOCAL_PREFIX= $(UPREFIX)/local
|
LOCAL_PREFIX= /usr/local
|
||||||
|
|
||||||
PICFLAG?= -fPIC
|
PICFLAG?= -fPIC
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
ifeq (${MKTERMCAP},ncurses)
|
ifeq (${MKTERMCAP},ncurses)
|
||||||
TERMCAP_CFLAGS:= $(shell ${PKG_CONFIG} ncurses --cflags 2> /dev/null)
|
TERMCAP_CFLAGS:= $(shell pkg-config ncurses --cflags 2> /dev/null)
|
||||||
LTERMCAP:= $(shell ${PKG_CONFIG} ncurses --libs 2> /dev/null)
|
LTERMCAP:= $(shell pkg-config ncurses --libs 2> /dev/null)
|
||||||
ifeq ($(LTERMCAP),)
|
ifeq ($(LTERMCAP),)
|
||||||
LIBTERMCAP?= -lncurses
|
LIBTERMCAP?= -lncurses
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ include ../mk/net.mk
|
|||||||
BOOT= bootmisc fsck hostname localmount loopback \
|
BOOT= bootmisc fsck hostname localmount loopback \
|
||||||
root swap swapfiles sysctl urandom ${BOOT-${OS}}
|
root swap swapfiles sysctl urandom ${BOOT-${OS}}
|
||||||
DEFAULT= local netmount
|
DEFAULT= local netmount
|
||||||
NONETWORK= local
|
|
||||||
SHUTDOWN= savecache ${SHUTDOWN-${OS}}
|
SHUTDOWN= savecache ${SHUTDOWN-${OS}}
|
||||||
SYSINIT= ${SYSINIT-${OS}}
|
SYSINIT= ${SYSINIT-${OS}}
|
||||||
|
|
||||||
@@ -11,7 +10,6 @@ LEVELDIR= ${DESTDIR}/${SYSCONFDIR}/runlevels
|
|||||||
SYSINITDIR= ${LEVELDIR}/sysinit
|
SYSINITDIR= ${LEVELDIR}/sysinit
|
||||||
BOOTDIR= ${LEVELDIR}/boot
|
BOOTDIR= ${LEVELDIR}/boot
|
||||||
DEFAULTDIR= ${LEVELDIR}/default
|
DEFAULTDIR= ${LEVELDIR}/default
|
||||||
NONETWORKDIR= ${LEVELDIR}/nonetwork
|
|
||||||
SHUTDOWNDIR= ${LEVELDIR}/shutdown
|
SHUTDOWNDIR= ${LEVELDIR}/shutdown
|
||||||
|
|
||||||
ifeq (${MKNET},yes)
|
ifeq (${MKNET},yes)
|
||||||
@@ -74,14 +72,6 @@ install:
|
|||||||
fi; \
|
fi; \
|
||||||
ln -snf ${INITDIR}/"$$x" ${DEFAULTDIR}/"$$x" || exit $$?; done \
|
ln -snf ${INITDIR}/"$$x" ${DEFAULTDIR}/"$$x" || exit $$?; done \
|
||||||
fi
|
fi
|
||||||
if ! test -d "${NONETWORKDIR}"; then \
|
|
||||||
${INSTALL} -d ${NONETWORKDIR} || exit $$?; \
|
|
||||||
for x in ${NONETWORK}; do \
|
|
||||||
if test "${MKPREFIX}" = yes; then \
|
|
||||||
grep -q "keyword .*-prefix" ${INITFILES}/"$$x" && continue; \
|
|
||||||
fi; \
|
|
||||||
ln -snf ${INITDIR}/"$$x" ${NONETWORKDIR}/"$$x" || exit $$?; done \
|
|
||||||
fi
|
|
||||||
if ! test -d "${SHUTDOWNDIR}"; then \
|
if ! test -d "${SHUTDOWNDIR}"; then \
|
||||||
${INSTALL} -d ${SHUTDOWNDIR} || exit $$?; \
|
${INSTALL} -d ${SHUTDOWNDIR} || exit $$?; \
|
||||||
for x in ${SHUTDOWN}; do \
|
for x in ${SHUTDOWN}; do \
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ if [ ! -d $scandir ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Make sure s6-svscan is running
|
# Make sure s6-svscan is running
|
||||||
if ! pgrep s6-svscan >/dev/null ; then
|
if ! pgrep s6-svscan >/dev/null ; then
|
||||||
printf "s6-svscan is not running\n"
|
printf "s6-svscan is not running\n"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -141,7 +141,7 @@ do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
rm -f $statfile 2>/dev/null
|
rm -f $statfile 2>/dev/null
|
||||||
|
|
||||||
printf "\n\n"
|
printf "\n\n"
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
DIR= ${LIBEXECDIR}/sh
|
DIR= ${LIBEXECDIR}/sh
|
||||||
SRCS= init.sh.in functions.sh.in gendepends.sh.in \
|
SRCS= init.sh.in functions.sh.in gendepends.sh.in \
|
||||||
openrc-run.sh.in rc-functions.sh.in tmpfiles.sh.in ${SRCS-${OS}}
|
openrc-run.sh.in rc-functions.sh.in tmpfiles.sh.in ${SRCS-${OS}}
|
||||||
INC= functions.sh rc-mount.sh rc-functions.sh s6.sh start-stop-daemon.sh \
|
INC= rc-mount.sh functions.sh rc-functions.sh s6.sh start-stop-daemon.sh
|
||||||
supervise-daemon.sh
|
|
||||||
BIN= gendepends.sh init.sh openrc-run.sh tmpfiles.sh ${BIN-${OS}}
|
BIN= gendepends.sh init.sh openrc-run.sh tmpfiles.sh ${BIN-${OS}}
|
||||||
|
|
||||||
INSTALLAFTER= _installafter
|
INSTALLAFTER= _installafter
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ apply_file() {
|
|||||||
|
|
||||||
### FILE FORMAT ###
|
### FILE FORMAT ###
|
||||||
# See https://www.kernel.org/doc/Documentation/binfmt_misc.txt
|
# See https://www.kernel.org/doc/Documentation/binfmt_misc.txt
|
||||||
while read -r line; do
|
while read line; do
|
||||||
LINENUM=$(( LINENUM+1 ))
|
LINENUM=$(( LINENUM+1 ))
|
||||||
case $line in
|
case $line in
|
||||||
\#*) continue ;;
|
\#*) continue ;;
|
||||||
|
|||||||
@@ -154,7 +154,6 @@ start()
|
|||||||
local func=ssd_start
|
local func=ssd_start
|
||||||
case "$supervisor" in
|
case "$supervisor" in
|
||||||
s6) func=s6_start ;;
|
s6) func=s6_start ;;
|
||||||
supervise-daemon) func=supervise_start ;;
|
|
||||||
?*)
|
?*)
|
||||||
ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
|
ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
|
||||||
;;
|
;;
|
||||||
@@ -167,7 +166,6 @@ stop()
|
|||||||
local func=ssd_stop
|
local func=ssd_stop
|
||||||
case "$supervisor" in
|
case "$supervisor" in
|
||||||
s6) func=s6_stop ;;
|
s6) func=s6_stop ;;
|
||||||
supervise-daemon) func=supervise_stop ;;
|
|
||||||
?*)
|
?*)
|
||||||
ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
|
ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
|
||||||
;;
|
;;
|
||||||
@@ -180,7 +178,6 @@ status()
|
|||||||
local func=ssd_status
|
local func=ssd_status
|
||||||
case "$supervisor" in
|
case "$supervisor" in
|
||||||
s6) func=s6_status ;;
|
s6) func=s6_status ;;
|
||||||
supervise-daemon) func=supervise_status ;;
|
|
||||||
?*)
|
?*)
|
||||||
ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
|
ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
|
||||||
;;
|
;;
|
||||||
@@ -218,7 +215,6 @@ fi
|
|||||||
# load service supervisor functions
|
# load service supervisor functions
|
||||||
sourcex "@LIBEXECDIR@/sh/s6.sh"
|
sourcex "@LIBEXECDIR@/sh/s6.sh"
|
||||||
sourcex "@LIBEXECDIR@/sh/start-stop-daemon.sh"
|
sourcex "@LIBEXECDIR@/sh/start-stop-daemon.sh"
|
||||||
sourcex "@LIBEXECDIR@/sh/supervise-daemon.sh"
|
|
||||||
|
|
||||||
# Set verbose mode
|
# Set verbose mode
|
||||||
if yesno "${rc_verbose:-$RC_VERBOSE}"; then
|
if yesno "${rc_verbose:-$RC_VERBOSE}"; then
|
||||||
@@ -248,7 +244,7 @@ for _cmd; do
|
|||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Load our script
|
# Load our script
|
||||||
sourcex "$RC_SERVICE"
|
sourcex "$RC_SERVICE"
|
||||||
|
|
||||||
|
|||||||
2
sh/s6.sh
2
sh/s6.sh
@@ -41,7 +41,7 @@ s6_stop()
|
|||||||
fi
|
fi
|
||||||
s6_service_link="${RC_SVCDIR}/s6-scan/${s6_service_path##*/}"
|
s6_service_link="${RC_SVCDIR}/s6-scan/${s6_service_path##*/}"
|
||||||
ebegin "Stopping ${name:-$RC_SVCNAME}"
|
ebegin "Stopping ${name:-$RC_SVCNAME}"
|
||||||
s6-svc -wD -d -T ${s6_service_timeout_stop:-10000} "${s6_service_link}"
|
s6-svc -Dd -T ${s6_service_timeout_stop:-10000} "${s6_service_link}"
|
||||||
set -- $(s6-svstat "${s6_service_link}")
|
set -- $(s6-svstat "${s6_service_link}")
|
||||||
[ "$1" = "down" ]
|
[ "$1" = "down" ]
|
||||||
eend $? "Failed to stop $RC_SVCNAME"
|
eend $? "Failed to stop $RC_SVCNAME"
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ ssd_start()
|
|||||||
fi
|
fi
|
||||||
eval start-stop-daemon --start \
|
eval start-stop-daemon --start \
|
||||||
--exec $command \
|
--exec $command \
|
||||||
${chroot:+--chroot} $chroot \
|
|
||||||
${procname:+--name} $procname \
|
${procname:+--name} $procname \
|
||||||
${pidfile:+--pidfile} $pidfile \
|
${pidfile:+--pidfile} $pidfile \
|
||||||
${command_user+--user} $command_user \
|
${command_user+--user} $command_user \
|
||||||
@@ -48,7 +47,6 @@ ssd_start()
|
|||||||
-- $command_args $command_args_background
|
-- $command_args $command_args_background
|
||||||
if eend $? "Failed to start $RC_SVCNAME"; then
|
if eend $? "Failed to start $RC_SVCNAME"; then
|
||||||
service_set_value "command" "${command}"
|
service_set_value "command" "${command}"
|
||||||
[ -n "${chroot}" ] && service_set_value "chroot" "${chroot}"
|
|
||||||
[ -n "${pidfile}" ] && service_set_value "pidfile" "${pidfile}"
|
[ -n "${pidfile}" ] && service_set_value "pidfile" "${pidfile}"
|
||||||
[ -n "${procname}" ] && service_set_value "procname" "${procname}"
|
[ -n "${procname}" ] && service_set_value "procname" "${procname}"
|
||||||
return 0
|
return 0
|
||||||
@@ -64,11 +62,9 @@ ssd_start()
|
|||||||
ssd_stop()
|
ssd_stop()
|
||||||
{
|
{
|
||||||
local startcommand="$(service_get_value "command")"
|
local startcommand="$(service_get_value "command")"
|
||||||
local startchroot="$(service_get_value "chroot")"
|
|
||||||
local startpidfile="$(service_get_value "pidfile")"
|
local startpidfile="$(service_get_value "pidfile")"
|
||||||
local startprocname="$(service_get_value "procname")"
|
local startprocname="$(service_get_value "procname")"
|
||||||
command="${startcommand:-$command}"
|
command="${startcommand:-$command}"
|
||||||
chroot="${startchroot:-$chroot}"
|
|
||||||
pidfile="${startpidfile:-$pidfile}"
|
pidfile="${startpidfile:-$pidfile}"
|
||||||
procname="${startprocname:-$procname}"
|
procname="${startprocname:-$procname}"
|
||||||
[ -n "$command" -o -n "$procname" -o -n "$pidfile" ] || return 0
|
[ -n "$command" -o -n "$procname" -o -n "$pidfile" ] || return 0
|
||||||
@@ -77,7 +73,7 @@ ssd_stop()
|
|||||||
${retry:+--retry} $retry \
|
${retry:+--retry} $retry \
|
||||||
${command:+--exec} $command \
|
${command:+--exec} $command \
|
||||||
${procname:+--name} $procname \
|
${procname:+--name} $procname \
|
||||||
${pidfile:+--pidfile} $chroot$pidfile \
|
${pidfile:+--pidfile} $pidfile \
|
||||||
${stopsig:+--signal} $stopsig
|
${stopsig:+--signal} $stopsig
|
||||||
|
|
||||||
eend $? "Failed to stop $RC_SVCNAME"
|
eend $? "Failed to stop $RC_SVCNAME"
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
# start / stop / status functions for supervise-daemon
|
|
||||||
|
|
||||||
# Copyright (c) 2016 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.
|
|
||||||
|
|
||||||
supervise_start()
|
|
||||||
{
|
|
||||||
if [ -z "$command" ]; then
|
|
||||||
ewarn "The command variable is undefined."
|
|
||||||
ewarn "There is nothing for ${name:-$RC_SVCNAME} to start."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
ebegin "Starting ${name:-$RC_SVCNAME}"
|
|
||||||
eval supervise-daemon --start \
|
|
||||||
${chroot:+--chroot} $chroot \
|
|
||||||
${pidfile:+--pidfile} $pidfile \
|
|
||||||
${command_user+--user} $command_user \
|
|
||||||
$supervise_daemon_args \
|
|
||||||
$command \
|
|
||||||
-- $command_args $command_args_foreground
|
|
||||||
rc=$?
|
|
||||||
if [ $rc = 0 ]; then
|
|
||||||
[ -n "${chroot}" ] && service_set_value "chroot" "${chroot}"
|
|
||||||
[ -n "${pidfile}" ] && service_set_value "pidfile" "${pidfile}"
|
|
||||||
fi
|
|
||||||
eend $rc "failed to start $RC_SVCNAME"
|
|
||||||
}
|
|
||||||
|
|
||||||
supervise_stop()
|
|
||||||
{
|
|
||||||
local startchroot="$(service_get_value "chroot")"
|
|
||||||
local startpidfile="$(service_get_value "pidfile")"
|
|
||||||
chroot="${startchroot:-$chroot}"
|
|
||||||
pidfile="${startpidfile:-$pidfile}"
|
|
||||||
[ -n "$pidfile" ] || return 0
|
|
||||||
ebegin "Stopping ${name:-$RC_SVCNAME}"
|
|
||||||
supervise-daemon --stop \
|
|
||||||
${pidfile:+--pidfile} $chroot$pidfile \
|
|
||||||
${stopsig:+--signal} $stopsig
|
|
||||||
|
|
||||||
eend $? "Failed to stop $RC_SVCNAME"
|
|
||||||
}
|
|
||||||
|
|
||||||
supervise_status()
|
|
||||||
{
|
|
||||||
_status
|
|
||||||
}
|
|
||||||
@@ -717,16 +717,14 @@ rc_deptree_update_needed(time_t *newest, char *file)
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_deptree_update_needed)
|
librc_hidden_def(rc_deptree_update_needed)
|
||||||
|
|
||||||
/* This is a 7 phase operation
|
/* This is a 6 phase operation
|
||||||
Phase 1 is a shell script which loads each init script and config in turn
|
Phase 1 is a shell script which loads each init script and config in turn
|
||||||
and echos their dependency info to stdout
|
and echos their dependency info to stdout
|
||||||
Phase 2 takes that and populates a depinfo object with that data
|
Phase 2 takes that and populates a depinfo object with that data
|
||||||
Phase 3 adds any provided services to the depinfo object
|
Phase 3 adds any provided services to the depinfo object
|
||||||
Phase 4 scans that depinfo object and puts in backlinks
|
Phase 4 scans that depinfo object and puts in backlinks
|
||||||
Phase 5 removes broken before dependencies
|
Phase 5 removes broken before dependencies
|
||||||
Phase 6 looks for duplicate services indicating a real and virtual service
|
Phase 6 saves the depinfo object to disk
|
||||||
with the same names
|
|
||||||
Phase 7 saves the depinfo object to disk
|
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
rc_deptree_update(void)
|
rc_deptree_update(void)
|
||||||
@@ -735,7 +733,7 @@ rc_deptree_update(void)
|
|||||||
RC_DEPTREE *deptree, *providers;
|
RC_DEPTREE *deptree, *providers;
|
||||||
RC_DEPINFO *depinfo = NULL, *depinfo_np, *di;
|
RC_DEPINFO *depinfo = NULL, *depinfo_np, *di;
|
||||||
RC_DEPTYPE *deptype = NULL, *dt_np, *dt, *provide;
|
RC_DEPTYPE *deptype = NULL, *dt_np, *dt, *provide;
|
||||||
RC_STRINGLIST *config, *dupes, *types, *sorted, *visited;
|
RC_STRINGLIST *config, *types, *sorted, *visited;
|
||||||
RC_STRING *s, *s2, *s2_np, *s3, *s4;
|
RC_STRING *s, *s2, *s2_np, *s3, *s4;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
@@ -744,7 +742,6 @@ rc_deptree_update(void)
|
|||||||
bool retval = true;
|
bool retval = true;
|
||||||
const char *sys = rc_sys();
|
const char *sys = rc_sys();
|
||||||
struct utsname uts;
|
struct utsname uts;
|
||||||
int serrno;
|
|
||||||
|
|
||||||
/* Some init scripts need RC_LIBEXECDIR to source stuff
|
/* Some init scripts need RC_LIBEXECDIR to source stuff
|
||||||
Ideally we should be setting our full env instead */
|
Ideally we should be setting our full env instead */
|
||||||
@@ -999,22 +996,7 @@ rc_deptree_update(void)
|
|||||||
}
|
}
|
||||||
rc_stringlist_free(types);
|
rc_stringlist_free(types);
|
||||||
|
|
||||||
/* Phase 6 - Print errors for duplicate services */
|
/* Phase 6 - save to disk
|
||||||
dupes = rc_stringlist_new();
|
|
||||||
TAILQ_FOREACH(depinfo, deptree, entries) {
|
|
||||||
serrno = errno;
|
|
||||||
errno = 0;
|
|
||||||
rc_stringlist_addu(dupes,depinfo->service);
|
|
||||||
if (errno == EEXIST) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error: %s is the name of a real and virtual service.\n",
|
|
||||||
depinfo->service);
|
|
||||||
}
|
|
||||||
errno = serrno;
|
|
||||||
}
|
|
||||||
rc_stringlist_free(dupes);
|
|
||||||
|
|
||||||
/* Phase 7 - save to disk
|
|
||||||
Now that we're purely in C, do we need to keep a shell parseable file?
|
Now that we're purely in C, do we need to keep a shell parseable file?
|
||||||
I think yes as then it stays human readable
|
I think yes as then it stays human readable
|
||||||
This works and should be entirely shell parseable provided that depend
|
This works and should be entirely shell parseable provided that depend
|
||||||
|
|||||||
@@ -285,9 +285,6 @@ detect_container(const char *systype)
|
|||||||
return RC_SYS_RKT;
|
return RC_SYS_RKT;
|
||||||
else if (file_regex("/proc/1/environ", "container=systemd-nspawn"))
|
else if (file_regex("/proc/1/environ", "container=systemd-nspawn"))
|
||||||
return RC_SYS_SYSTEMD_NSPAWN;
|
return RC_SYS_SYSTEMD_NSPAWN;
|
||||||
else if (exists("/.dockerenv"))
|
|
||||||
return RC_SYS_DOCKER;
|
|
||||||
/* old test, I'm not sure when this was valid. */
|
|
||||||
else if (file_regex("/proc/1/environ", "container=docker"))
|
else if (file_regex("/proc/1/environ", "container=docker"))
|
||||||
return RC_SYS_DOCKER;
|
return RC_SYS_DOCKER;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
1
src/rc/.gitignore
vendored
1
src/rc/.gitignore
vendored
@@ -5,7 +5,6 @@ rc-update
|
|||||||
runscript
|
runscript
|
||||||
service
|
service
|
||||||
start-stop-daemon
|
start-stop-daemon
|
||||||
supervise-daemon
|
|
||||||
einfon
|
einfon
|
||||||
einfo
|
einfo
|
||||||
ewarnn
|
ewarnn
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ SRCS= checkpath.c do_e.c do_mark_service.c do_service.c \
|
|||||||
mountinfo.c openrc-run.c rc-abort.c rc.c \
|
mountinfo.c openrc-run.c rc-abort.c rc.c \
|
||||||
rc-depend.c rc-logger.c rc-misc.c rc-plugin.c \
|
rc-depend.c rc-logger.c rc-misc.c rc-plugin.c \
|
||||||
rc-service.c rc-status.c rc-update.c \
|
rc-service.c rc-status.c rc-update.c \
|
||||||
shell_var.c start-stop-daemon.c supervise-daemon.c swclock.c _usage.c
|
shell_var.c start-stop-daemon.c swclock.c _usage.c
|
||||||
|
|
||||||
ifeq (${MKSELINUX},yes)
|
ifeq (${MKSELINUX},yes)
|
||||||
SRCS+= rc-selinux.c
|
SRCS+= rc-selinux.c
|
||||||
@@ -16,8 +16,7 @@ SBINDIR= ${PREFIX}/sbin
|
|||||||
LINKDIR= ${LIBEXECDIR}
|
LINKDIR= ${LIBEXECDIR}
|
||||||
|
|
||||||
BINPROGS= rc-status
|
BINPROGS= rc-status
|
||||||
SBINPROGS = openrc openrc-run rc rc-service rc-update runscript service \
|
SBINPROGS = openrc openrc-run rc rc-service rc-update runscript service start-stop-daemon
|
||||||
start-stop-daemon supervise-daemon
|
|
||||||
RC_BINPROGS= einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
|
RC_BINPROGS= einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
|
||||||
eindent eoutdent esyslog eval_ecolors ewaitfile \
|
eindent eoutdent esyslog eval_ecolors ewaitfile \
|
||||||
veinfo vewarn vebegin veend vewend veindent veoutdent \
|
veinfo vewarn vebegin veend vewend veindent veoutdent \
|
||||||
@@ -75,7 +74,6 @@ install: all
|
|||||||
if test "${MKPAM}" = pam; then \
|
if test "${MKPAM}" = pam; then \
|
||||||
${INSTALL} -d ${DESTDIR}${PAMDIR}; \
|
${INSTALL} -d ${DESTDIR}${PAMDIR}; \
|
||||||
${INSTALL} -m ${PAMMODE} start-stop-daemon.pam ${DESTDIR}${PAMDIR}/start-stop-daemon; \
|
${INSTALL} -m ${PAMMODE} start-stop-daemon.pam ${DESTDIR}${PAMDIR}/start-stop-daemon; \
|
||||||
${INSTALL} -m ${PAMMODE} supervise-daemon.pam ${DESTDIR}${PAMDIR}/supervise-daemon; \
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
check test::
|
check test::
|
||||||
@@ -138,9 +136,6 @@ rc-update: rc-update.o _usage.o rc-misc.o
|
|||||||
start-stop-daemon: start-stop-daemon.o _usage.o rc-misc.o
|
start-stop-daemon: start-stop-daemon.o _usage.o rc-misc.o
|
||||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||||
|
|
||||||
supervise-daemon: supervise-daemon.o _usage.o rc-misc.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
|
service_get_value service_set_value get_options save_options: do_value.o rc-misc.o
|
||||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||||
|
|
||||||
|
|||||||
@@ -178,9 +178,6 @@ int main(int argc, char **argv)
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* fail if there is no /etc/fstab */
|
|
||||||
if (!exists("/etc/fstab"))
|
|
||||||
eerrorx("/etc/fstab does not exist");
|
|
||||||
/* Ensure that we are only quiet when explicitly told to be */
|
/* Ensure that we are only quiet when explicitly told to be */
|
||||||
unsetenv("EINFO_QUIET");
|
unsetenv("EINFO_QUIET");
|
||||||
|
|
||||||
|
|||||||
@@ -297,9 +297,6 @@ getmntfile(const char *file)
|
|||||||
struct mntent *ent = NULL;
|
struct mntent *ent = NULL;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
if (!exists("/etc/fstab"))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
fp = setmntent("/etc/fstab", "r");
|
fp = setmntent("/etc/fstab", "r");
|
||||||
while ((ent = getmntent(fp)))
|
while ((ent = getmntent(fp)))
|
||||||
if (strcmp(file, ent->mnt_dir) == 0)
|
if (strcmp(file, ent->mnt_dir) == 0)
|
||||||
|
|||||||
@@ -390,14 +390,6 @@ svc_exec(const char *arg1, const char *arg2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (exists(RC_SVCDIR "/openrc-run.sh")) {
|
if (exists(RC_SVCDIR "/openrc-run.sh")) {
|
||||||
if (arg2)
|
|
||||||
einfov("Executing: %s %s %s %s %s",
|
|
||||||
RC_SVCDIR "/openrc-run.sh", RC_SVCDIR "/openrc-run.sh",
|
|
||||||
service, arg1, arg2);
|
|
||||||
else
|
|
||||||
einfov("Executing: %s %s %s %s",
|
|
||||||
RC_SVCDIR "/openrc-run.sh", RC_SVCDIR "/openrc-run.sh",
|
|
||||||
service, arg1);
|
|
||||||
execl(RC_SVCDIR "/openrc-run.sh",
|
execl(RC_SVCDIR "/openrc-run.sh",
|
||||||
RC_SVCDIR "/openrc-run.sh",
|
RC_SVCDIR "/openrc-run.sh",
|
||||||
service, arg1, arg2, (char *) NULL);
|
service, arg1, arg2, (char *) NULL);
|
||||||
@@ -405,16 +397,6 @@ svc_exec(const char *arg1, const char *arg2)
|
|||||||
service, strerror(errno));
|
service, strerror(errno));
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
} else {
|
} else {
|
||||||
if (arg2)
|
|
||||||
einfov("Executing: %s %s %s %s %s",
|
|
||||||
RC_LIBEXECDIR "/sh/openrc-run.sh",
|
|
||||||
RC_LIBEXECDIR "/sh/openrc-run.sh",
|
|
||||||
service, arg1, arg2);
|
|
||||||
else
|
|
||||||
einfov("Executing: %s %s %s %s",
|
|
||||||
RC_LIBEXECDIR "/sh/openrc-run.sh",
|
|
||||||
RC_LIBEXECDIR "/sh/openrc-run.sh",
|
|
||||||
service, arg1);
|
|
||||||
execl(RC_LIBEXECDIR "/sh/openrc-run.sh",
|
execl(RC_LIBEXECDIR "/sh/openrc-run.sh",
|
||||||
RC_LIBEXECDIR "/sh/openrc-run.sh",
|
RC_LIBEXECDIR "/sh/openrc-run.sh",
|
||||||
service, arg1, arg2, (char *) NULL);
|
service, arg1, arg2, (char *) NULL);
|
||||||
@@ -1106,7 +1088,6 @@ service_plugable(void)
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool doneone = false;
|
bool doneone = false;
|
||||||
bool runscript = false;
|
|
||||||
int retval, opt, depoptions = RC_DEP_TRACE;
|
int retval, opt, depoptions = RC_DEP_TRACE;
|
||||||
RC_STRING *svc;
|
RC_STRING *svc;
|
||||||
char path[PATH_MAX], lnk[PATH_MAX];
|
char path[PATH_MAX], lnk[PATH_MAX];
|
||||||
@@ -1122,10 +1103,6 @@ int main(int argc, char **argv)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
applet = basename_c(argv[0]);
|
|
||||||
if (strcmp(applet, "runscript") == 0)
|
|
||||||
runscript = true;
|
|
||||||
|
|
||||||
if (stat(argv[1], &stbuf) != 0) {
|
if (stat(argv[1], &stbuf) != 0) {
|
||||||
fprintf(stderr, "openrc-run `%s': %s\n",
|
fprintf(stderr, "openrc-run `%s': %s\n",
|
||||||
argv[1], strerror(errno));
|
argv[1], strerror(errno));
|
||||||
@@ -1292,9 +1269,6 @@ int main(int argc, char **argv)
|
|||||||
applet_list = rc_stringlist_new();
|
applet_list = rc_stringlist_new();
|
||||||
rc_stringlist_add(applet_list, applet);
|
rc_stringlist_add(applet_list, applet);
|
||||||
|
|
||||||
if (runscript)
|
|
||||||
ewarn("%s uses runscript, please convert to openrc-run.", service);
|
|
||||||
|
|
||||||
/* Now run each option */
|
/* Now run each option */
|
||||||
retval = EXIT_SUCCESS;
|
retval = EXIT_SUCCESS;
|
||||||
while (optind < argc) {
|
while (optind < argc) {
|
||||||
|
|||||||
@@ -247,10 +247,6 @@ rc_logger_open(const char *level)
|
|||||||
logfile = rc_conf_value("rc_log_path");
|
logfile = rc_conf_value("rc_log_path");
|
||||||
if (logfile == NULL)
|
if (logfile == NULL)
|
||||||
logfile = DEFAULTLOG;
|
logfile = DEFAULTLOG;
|
||||||
if (!strcmp(logfile, TMPLOG)) {
|
|
||||||
eerror("Cowardly refusing to concatenate a logfile into itself.");
|
|
||||||
eerrorx("Please change rc_log_path to something other than %s to get rid of this message", TMPLOG);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((plog = fopen(logfile, "ae"))) {
|
if ((plog = fopen(logfile, "ae"))) {
|
||||||
if ((log = fopen(TMPLOG, "re"))) {
|
if ((log = fopen(TMPLOG, "re"))) {
|
||||||
|
|||||||
@@ -68,12 +68,6 @@ env_filter(void)
|
|||||||
|
|
||||||
/* Add the user defined list of vars */
|
/* Add the user defined list of vars */
|
||||||
env_allow = rc_stringlist_split(rc_conf_value("rc_env_allow"), " ");
|
env_allow = rc_stringlist_split(rc_conf_value("rc_env_allow"), " ");
|
||||||
/*
|
|
||||||
* If '*' is an entry in rc_env_allow, do nothing as we are to pass
|
|
||||||
* through all environment variables.
|
|
||||||
*/
|
|
||||||
if (rc_stringlist_find(env_allow, "*"))
|
|
||||||
return;
|
|
||||||
profile = rc_config_load(RC_PROFILE_ENV);
|
profile = rc_config_load(RC_PROFILE_ENV);
|
||||||
|
|
||||||
/* Copy the env and work from this so we can manipulate it safely */
|
/* Copy the env and work from this so we can manipulate it safely */
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ void selinux_setup(char **argv)
|
|||||||
* which will open the pty with initrc_devpts_t, if it doesnt exist,
|
* which will open the pty with initrc_devpts_t, if it doesnt exist,
|
||||||
* fall back to plain exec
|
* fall back to plain exec
|
||||||
*/
|
*/
|
||||||
if (!access("/usr/sbin/open_init_pty", X_OK)) {
|
if (access("/usr/sbin/open_init_pty", X_OK)) {
|
||||||
if (execvp("/usr/sbin/open_init_pty", argv)) {
|
if (execvp("/usr/sbin/open_init_pty", argv)) {
|
||||||
perror("execvp");
|
perror("execvp");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ void selinux_setup(char **argv);
|
|||||||
|
|
||||||
/* always return false for selinux_util_open() */
|
/* always return false for selinux_util_open() */
|
||||||
#define selinux_util_open() (0)
|
#define selinux_util_open() (0)
|
||||||
#define selinux_util_label(x) do { } while (0)
|
#define selinux_util_label(x) do { } while(0)
|
||||||
#define selinux_util_close() do { } while (0)
|
#define selinux_util_close() do { } while(0)
|
||||||
|
|
||||||
#define selinux_setup(x) do { } while (0)
|
#define selinux_setup(x) do { } while(0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -29,12 +29,10 @@
|
|||||||
|
|
||||||
const char *applet = NULL;
|
const char *applet = NULL;
|
||||||
const char *extraopts = NULL;
|
const char *extraopts = NULL;
|
||||||
const char *getoptstring = "e:ilr:IN" getoptstring_COMMON;
|
const char *getoptstring = "e:ilr:" getoptstring_COMMON;
|
||||||
const struct option longopts[] = {
|
const struct option longopts[] = {
|
||||||
{ "exists", 1, NULL, 'e' },
|
{ "exists", 1, NULL, 'e' },
|
||||||
{ "ifexists", 0, NULL, 'i' },
|
{ "ifexists", 0, NULL, 'i' },
|
||||||
{ "ifinactive", 0, NULL, 'I' },
|
|
||||||
{ "ifnotstarted", 0, NULL, 'N' },
|
|
||||||
{ "list", 0, NULL, 'l' },
|
{ "list", 0, NULL, 'l' },
|
||||||
{ "resolve", 1, NULL, 'r' },
|
{ "resolve", 1, NULL, 'r' },
|
||||||
longopts_COMMON
|
longopts_COMMON
|
||||||
@@ -42,8 +40,6 @@ const struct option longopts[] = {
|
|||||||
const char * const longopts_help[] = {
|
const char * const longopts_help[] = {
|
||||||
"tests if the service exists or not",
|
"tests if the service exists or not",
|
||||||
"if the service exists then run the command",
|
"if the service exists then run the command",
|
||||||
"if the service is inactive then run the command",
|
|
||||||
"if the service is not started then run the command",
|
|
||||||
"list all available services",
|
"list all available services",
|
||||||
"resolve the service name to an init script",
|
"resolve the service name to an init script",
|
||||||
longopts_help_COMMON
|
longopts_help_COMMON
|
||||||
@@ -60,10 +56,7 @@ int main(int argc, char **argv)
|
|||||||
char *service;
|
char *service;
|
||||||
RC_STRINGLIST *list;
|
RC_STRINGLIST *list;
|
||||||
RC_STRING *s;
|
RC_STRING *s;
|
||||||
RC_SERVICE state;
|
|
||||||
bool if_exists = false;
|
bool if_exists = false;
|
||||||
bool if_inactive = false;
|
|
||||||
bool if_notstarted = false;
|
|
||||||
|
|
||||||
applet = basename_c(argv[0]);
|
applet = basename_c(argv[0]);
|
||||||
/* Ensure that we are only quiet when explicitly told to be */
|
/* Ensure that we are only quiet when explicitly told to be */
|
||||||
@@ -84,12 +77,6 @@ int main(int argc, char **argv)
|
|||||||
case 'i':
|
case 'i':
|
||||||
if_exists = true;
|
if_exists = true;
|
||||||
break;
|
break;
|
||||||
case 'I':
|
|
||||||
if_inactive = true;
|
|
||||||
break;
|
|
||||||
case 'N':
|
|
||||||
if_notstarted = true;
|
|
||||||
break;
|
|
||||||
case 'l':
|
case 'l':
|
||||||
list = rc_services_in_runlevel(NULL);
|
list = rc_services_in_runlevel(NULL);
|
||||||
if (TAILQ_FIRST(list) == NULL)
|
if (TAILQ_FIRST(list) == NULL)
|
||||||
@@ -126,11 +113,6 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
eerrorx("%s: service `%s' does not exist", applet, *argv);
|
eerrorx("%s: service `%s' does not exist", applet, *argv);
|
||||||
}
|
}
|
||||||
state = rc_service_state(*argv);
|
|
||||||
if (if_inactive && ! (state & RC_SERVICE_INACTIVE))
|
|
||||||
return 0;
|
|
||||||
if (if_notstarted && (state & RC_SERVICE_STARTED))
|
|
||||||
return 0;
|
|
||||||
*argv = service;
|
*argv = service;
|
||||||
execv(*argv, argv);
|
execv(*argv, argv);
|
||||||
eerrorx("%s: %s", applet, strerror(errno));
|
eerrorx("%s: %s", applet, strerror(errno));
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ open_shell(void)
|
|||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
const char *sys = rc_sys();
|
const char *sys = rc_sys();
|
||||||
|
|
||||||
/* VSERVER systems cannot really drop to shells */
|
/* VSERVER systems cannot really drop to shells */
|
||||||
if (sys && strcmp(sys, RC_SYS_VSERVER) == 0)
|
if (sys && strcmp(sys, RC_SYS_VSERVER) == 0)
|
||||||
{
|
{
|
||||||
@@ -830,8 +830,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(applet, "rc") == 0)
|
|
||||||
ewarn("rc is deprecated, please use openrc instead.");
|
|
||||||
newlevel = argv[optind++];
|
newlevel = argv[optind++];
|
||||||
/* To make life easier, we only have the shutdown runlevel as
|
/* To make life easier, we only have the shutdown runlevel as
|
||||||
* nothing really needs to know that we're rebooting.
|
* nothing really needs to know that we're rebooting.
|
||||||
|
|||||||
@@ -1242,7 +1242,7 @@ int main(int argc, char **argv)
|
|||||||
if (redirect_stdout) {
|
if (redirect_stdout) {
|
||||||
if ((stdout_fd = open(redirect_stdout,
|
if ((stdout_fd = open(redirect_stdout,
|
||||||
O_WRONLY | O_CREAT | O_APPEND,
|
O_WRONLY | O_CREAT | O_APPEND,
|
||||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1)
|
S_IRUSR | S_IWUSR)) == -1)
|
||||||
eerrorx("%s: unable to open the logfile"
|
eerrorx("%s: unable to open the logfile"
|
||||||
" for stdout `%s': %s",
|
" for stdout `%s': %s",
|
||||||
applet, redirect_stdout, strerror(errno));
|
applet, redirect_stdout, strerror(errno));
|
||||||
@@ -1250,7 +1250,7 @@ int main(int argc, char **argv)
|
|||||||
if (redirect_stderr) {
|
if (redirect_stderr) {
|
||||||
if ((stderr_fd = open(redirect_stderr,
|
if ((stderr_fd = open(redirect_stderr,
|
||||||
O_WRONLY | O_CREAT | O_APPEND,
|
O_WRONLY | O_CREAT | O_APPEND,
|
||||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1)
|
S_IRUSR | S_IWUSR)) == -1)
|
||||||
eerrorx("%s: unable to open the logfile"
|
eerrorx("%s: unable to open the logfile"
|
||||||
" for stderr `%s': %s",
|
" for stderr `%s': %s",
|
||||||
applet, redirect_stderr, strerror(errno));
|
applet, redirect_stderr, strerror(errno));
|
||||||
|
|||||||
@@ -1,726 +0,0 @@
|
|||||||
/*
|
|
||||||
* supervise-daemon
|
|
||||||
* This is an experimental supervisor for daemons.
|
|
||||||
* It will start a deamon and make sure it restarts if it crashes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2016 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 <sys/types.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
#include <sys/syscall.h> /* For io priority */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <grp.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_PAM
|
|
||||||
#include <security/pam_appl.h>
|
|
||||||
|
|
||||||
/* We are not supporting authentication conversations */
|
|
||||||
static struct pam_conv conv = { NULL, NULL};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "einfo.h"
|
|
||||||
#include "queue.h"
|
|
||||||
#include "rc.h"
|
|
||||||
#include "rc-misc.h"
|
|
||||||
#include "_usage.h"
|
|
||||||
|
|
||||||
const char *applet = NULL;
|
|
||||||
const char *extraopts = NULL;
|
|
||||||
const char *getoptstring = "d:e:g:I:Kk:N:p:r:Su:1:2:" \
|
|
||||||
getoptstring_COMMON;
|
|
||||||
const struct option longopts[] = {
|
|
||||||
{ "chdir", 1, NULL, 'd'},
|
|
||||||
{ "env", 1, NULL, 'e'},
|
|
||||||
{ "group", 1, NULL, 'g'},
|
|
||||||
{ "ionice", 1, NULL, 'I'},
|
|
||||||
{ "stop", 0, NULL, 'K'},
|
|
||||||
{ "umask", 1, NULL, 'k'},
|
|
||||||
{ "nicelevel", 1, NULL, 'N'},
|
|
||||||
{ "pidfile", 1, NULL, 'p'},
|
|
||||||
{ "user", 1, NULL, 'u'},
|
|
||||||
{ "chroot", 1, NULL, 'r'},
|
|
||||||
{ "start", 0, NULL, 'S'},
|
|
||||||
{ "stdout", 1, NULL, '1'},
|
|
||||||
{ "stderr", 1, NULL, '2'},
|
|
||||||
longopts_COMMON
|
|
||||||
};
|
|
||||||
const char * const longopts_help[] = {
|
|
||||||
"Change the PWD",
|
|
||||||
"Set an environment string",
|
|
||||||
"Change the process group",
|
|
||||||
"Set an ionice class:data when starting",
|
|
||||||
"Stop daemon",
|
|
||||||
"Set the umask for the daemon",
|
|
||||||
"Set a nicelevel when starting",
|
|
||||||
"Match pid found in this file",
|
|
||||||
"Change the process user",
|
|
||||||
"Chroot to this directory",
|
|
||||||
"Start daemon",
|
|
||||||
"Redirect stdout to file",
|
|
||||||
"Redirect stderr to file",
|
|
||||||
longopts_help_COMMON
|
|
||||||
};
|
|
||||||
const char *usagestring = NULL;
|
|
||||||
|
|
||||||
static int nicelevel = 0;
|
|
||||||
static int ionicec = -1;
|
|
||||||
static int ioniced = 0;
|
|
||||||
static char *changeuser, *ch_root, *ch_dir;
|
|
||||||
static uid_t uid = 0;
|
|
||||||
static gid_t gid = 0;
|
|
||||||
static int devnull_fd = -1;
|
|
||||||
static int stdin_fd;
|
|
||||||
static int stdout_fd;
|
|
||||||
static int stderr_fd;
|
|
||||||
static char *redirect_stderr = NULL;
|
|
||||||
static char *redirect_stdout = NULL;
|
|
||||||
static bool exiting = false;
|
|
||||||
#ifdef TIOCNOTTY
|
|
||||||
static int tty_fd = -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern char **environ;
|
|
||||||
|
|
||||||
#if !defined(SYS_ioprio_set) && defined(__NR_ioprio_set)
|
|
||||||
# define SYS_ioprio_set __NR_ioprio_set
|
|
||||||
#endif
|
|
||||||
#if !defined(__DragonFly__)
|
|
||||||
static inline int ioprio_set(int which, int who, int ioprio)
|
|
||||||
{
|
|
||||||
#ifdef SYS_ioprio_set
|
|
||||||
return syscall(SYS_ioprio_set, which, who, ioprio);
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
RC_STRINGLIST *env_list;
|
|
||||||
RC_STRING *env;
|
|
||||||
int i;
|
|
||||||
char *p;
|
|
||||||
char *token;
|
|
||||||
size_t len;
|
|
||||||
char *newpath;
|
|
||||||
char *np;
|
|
||||||
char **c;
|
|
||||||
char cmdline[PATH_MAX];
|
|
||||||
|
|
||||||
#ifdef HAVE_PAM
|
|
||||||
pam_handle_t *pamh = NULL;
|
|
||||||
int pamr;
|
|
||||||
const char *const *pamenv = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
setsid();
|
|
||||||
|
|
||||||
if (nicelevel) {
|
|
||||||
if (setpriority(PRIO_PROCESS, getpid(), nicelevel) == -1)
|
|
||||||
eerrorx("%s: setpriority %d: %s", applet, nicelevel,
|
|
||||||
strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ionicec != -1 && ioprio_set(1, getpid(), ionicec | ioniced) == -1)
|
|
||||||
eerrorx("%s: ioprio_set %d %d: %s", applet, ionicec, ioniced,
|
|
||||||
strerror(errno));
|
|
||||||
|
|
||||||
if (ch_root && chroot(ch_root) < 0)
|
|
||||||
eerrorx("%s: chroot `%s': %s", applet, ch_root, strerror(errno));
|
|
||||||
|
|
||||||
if (ch_dir && chdir(ch_dir) < 0)
|
|
||||||
eerrorx("%s: chdir `%s': %s", applet, ch_dir, strerror(errno));
|
|
||||||
|
|
||||||
#ifdef HAVE_PAM
|
|
||||||
if (changeuser != NULL) {
|
|
||||||
pamr = pam_start("supervise-daemon",
|
|
||||||
changeuser, &conv, &pamh);
|
|
||||||
|
|
||||||
if (pamr == PAM_SUCCESS)
|
|
||||||
pamr = pam_acct_mgmt(pamh, PAM_SILENT);
|
|
||||||
if (pamr == PAM_SUCCESS)
|
|
||||||
pamr = pam_open_session(pamh, PAM_SILENT);
|
|
||||||
if (pamr != PAM_SUCCESS)
|
|
||||||
eerrorx("%s: pam error: %s", applet, pam_strerror(pamh, pamr));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (gid && setgid(gid))
|
|
||||||
eerrorx("%s: unable to set groupid to %d", applet, gid);
|
|
||||||
if (changeuser && initgroups(changeuser, gid))
|
|
||||||
eerrorx("%s: initgroups (%s, %d)", applet, changeuser, gid);
|
|
||||||
if (uid && setuid(uid))
|
|
||||||
eerrorx ("%s: unable to set userid to %d", applet, uid);
|
|
||||||
|
|
||||||
/* Close any fd's to the passwd database */
|
|
||||||
endpwent();
|
|
||||||
|
|
||||||
#ifdef TIOCNOTTY
|
|
||||||
ioctl(tty_fd, TIOCNOTTY, 0);
|
|
||||||
close(tty_fd);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Clean the environment of any RC_ variables */
|
|
||||||
env_list = rc_stringlist_new();
|
|
||||||
i = 0;
|
|
||||||
while (environ[i])
|
|
||||||
rc_stringlist_add(env_list, environ[i++]);
|
|
||||||
|
|
||||||
#ifdef HAVE_PAM
|
|
||||||
if (changeuser != NULL) {
|
|
||||||
pamenv = (const char *const *)pam_getenvlist(pamh);
|
|
||||||
if (pamenv) {
|
|
||||||
while (*pamenv) {
|
|
||||||
/* Don't add strings unless they set a var */
|
|
||||||
if (strchr(*pamenv, '='))
|
|
||||||
putenv(xstrdup(*pamenv));
|
|
||||||
else
|
|
||||||
unsetenv(*pamenv);
|
|
||||||
pamenv++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TAILQ_FOREACH(env, env_list, entries) {
|
|
||||||
if ((strncmp(env->value, "RC_", 3) == 0 &&
|
|
||||||
strncmp(env->value, "RC_SERVICE=", 10) != 0 &&
|
|
||||||
strncmp(env->value, "RC_SVCNAME=", 10) != 0) ||
|
|
||||||
strncmp(env->value, "SSD_NICELEVEL=", 14) == 0)
|
|
||||||
{
|
|
||||||
p = strchr(env->value, '=');
|
|
||||||
*p = '\0';
|
|
||||||
unsetenv(env->value);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rc_stringlist_free(env_list);
|
|
||||||
|
|
||||||
/* For the path, remove the rcscript bin dir from it */
|
|
||||||
if ((token = getenv("PATH"))) {
|
|
||||||
len = strlen(token);
|
|
||||||
newpath = np = xmalloc(len + 1);
|
|
||||||
while (token && *token) {
|
|
||||||
p = strchr(token, ':');
|
|
||||||
if (p) {
|
|
||||||
*p++ = '\0';
|
|
||||||
while (*p == ':')
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
if (strcmp(token, RC_LIBEXECDIR "/bin") != 0 &&
|
|
||||||
strcmp(token, RC_LIBEXECDIR "/sbin") != 0)
|
|
||||||
{
|
|
||||||
len = strlen(token);
|
|
||||||
if (np != newpath)
|
|
||||||
*np++ = ':';
|
|
||||||
memcpy(np, token, len);
|
|
||||||
np += len;
|
|
||||||
}
|
|
||||||
token = p;
|
|
||||||
}
|
|
||||||
*np = '\0';
|
|
||||||
unsetenv("PATH");
|
|
||||||
setenv("PATH", newpath, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
stdin_fd = devnull_fd;
|
|
||||||
stdout_fd = devnull_fd;
|
|
||||||
stderr_fd = devnull_fd;
|
|
||||||
if (redirect_stdout) {
|
|
||||||
if ((stdout_fd = open(redirect_stdout,
|
|
||||||
O_WRONLY | O_CREAT | O_APPEND,
|
|
||||||
S_IRUSR | S_IWUSR)) == -1)
|
|
||||||
eerrorx("%s: unable to open the logfile"
|
|
||||||
" for stdout `%s': %s",
|
|
||||||
applet, redirect_stdout, strerror(errno));
|
|
||||||
}
|
|
||||||
if (redirect_stderr) {
|
|
||||||
if ((stderr_fd = open(redirect_stderr,
|
|
||||||
O_WRONLY | O_CREAT | O_APPEND,
|
|
||||||
S_IRUSR | S_IWUSR)) == -1)
|
|
||||||
eerrorx("%s: unable to open the logfile"
|
|
||||||
" for stderr `%s': %s",
|
|
||||||
applet, redirect_stderr, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
dup2(stdin_fd, STDIN_FILENO);
|
|
||||||
if (redirect_stdout || rc_yesno(getenv("EINFO_QUIET")))
|
|
||||||
dup2(stdout_fd, STDOUT_FILENO);
|
|
||||||
if (redirect_stderr || rc_yesno(getenv("EINFO_QUIET")))
|
|
||||||
dup2(stderr_fd, STDERR_FILENO);
|
|
||||||
|
|
||||||
for (i = getdtablesize() - 1; i >= 3; --i)
|
|
||||||
close(i);
|
|
||||||
|
|
||||||
*cmdline = '\0';
|
|
||||||
c = argv;
|
|
||||||
while (*c) {
|
|
||||||
strcat(cmdline, *c);
|
|
||||||
strcat(cmdline, " ");
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
syslog(LOG_INFO, "Running command line: %s", cmdline);
|
|
||||||
execvp(exec, argv);
|
|
||||||
|
|
||||||
#ifdef HAVE_PAM
|
|
||||||
if (changeuser != NULL && pamr == PAM_SUCCESS)
|
|
||||||
pam_close_session(pamh, PAM_SILENT);
|
|
||||||
#endif
|
|
||||||
eerrorx("%s: failed to exec `%s': %s", applet, exec,strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_signal(int sig)
|
|
||||||
{
|
|
||||||
int serrno = errno;
|
|
||||||
char signame[10] = { '\0' };
|
|
||||||
|
|
||||||
switch (sig) {
|
|
||||||
case SIGINT:
|
|
||||||
snprintf(signame, sizeof(signame), "SIGINT");
|
|
||||||
break;
|
|
||||||
case SIGTERM:
|
|
||||||
snprintf(signame, sizeof(signame), "SIGTERM");
|
|
||||||
break;
|
|
||||||
case SIGQUIT:
|
|
||||||
snprintf(signame, sizeof(signame), "SIGQUIT");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*signame != 0) {
|
|
||||||
syslog(LOG_INFO, "%s: caught signal %s, exiting", applet, signame);
|
|
||||||
exiting = true;
|
|
||||||
} else
|
|
||||||
syslog(LOG_INFO, "%s: caught unknown signal %d", applet, sig);
|
|
||||||
|
|
||||||
/* Restore errno */
|
|
||||||
errno = serrno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char * expand_home(const char *home, const char *path)
|
|
||||||
{
|
|
||||||
char *opath, *ppath, *p, *nh;
|
|
||||||
size_t len;
|
|
||||||
struct passwd *pw;
|
|
||||||
|
|
||||||
if (!path || *path != '~')
|
|
||||||
return xstrdup(path);
|
|
||||||
|
|
||||||
opath = ppath = xstrdup(path);
|
|
||||||
if (ppath[1] != '/' && ppath[1] != '\0') {
|
|
||||||
p = strchr(ppath + 1, '/');
|
|
||||||
if (p)
|
|
||||||
*p = '\0';
|
|
||||||
pw = getpwnam(ppath + 1);
|
|
||||||
if (pw) {
|
|
||||||
home = pw->pw_dir;
|
|
||||||
ppath = p;
|
|
||||||
if (ppath)
|
|
||||||
*ppath = '/';
|
|
||||||
} else
|
|
||||||
home = NULL;
|
|
||||||
} else
|
|
||||||
ppath++;
|
|
||||||
|
|
||||||
if (!home) {
|
|
||||||
free(opath);
|
|
||||||
return xstrdup(path);
|
|
||||||
}
|
|
||||||
if (!ppath) {
|
|
||||||
free(opath);
|
|
||||||
return xstrdup(home);
|
|
||||||
}
|
|
||||||
|
|
||||||
len = strlen(ppath) + strlen(home) + 1;
|
|
||||||
nh = xmalloc(len);
|
|
||||||
snprintf(nh, len, "%s%s", home, ppath);
|
|
||||||
free(opath);
|
|
||||||
return nh;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int opt;
|
|
||||||
bool start = false;
|
|
||||||
bool stop = false;
|
|
||||||
char *exec = NULL;
|
|
||||||
char *pidfile = NULL;
|
|
||||||
char *home = NULL;
|
|
||||||
int tid = 0;
|
|
||||||
pid_t child_pid, pid;
|
|
||||||
char *svcname = getenv("RC_SVCNAME");
|
|
||||||
char *tmp;
|
|
||||||
char *p;
|
|
||||||
char *token;
|
|
||||||
int i;
|
|
||||||
char exec_file[PATH_MAX];
|
|
||||||
struct passwd *pw;
|
|
||||||
struct group *gr;
|
|
||||||
FILE *fp;
|
|
||||||
mode_t numask = 022;
|
|
||||||
|
|
||||||
applet = basename_c(argv[0]);
|
|
||||||
atexit(cleanup);
|
|
||||||
|
|
||||||
signal_setup(SIGINT, handle_signal);
|
|
||||||
signal_setup(SIGQUIT, handle_signal);
|
|
||||||
signal_setup(SIGTERM, handle_signal);
|
|
||||||
openlog(applet, LOG_PID, LOG_DAEMON);
|
|
||||||
|
|
||||||
if ((tmp = getenv("SSD_NICELEVEL")))
|
|
||||||
if (sscanf(tmp, "%d", &nicelevel) != 1)
|
|
||||||
eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)",
|
|
||||||
applet, tmp);
|
|
||||||
|
|
||||||
/* Get our user name and initial dir */
|
|
||||||
p = getenv("USER");
|
|
||||||
home = getenv("HOME");
|
|
||||||
if (home == NULL || p == NULL) {
|
|
||||||
pw = getpwuid(getuid());
|
|
||||||
if (pw != NULL) {
|
|
||||||
if (p == NULL)
|
|
||||||
setenv("USER", pw->pw_name, 1);
|
|
||||||
if (home == NULL) {
|
|
||||||
setenv("HOME", pw->pw_dir, 1);
|
|
||||||
home = pw->pw_dir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, getoptstring, longopts,
|
|
||||||
(int *) 0)) != -1)
|
|
||||||
switch (opt) {
|
|
||||||
case 'I': /* --ionice */
|
|
||||||
if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0)
|
|
||||||
eerrorx("%s: invalid ionice `%s'",
|
|
||||||
applet, optarg);
|
|
||||||
if (ionicec == 0)
|
|
||||||
ioniced = 0;
|
|
||||||
else if (ionicec == 3)
|
|
||||||
ioniced = 7;
|
|
||||||
ionicec <<= 13; /* class shift */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'K': /* --stop */
|
|
||||||
stop = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'N': /* --nice */
|
|
||||||
if (sscanf(optarg, "%d", &nicelevel) != 1)
|
|
||||||
eerrorx("%s: invalid nice level `%s'",
|
|
||||||
applet, optarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'S': /* --start */
|
|
||||||
start = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'd': /* --chdir /new/dir */
|
|
||||||
ch_dir = optarg;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'e': /* --env */
|
|
||||||
putenv(optarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'g': /* --group <group>|<gid> */
|
|
||||||
if (sscanf(optarg, "%d", &tid) != 1)
|
|
||||||
gr = getgrnam(optarg);
|
|
||||||
else
|
|
||||||
gr = getgrgid((gid_t)tid);
|
|
||||||
if (gr == NULL)
|
|
||||||
eerrorx("%s: group `%s' not found",
|
|
||||||
applet, optarg);
|
|
||||||
gid = gr->gr_gid;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'k':
|
|
||||||
if (parse_mode(&numask, optarg))
|
|
||||||
eerrorx("%s: invalid mode `%s'",
|
|
||||||
applet, optarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'p': /* --pidfile <pid-file> */
|
|
||||||
pidfile = optarg;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'r': /* --chroot /new/root */
|
|
||||||
ch_root = optarg;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'u': /* --user <username>|<uid> */
|
|
||||||
{
|
|
||||||
p = optarg;
|
|
||||||
tmp = strsep(&p, ":");
|
|
||||||
changeuser = xstrdup(tmp);
|
|
||||||
if (sscanf(tmp, "%d", &tid) != 1)
|
|
||||||
pw = getpwnam(tmp);
|
|
||||||
else
|
|
||||||
pw = getpwuid((uid_t)tid);
|
|
||||||
|
|
||||||
if (pw == NULL)
|
|
||||||
eerrorx("%s: user `%s' not found",
|
|
||||||
applet, tmp);
|
|
||||||
uid = pw->pw_uid;
|
|
||||||
home = pw->pw_dir;
|
|
||||||
unsetenv("HOME");
|
|
||||||
if (pw->pw_dir)
|
|
||||||
setenv("HOME", pw->pw_dir, 1);
|
|
||||||
unsetenv("USER");
|
|
||||||
if (pw->pw_name)
|
|
||||||
setenv("USER", pw->pw_name, 1);
|
|
||||||
if (gid == 0)
|
|
||||||
gid = pw->pw_gid;
|
|
||||||
|
|
||||||
if (p) {
|
|
||||||
tmp = strsep (&p, ":");
|
|
||||||
if (sscanf(tmp, "%d", &tid) != 1)
|
|
||||||
gr = getgrnam(tmp);
|
|
||||||
else
|
|
||||||
gr = getgrgid((gid_t) tid);
|
|
||||||
|
|
||||||
if (gr == NULL)
|
|
||||||
eerrorx("%s: group `%s'"
|
|
||||||
" not found",
|
|
||||||
applet, tmp);
|
|
||||||
gid = gr->gr_gid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '1': /* --stdout /path/to/stdout.lgfile */
|
|
||||||
redirect_stdout = optarg;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '2': /* --stderr /path/to/stderr.logfile */
|
|
||||||
redirect_stderr = optarg;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case_RC_COMMON_GETOPT
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pidfile)
|
|
||||||
eerrorx("%s: --pidfile must be specified", applet);
|
|
||||||
|
|
||||||
endpwent();
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
exec = *argv;
|
|
||||||
|
|
||||||
if (start) {
|
|
||||||
if (!exec)
|
|
||||||
eerrorx("%s: nothing to start", applet);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expand ~ */
|
|
||||||
if (ch_dir && *ch_dir == '~')
|
|
||||||
ch_dir = expand_home(home, ch_dir);
|
|
||||||
if (ch_root && *ch_root == '~')
|
|
||||||
ch_root = expand_home(home, ch_root);
|
|
||||||
if (exec) {
|
|
||||||
if (*exec == '~')
|
|
||||||
exec = expand_home(home, exec);
|
|
||||||
|
|
||||||
/* Validate that the binary exists if we are starting */
|
|
||||||
if (*exec == '/' || *exec == '.') {
|
|
||||||
/* Full or relative path */
|
|
||||||
if (ch_root)
|
|
||||||
snprintf(exec_file, sizeof(exec_file),
|
|
||||||
"%s/%s", ch_root, exec);
|
|
||||||
else
|
|
||||||
snprintf(exec_file, sizeof(exec_file),
|
|
||||||
"%s", exec);
|
|
||||||
} else {
|
|
||||||
/* Something in $PATH */
|
|
||||||
p = tmp = xstrdup(getenv("PATH"));
|
|
||||||
*exec_file = '\0';
|
|
||||||
while ((token = strsep(&p, ":"))) {
|
|
||||||
if (ch_root)
|
|
||||||
snprintf(exec_file, sizeof(exec_file),
|
|
||||||
"%s/%s/%s",
|
|
||||||
ch_root, token, exec);
|
|
||||||
else
|
|
||||||
snprintf(exec_file, sizeof(exec_file),
|
|
||||||
"%s/%s", token, exec);
|
|
||||||
if (exists(exec_file))
|
|
||||||
break;
|
|
||||||
*exec_file = '\0';
|
|
||||||
}
|
|
||||||
free(tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (start && !exists(exec_file))
|
|
||||||
eerrorx("%s: %s does not exist", applet,
|
|
||||||
*exec_file ? exec_file : exec);
|
|
||||||
|
|
||||||
if (stop) {
|
|
||||||
pid = get_pid(pidfile);
|
|
||||||
if (pid == -1)
|
|
||||||
i = pid;
|
|
||||||
else
|
|
||||||
i = kill(pid, SIGTERM);
|
|
||||||
if (i != 0)
|
|
||||||
/* We failed to stop something */
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
* result would be the same. */
|
|
||||||
if (pidfile && exists(pidfile))
|
|
||||||
unlink(pidfile);
|
|
||||||
if (svcname)
|
|
||||||
rc_service_daemon_set(svcname, exec,
|
|
||||||
(const char *const *)argv,
|
|
||||||
pidfile, false);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
pid = get_pid(pidfile);
|
|
||||||
if (pid != -1)
|
|
||||||
if (kill(pid, 0) == 0)
|
|
||||||
eerrorx("%s: %s is already running", applet, exec);
|
|
||||||
|
|
||||||
einfov("Detaching to start `%s'", exec);
|
|
||||||
eindentv();
|
|
||||||
|
|
||||||
/* Remove existing pidfile */
|
|
||||||
if (pidfile)
|
|
||||||
unlink(pidfile);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure we can write a pid file
|
|
||||||
*/
|
|
||||||
fp = fopen(pidfile, "w");
|
|
||||||
if (! fp)
|
|
||||||
eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
child_pid = fork();
|
|
||||||
if (child_pid == -1)
|
|
||||||
eerrorx("%s: fork: %s", applet, strerror(errno));
|
|
||||||
|
|
||||||
/* first parent process, do nothing. */
|
|
||||||
if (child_pid != 0)
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
|
|
||||||
child_pid = fork();
|
|
||||||
if (child_pid == -1)
|
|
||||||
eerrorx("%s: fork: %s", applet, strerror(errno));
|
|
||||||
|
|
||||||
if (child_pid != 0) {
|
|
||||||
/* this is the supervisor */
|
|
||||||
umask(numask);
|
|
||||||
|
|
||||||
#ifdef TIOCNOTTY
|
|
||||||
tty_fd = open("/dev/tty", O_RDWR);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
devnull_fd = open("/dev/null", O_RDWR);
|
|
||||||
|
|
||||||
fp = fopen(pidfile, "w");
|
|
||||||
if (! fp)
|
|
||||||
eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
|
|
||||||
fprintf(fp, "%d\n", getpid());
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Supervisor main loop
|
|
||||||
*/
|
|
||||||
i = 0;
|
|
||||||
while (!exiting) {
|
|
||||||
wait(&i);
|
|
||||||
if (exiting) {
|
|
||||||
syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
|
|
||||||
kill(child_pid, SIGTERM);
|
|
||||||
} else {
|
|
||||||
if (WIFEXITED(i))
|
|
||||||
syslog(LOG_INFO, "%s, pid %d, exited with return code %d",
|
|
||||||
exec, child_pid, WEXITSTATUS(i));
|
|
||||||
else if (WIFSIGNALED(i))
|
|
||||||
syslog(LOG_INFO, "%s, pid %d, terminated by signal %d",
|
|
||||||
exec, child_pid, WTERMSIG(i));
|
|
||||||
child_pid = fork();
|
|
||||||
if (child_pid == -1)
|
|
||||||
eerrorx("%s: fork: %s", applet, strerror(errno));
|
|
||||||
if (child_pid == 0)
|
|
||||||
child_process(exec, argv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (svcname)
|
|
||||||
rc_service_daemon_set(svcname, exec,
|
|
||||||
(const char * const *) argv, pidfile, true);
|
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
} else if (child_pid == 0)
|
|
||||||
child_process(exec, argv);
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#%PAM-1.0
|
|
||||||
|
|
||||||
auth required pam_permit.so
|
|
||||||
account required pam_permit.so
|
|
||||||
password required pam_deny.so
|
|
||||||
session optional pam_limits.so
|
|
||||||
@@ -85,14 +85,12 @@ eend $? "Trailing newlines need to be deleted:"$'\n'"${out}"
|
|||||||
|
|
||||||
ebegin "Checking for obsolete functions"
|
ebegin "Checking for obsolete functions"
|
||||||
out=$(cd ${top_srcdir}; find src -name '*.[ch]' \
|
out=$(cd ${top_srcdir}; find src -name '*.[ch]' \
|
||||||
! -name queue.h \
|
|
||||||
-exec grep -n -E '\<(malloc|memory|sys/(errno|fcntl|signal|stropts|termios|unistd))\.h\>' {} +)
|
-exec grep -n -E '\<(malloc|memory|sys/(errno|fcntl|signal|stropts|termios|unistd))\.h\>' {} +)
|
||||||
[ -z "${out}" ]
|
[ -z "${out}" ]
|
||||||
eend $? "Avoid these obsolete functions:"$'\n'"${out}"
|
eend $? "Avoid these obsolete functions:"$'\n'"${out}"
|
||||||
|
|
||||||
ebegin "Checking for x* func usage"
|
ebegin "Checking for x* func usage"
|
||||||
out=$(cd ${top_srcdir}; find src -name '*.[ch]' \
|
out=$(cd ${top_srcdir}; find src -name '*.[ch]' \
|
||||||
! -name queue.h \
|
|
||||||
-exec grep -n -E '\<(malloc|strdup)[[:space:]]*\(' {} + \
|
-exec grep -n -E '\<(malloc|strdup)[[:space:]]*\(' {} + \
|
||||||
| grep -v \
|
| grep -v \
|
||||||
-e src/includes/helpers.h \
|
-e src/includes/helpers.h \
|
||||||
@@ -102,7 +100,6 @@ eend $? "These need to be using the x* variant:"$'\n'"${out}"
|
|||||||
|
|
||||||
ebegin "Checking spacing style"
|
ebegin "Checking spacing style"
|
||||||
out=$(cd ${top_srcdir}; find src -name '*.[ch]' \
|
out=$(cd ${top_srcdir}; find src -name '*.[ch]' \
|
||||||
! -name queue.h \
|
|
||||||
-exec grep -n -E \
|
-exec grep -n -E \
|
||||||
-e '\<(for|if|switch|while)\(' \
|
-e '\<(for|if|switch|while)\(' \
|
||||||
-e '\<(for|if|switch|while) \( ' \
|
-e '\<(for|if|switch|while) \( ' \
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
# Using supervise-daemon
|
|
||||||
|
|
||||||
Beginning with OpenRC-0.21 we have our own daemon supervisor,
|
|
||||||
supervise-daemon., which can start a daemon and restart it if it
|
|
||||||
terminates unexpectedly.
|
|
||||||
|
|
||||||
The following is a brief guide on using this capability.
|
|
||||||
|
|
||||||
## Use Default start, stop and status functions
|
|
||||||
|
|
||||||
If you write your own start, stop and status functions in your service
|
|
||||||
script, none of this will work. You must allow OpenRC to use the default
|
|
||||||
functions.
|
|
||||||
|
|
||||||
## Daemons must not fork
|
|
||||||
|
|
||||||
Any deamon that you would like to have monitored by supervise-daemon
|
|
||||||
must not fork. Instead, it must stay in the foreground. If the daemon
|
|
||||||
itself forks, the supervisor will be unable to monitor it.
|
|
||||||
|
|
||||||
If the daemon can be configured to not fork, this should be done in the
|
|
||||||
daemon's configuration file, or by adding a command line option that
|
|
||||||
instructs it not to fork to the command_args_foreground variable shown
|
|
||||||
below.
|
|
||||||
|
|
||||||
## Variable Settings
|
|
||||||
|
|
||||||
The most important setting is the supervisor variable. At the top of
|
|
||||||
your service script, you should set this variable as follows:
|
|
||||||
|
|
||||||
supervisor=supervise-daemon
|
|
||||||
|
|
||||||
Several other variables affect the way services behave under
|
|
||||||
supervise-daemon. They are documented on the openrc-run man page, but I
|
|
||||||
will list them here for convenience:
|
|
||||||
|
|
||||||
pidfile=/pid/of/supervisor.pid
|
|
||||||
|
|
||||||
If you are using start-stop-daemon to monitor your scripts, the pidfile
|
|
||||||
is the path to the pidfile the daemon creates. If, on the other hand,
|
|
||||||
you are using supervise-daemon, this is the path to the pidfile the
|
|
||||||
supervisor creates.
|
|
||||||
|
|
||||||
command_args_foreground should be used if the daemon you want to monitor
|
|
||||||
forks and goes to the background by default. This should be set to the
|
|
||||||
command line option that instructs the daemon to stay in the foreground.
|
|
||||||
|
|
||||||
This is very early support, so feel free to file bugs if you have
|
|
||||||
issues.
|
|
||||||
@@ -21,3 +21,7 @@ LD_LIBRARY_PATH=${top_builddir}/src/libeinfo:${top_builddir}/src/librc:${LD_LIBR
|
|||||||
PATH=${top_builddir}/src/rc:${PATH}
|
PATH=${top_builddir}/src/rc:${PATH}
|
||||||
export LD_LIBRARY_PATH PATH
|
export LD_LIBRARY_PATH PATH
|
||||||
|
|
||||||
|
cd ${top_srcdir}/src/rc
|
||||||
|
${MAKE:-make} links >/dev/null
|
||||||
|
cd -
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user