Compare commits

..

18 Commits

Author SHA1 Message Date
William Hubbs
66651180a7 update change log 2016-01-19 13:55:30 -06:00
William Hubbs
7d63dc928c localmount: Allow users to control whether errors are ignored
X-Gentoo-Bug: 572138
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=572138
2016-01-19 13:38:33 -06:00
Doug Freed
8e16828bd3 rc: remove use of magic constant and allow OpenVZ to drop to shell
OpenVZ has had console support for a long time now; allow them to use it
to drop to a shell during interactive boot.
2016-01-19 10:54:52 -06:00
Doug Freed
3a30710916 librc: handle rc_sys="prefix" even if we weren't built with a prefix
This probably isn't needed, but it mimics old behavior.
2016-01-19 10:54:52 -06:00
Doug Freed
290a91e8e9 librc: fix handling the nothing special case for rc_sys 2016-01-19 10:54:52 -06:00
Doug Freed
04d94be766 librc: move system detection code into rc_sys and use it
This fixes an issue where librc code was calling code that only existed
in the rc binary.

This reverts commits 8addd79 and 9f6e056

This fixes #75.
2016-01-19 10:54:52 -06:00
William Hubbs
fa6707e5b3 fix bsd build
X-Gentoo-Bug: 572068
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=572068
2016-01-18 22:53:58 -06:00
William Hubbs
3286a98fe6 start 0.20.3 2016-01-18 22:45:01 -06:00
William Hubbs
dc0ab571a2 update change log 2016-01-14 13:53:50 -06:00
William Hubbs
fb37e1aa96 src/rc/Makefile: fix make depend target 2016-01-14 13:35:56 -06:00
William Hubbs
8769cca710 include rc.h properly in source files
We were attempting to include rc.h in rc-misc.h instead of the source
files where it should be included.
2016-01-14 13:35:56 -06:00
William Hubbs
506f2887e1 fix selinux build
X-Gentoo-Bug: 571798
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=571798
2016-01-14 11:47:23 -06:00
William Hubbs
83223a6e97 version 0.20.2 2016-01-14 11:45:21 -06:00
William Hubbs
2747f40f82 update changelog 2016-01-13 20:21:17 -06:00
William Hubbs
933972da53 fix selinux build 2016-01-13 20:15:15 -06:00
William Hubbs
dbcb8ba3fe Add LANG, LC_MESSAGES and TERM to the environment whitelist 2016-01-13 20:15:14 -06:00
William Hubbs
e462c3223e fix seg fault 2016-01-13 20:15:14 -06:00
William Hubbs
06f195ce37 increment version number 2016-01-13 19:53:03 -06:00
70 changed files with 918 additions and 2074 deletions

1301
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@@ -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:

View File

@@ -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
View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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
View File

@@ -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
View File

@@ -1,5 +1,4 @@
binfmt binfmt
modules-load
bootmisc bootmisc
fsck fsck
hostname hostname

View File

@@ -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

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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() {

View File

@@ -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()

View File

@@ -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
} }

View File

@@ -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()

View File

@@ -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
} }

View File

@@ -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
} }

View File

@@ -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
}

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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

View File

@@ -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()

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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
} }

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 \

View File

@@ -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"

View File

@@ -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

View File

@@ -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 ;;

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
View File

@@ -5,7 +5,6 @@ rc-update
runscript runscript
service service
start-stop-daemon start-stop-daemon
supervise-daemon
einfon einfon
einfo einfo
ewarnn ewarnn

View File

@@ -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}

View File

@@ -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");

View File

@@ -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)

View File

@@ -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) {

View File

@@ -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"))) {

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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

View File

@@ -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));

View File

@@ -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.

View File

@@ -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));

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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) \( ' \

View File

@@ -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.

View File

@@ -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 -