Compare commits

..

40 Commits
0.48 ... master

Author SHA1 Message Date
John Einar Reitan
3d30b6fdda Add xterm-kitty to color capable term list 2024-04-05 00:02:33 -05:00
William Hubbs
4574b5d8e4 clarify news update about split-usr option 2024-04-01 14:22:37 -05:00
William Hubbs
6b42019697 version 0.54 2024-04-01 12:06:53 -05:00
William Hubbs
42408e7488 update news 2024-04-01 12:05:18 -05:00
Oskari Pirhonen
957140cb78 Touch up docs/comments
Remove the mention of linking with libtermcap from einfo(3), and fix
some comments in libeinfo.c to more accurately reflect the new
situation.
2024-03-31 23:13:02 -05:00
Oskari Pirhonen
536794dfad Trivial curses/termcap removal
Remove the curses code and make the HAVE_TERMCAP-gated "fallbacks"
always present. This makes an ANSI terminal required for colors.

X-Gentoo-Bug: https://bugs.gentoo.org/904277
Closes: https://github.com/OpenRC/openrc/issues/619
2024-03-31 23:13:02 -05:00
William Hubbs
7ac2080e31 ci: update FreeBSD releases we test against 2024-03-31 18:31:19 -05:00
Sam James
12e1e88475 meson: drop broken split-usr handling
Two issues here:

* The 'split-usr' meson option wasn't doing anything, it tried to check
  if /bin was a symlink, but nothing acted on this information.

* The actual rootprefix default was decided based on whether /bin was a symlink
  which is flaky if e.g. building on a merged-usr system for use on a non-merged-usr
  system.

People can set -Drootprefix=/usr if they wish.

There's no real advantage to installing to /usr over / as the compat. symlinks
are really here to stay. If someone really does care about this, they can bring
it back and do it properly, but it doesn't seem worth it to me at all.

Bug: https://bugs.gentoo.org/927776
Fixes: cc0037e9ca
Fixes: f2362cc277
Fixes: #696
2024-03-25 14:10:13 -05:00
William Hubbs
c45fe9fba5 version 0.53 2024-01-12 11:29:03 -06:00
William Hubbs
961c479e1d update news 2024-01-12 11:24:48 -06:00
Forza-tng
f9c92d7822 enable confd cgroups mount options
This fixes #684.
2024-01-12 11:17:14 -06:00
Natanael Copa
97689d6c44 sh/rc-cgroup.sh: add openrc. prefix the cgroupv2 path
Some services, like docker, creates and manages /sys/fs/cgroup/<service>
themselves. Avoid conflict with the openrc created cgroup path by adding
a `openrc.` prefix.

Fixes: https://github.com/OpenRC/openrc/issues/680
2024-01-09 10:09:59 -06:00
Alexey Vazhnov
439cce426d supervise-daemon-guide.md: adjust markdown formatting. No logic/text changes were made. 2023-12-16 09:10:18 -05:00
Zhao Yongming
bfdafe4463 change info words "remove" to "delete" in delete sub-command
This close #664
2023-12-04 10:53:23 -05:00
Zhao Yongming
179ff285ca update start-stop-daemon manual to include --quiet 2023-12-04 10:52:07 -05:00
William Hubbs
f9bbbfbf4b update news 2023-11-16 23:29:09 -06:00
William Hubbs
59a175541d remove warning for runscript deprecation 2023-11-15 10:04:46 -06:00
William Hubbs
65b13eb86f drop the deprecated "rc" binary
This binary is a copy of the openrc binary. Referring to it as rc was
deprecated in 2016, so we should be able to drop it at this point.
2023-11-15 10:01:45 -06:00
Alexander Maltsev
fda9dcd1f2 Skip already processed files in rc_service_daemon_set
Fixes the problem described in https://bugs.gentoo.org/916947 -
start-stop-daemon hangs in infinite loop when stopping some daemons on
linux 6.6+

It appears linux 6.6 reworked tmpfs, and since then it triggers this
problem in openrc: when iterating over files via readdir, running rename
on a file could result in reading the same file again with next readdir
call.

The Open Group manual for readdir explicitly states "If a file is
removed from or added to the directory after the most recent call to
opendir() or rewinddir(), whether a subsequent call to readdir() returns
an entry for that file is unspecified.". Linux man page don't seem to
mention that, but don't seem to say anything to contradict that either.
So I presume we can't rely on some specific behaviour here.

Bug: https://bugs.gentoo.org/916947
2023-11-14 14:35:23 -06:00
Sam James
6f180e9424 init.d/cgroups.in: fix inconsistency between mount_cgroups and mount_cgroups
965de92b37 changed the default cgroup mode which
exposes an issue in init.d/cgroups.in.

While mount_cgroups defaults to 'unified' if rc_cgroup_mode is unset, cgroup2_controllers
has no default and therefore has a mismatch with the logic in mount_cgroups. The
two should be consistent so the flow makes sense, as mount_cgroups expects a certain
path to be taken in cgroup2_controllers.

Make cgroup2_controllers default to 'unified' if rc_cgroup_mode is unset, just
like mount_cgroups.

Bug: https://bugs.gentoo.org/916964
Thanks-to: acab@digitalfuture.it
2023-11-14 14:31:22 -06:00
William Hubbs
88e5d98d05 drop the deprecated runscript binary 2023-11-14 14:19:35 -06:00
Haelwenn (lanodan) Monnier
1433552435 sh/supervise-daemon.sh: Proper casing for --no-new-privs 2023-11-02 13:35:37 -04:00
William Hubbs
554ccab718 version 0.51 2023-10-10 14:16:44 -05:00
William Hubbs
228b3c6c99 update news 2023-10-10 14:15:15 -05:00
William Hubbs
965de92b37 change default RC_CGROUP_MODE to unified
This improves resource management by assigning services to individual
cgroups.

X-Gentoo-Bug: https://bugs.gentoo.org/914972
2023-10-10 12:50:09 -05:00
Adam Duskett
b85d771e1f Force symlinking of openrc-init to init
When building on embedded SDKs such as Buildroot or Yocto, if OpenRC has a
previous installation, the package will fail the installation step as the
openrc-init is already a symlink to "${DESTDIR}/${sbindir}"/init. Force
symlinking to prevent errors when reinstalling the package.
2023-10-10 08:55:33 -04:00
Lexxy Fox
cf9286d2d8 Relocate pipes.c and pipes.h file to shared directory.
With the addition of logger process redirect in supervise-daemon,
pipes.c and pipes.h are now included in both s-s-d and supervise-daemon.
Thus it makes sense to move the source files to the src/shared dir.
2023-10-03 16:43:39 -05:00
Lexxy Fox
9934e9f96e supervise-daemon: implement output_logger and error_logger.
Allows redirecting process stdin and stdout to another process,
just like is already possible with start-stop-daemon.

Also added --stdout-logger and --stderr-logger to the man page.
2023-10-03 16:43:39 -05:00
William Hubbs
f1e5510ccf version 0.50 2023-09-19 16:02:03 -05:00
William Hubbs
1b72c3a7ab update news 2023-09-19 15:59:31 -05:00
Natanael Copa
c4785f1b99 misc: add syscall fallback for close_range for musl libc
Add fallback for the close_range syscall wrapper. This is needed for
musl libc, which currently does not have a close_range wrapper.

Also set errno on errors.
2023-09-12 22:53:12 -05:00
Natanael Copa
e447562aaa start-stop-daemon: set fds to CLOEXEC instead of closing
Set file descriptors to CLOEXEC instead of closing them before exec,
similar to what we do in supervise-daemon.

Use the share cloexec_fds_from() helper for this.

closefrom() is no longer used so remove the test.
2023-09-12 22:53:12 -05:00
Natanael Copa
c199c5cf6e misc: add cloexec_fds_from() helper function
Move logic to set file descriptors to a cloexec_fds_from() function in
misc.c so it can be shared by both supervisor-daemon and
start-stop-daemon, and hide the details behind.
2023-09-12 22:53:12 -05:00
Natanael Copa
5bfb592d75 supervise-daemon: rename HAVE_CLOSE_RANGE_EXEC to HAVE_CLOSE_RANGE
Use HAVE_CLOSE_RANGE to tell if system provides a close_range(2)
wrapper, which better explains the purpose.

Add a compat inline which returns -1 if close_range is unavailable.
2023-09-12 22:53:12 -05:00
Timothy Kenno Handojo
b2c4eb97b5 remove /lib/rc/tmp creation from meson script
It is apparently for a piece of code that no longer exist.
There don't seem to be any part of the code referring to this directory (anymore, if there was).
2023-09-01 11:54:30 -05:00
William Hubbs
e740913fcb version 0.49 2023-08-31 14:13:19 -05:00
William Hubbs
1bc34a39cd update news 2023-08-31 14:12:26 -05:00
Sam James
c1cd3c9830 Don't re-define strlcpy/strlcat with >=glibc-2.38
`>=glibc-2.38` implements strlcpy, strlcat, etc so check for those functions
with Meson and don't provide conflicting prototypes.

Technically, it doesn't need _GNU_SOURCE, but it's easier because it's not
clear right now what glibc wants to guard it with. Note that these are in
POSIX next anyway.

Fixes: https://github.com/OpenRC/openrc/issues/643
Signed-off-by: Sam James <sam@gentoo.org>
2023-08-29 23:31:18 -04:00
Sven Wegener
86efc43d0e rc: fix automatic restart with runlevel-specific conf.d files
Commit fc4f15d6cd broke the automatic restart of
services having runlevel-specific conf.d files.

The double dirname() was not a mistake, but the way of getting from the
service script in init.d to the upper directory containing the conf.d
directory. dirname() modifies the argument in-place, so the second call
operated on a modified value. To make it more obvious what is going on,
have the second call operate on the returned value from the first call.

Fixes: fc4f15d ("openrc: fix double-assignment to dir")
Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
2023-07-26 22:41:42 -05:00
Jernej Jakob
cd53239701 bash-completion/rc-service: don't set or unset extglob
It breaks bash-completion.
It's not necessary to set extglob as patterns in '[[' after '=='
are always matched as if extglob were set.

Closes: #636
Signed-off-by: Jernej Jakob <jernej.jakob@gmail.com>
2023-07-26 22:41:19 -05:00
33 changed files with 240 additions and 213 deletions

View File

@@ -4,8 +4,8 @@
test_task: test_task:
freebsd_instance: freebsd_instance:
matrix: matrix:
image: freebsd-13-1-release-amd64 image: freebsd-13-2-release-amd64
image: freebsd-12-4-release-amd64 image: freebsd-13-3-release-amd64
env: env:
OS: FreeBSD OS: FreeBSD
procfs_script: > procfs_script: >

48
NEWS.md
View File

@@ -4,6 +4,54 @@ OpenRC NEWS
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.54
This release drops the support for the split-usr build option.
Also, it drops the support for ncurses/termcap and uses ansi codes
directly for color support on terminals that support them.
## OpenRC 0.53
The names of cgroups for services started by OpenRC are now prefixed by
"openrc." This is done because some services, like docker, create their
own cgroups.
It is now possible to override the mount options used to mount the
cgroups filesystems.
## OpenRC 0.52
This release drops the "runscript" and "rc" binaries.
These binaries have been deprecated for multiple years, so it should be
fine to remove them at this point.
There was an issue before this release with the default setting for
cgroups being inconsistent. This is fixed.
Start-stop-daemon did not work correctly on Linux 6.6 systems.
This has been fixed in this release as well.
## OpenRC 0.51
The default RC_CGROUP_MODE has been updated to unified.
This benefits users since it will assign each service to its own cgroup,
making resource nanagement better over all.
OUTPUT_LOGGER and ERROR_LOGGER have been implemented for
supervise-daemon. For mor einformation on these settings, please check
the man page.
## OpenRC 0.50
This is a bug fix release which fixes a significant performance issue on
musl libc systems.
## OpenRC 0.49
This release adds support for glibc's builtin
strlcpy, strlcat etc functions, which will be in posix next.
Also, it fixes completions.
## OpenRC 0.48 ## OpenRC 0.48
This release is a maintenance release; it has no user-facing changes. This release is a maintenance release; it has no user-facing changes.

View File

@@ -92,13 +92,11 @@ _rc_service()
return 0 return 0
elif [[ ${COMP_CWORD} -eq 2 ]] && [[ ${prev} != -* ]]; then # if second word typed and we didn't type in a function elif [[ ${COMP_CWORD} -eq 2 ]] && [[ ${prev} != -* ]]; then # if second word typed and we didn't type in a function
rc-service --exists "$prev" || return rc-service --exists "$prev" || return
shopt -s extglob
while read -r _ line; do while read -r _ line; do
if [[ $line == +([[:alnum:]_]):* ]]; then if [[ $line == +([[:alnum:]_]):* ]]; then
opts+="${line%%:*} " opts+="${line%%:*} "
fi fi
done < <(rc-service "$prev" describe 2>&1) done < <(rc-service "$prev" describe 2>&1)
shopt -u extglob
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0 return 0
fi fi

2
conf.d/cgroups Normal file
View File

@@ -0,0 +1,2 @@
# override cgroup mount options
#cgroup_opts=nodev,noexec,nosuid

View File

@@ -199,7 +199,7 @@ rc_tty_number=12
# cgroups version 1 on /sys/fs/cgroup. # cgroups version 1 on /sys/fs/cgroup.
# "legacy" mounts cgroups version 1 on /sys/fs/cgroup # "legacy" mounts cgroups version 1 on /sys/fs/cgroup
# "unified" mounts cgroups version 2 on /sys/fs/cgroup # "unified" mounts cgroups version 2 on /sys/fs/cgroup
#rc_cgroup_mode="hybrid" #rc_cgroup_mode="unified"
# This is a list of controllers which should be enabled for cgroups version 2 # This is a list of controllers which should be enabled for cgroups version 2
# when hybrid mode is being used. # when hybrid mode is being used.

View File

@@ -11,7 +11,7 @@
description="Mount the control groups." description="Mount the control groups."
cgroup_opts=nodev,noexec,nosuid : "${cgroup_opts:="nodev,noexec,nosuid"}"
depend() depend()
{ {
@@ -87,7 +87,7 @@ cgroup2_controllers()
[ ! -e "${cgroup_path}/cgroup.subtree_control" ]&& return 0 [ ! -e "${cgroup_path}/cgroup.subtree_control" ]&& return 0
read -r active < "${cgroup_path}/cgroup.controllers" read -r active < "${cgroup_path}/cgroup.controllers"
for x in ${active}; do for x in ${active}; do
case "$rc_cgroup_mode" in case "${rc_cgroup_mode:-unified}" in
unified) unified)
echo "+${x}" > "${cgroup_path}/cgroup.subtree_control" echo "+${x}" > "${cgroup_path}/cgroup.subtree_control"
;; ;;
@@ -128,7 +128,7 @@ cgroups_unified()
mount_cgroups() mount_cgroups()
{ {
case "${rc_cgroup_mode:-hybrid}" in case "${rc_cgroup_mode:-unified}" in
hybrid) cgroups_hybrid ;; hybrid) cgroups_hybrid ;;
legacy) cgroups_legacy ;; legacy) cgroups_legacy ;;
unified) cgroups_unified ;; unified) cgroups_unified ;;

View File

@@ -158,13 +158,6 @@ is true.
prefixes the string prefixes the string
.Fa prefix .Fa prefix
to the above functions. to the above functions.
.Sh IMPLEMENTATION NOTES
einfo can optionally be linked against the
.Lb libtermcap
so that we can correctly query the connected console for our color and
cursor escape codes.
If not, then we have a hard coded list of terminals we know about that support
the commonly used codes for color and cursor position.
.Sh ENVIRONMENT .Sh ENVIRONMENT
.Va EINFO_QUIET .Va EINFO_QUIET
when set to true makes the when set to true makes the

View File

@@ -84,6 +84,8 @@ Print the action(s) that would be taken, but don't actually do anything.
The return value is set as if the command was taken and worked. The return value is set as if the command was taken and worked.
.It Fl v , -verbose .It Fl v , -verbose
Print the action(s) that are taken just before doing them. Print the action(s) that are taken just before doing them.
.It Fl q , -quiet
Run quietly (repeat to suppress errors).
.It Fl P , -progress .It Fl P , -progress
Echo a . to the console for each second elapsed whilst waiting. Echo a . to the console for each second elapsed whilst waiting.
.El .El

View File

@@ -158,6 +158,23 @@ The logfile can also be a named pipe.
The same thing as The same thing as
.Fl 1 , -stdout .Fl 1 , -stdout
but with the standard error output. but with the standard error output.
.It Fl -stdout-logger Ar cmd
Run cmd as a child process redirecting the standard output to the
standard input of cmd when started with
.Fl background .
Cmd must be an absolute pathname, but relative to the path optionally given with
.Fl r , -chroot .
This process must be prepared to accept input on stdin and be able to
log it or send it to another location.
.It Fl -stderr-logger Ar cmd
Run cmd as a child process and
Redirect the standard error of the process to the standard input of cmd
when started with
.Fl background .
Cmd must be an absolute pathname, but relative to the path optionally given with
.Fl r , -chroot .
This process must be prepared to accept input on stdin and be able to
log it or send it to another location.
.It Fl -capabilities Ar cap-list .It Fl -capabilities Ar cap-list
Start the daemon with the listed inheritable, ambient and bounding capabilities. Start the daemon with the listed inheritable, ambient and bounding capabilities.
The format is the same as in cap_iab(3). The format is the same as in cap_iab(3).

View File

@@ -1,5 +1,5 @@
project('OpenRC', 'c', project('OpenRC', 'c',
version : '0.48', version : '0.54',
license: 'BSD-2', license: 'BSD-2',
default_options : [ default_options : [
'c_std=c99', 'c_std=c99',
@@ -83,16 +83,9 @@ else
pkg_prefix = option_pkg_prefix pkg_prefix = option_pkg_prefix
endif endif
if get_option('split-usr') == 'auto'
split_usr = run_command('test', '-L', '/bin', check: false).returncode() != 0
else
split_usr = get_option('split-usr') == 'true'
endif
rootprefix = get_option('rootprefix') rootprefix = get_option('rootprefix')
rootprefix_default = fs.is_symlink('/bin') ? '/usr' : '/'
if rootprefix == '' if rootprefix == ''
rootprefix = rootprefix_default rootprefix = '/'
endif endif
bindir = rootprefix / get_option('bindir') bindir = rootprefix / get_option('bindir')
@@ -133,15 +126,6 @@ else
cc_selinux_flags = [] cc_selinux_flags = []
endif endif
termcap = get_option('termcap')
if termcap != ''
termcap_dep = dependency(termcap)
termcap_flags = '-DHAVE_TERMCAP'
else
termcap_dep = []
termcap_flags = []
endif
if get_option('buildtype').startswith('debug') if get_option('buildtype').startswith('debug')
cc_debug_flags = ['-DRC_DEBUG'] cc_debug_flags = ['-DRC_DEBUG']
else else
@@ -195,12 +179,14 @@ if cc.compiles(malloc_attribute_test, name : 'malloc attribute with arguments')
add_project_arguments('-DHAVE_MALLOC_EXTENDED_ATTRIBUTE', language: 'c') add_project_arguments('-DHAVE_MALLOC_EXTENDED_ATTRIBUTE', language: 'c')
endif endif
if cc.has_function('closefrom', prefix: '#define _GNU_SOURCE\n#include <unistd.h>') if cc.has_function('close_range', prefix: '#define _GNU_SOURCE\n#include <unistd.h>')
add_project_arguments('-DHAVE_CLOSEFROM', language: 'c') add_project_arguments('-DHAVE_CLOSE_RANGE', language: 'c')
elif cc.has_header('linux/close_range.h')
add_project_arguments('-DHAVE_LINUX_CLOSE_RANGE_H', language: 'c')
endif endif
if cc.has_function('close_range', prefix: '#define _GNU_SOURCE\n#include <unistd.h>') and \
cc.has_header_symbol('unistd.h', 'CLOSE_RANGE_CLOEXEC', prefix: '#define _GNU_SOURCE') if cc.has_function('strlcpy', prefix: '#define _GNU_SOURCE\n#include <string.h>')
add_project_arguments('-DHAVE_CLOSE_RANGE_CLOEXEC', language: 'c') add_project_arguments('-DHAVE_STRLCPY', language: 'c')
endif endif
incdir = include_directories('src/shared') incdir = include_directories('src/shared')

View File

@@ -26,14 +26,7 @@ option('selinux', type : 'feature', value : 'auto',
description : 'enable SELinux support') description : 'enable SELinux support')
option('shell', type : 'string', value : '/bin/sh', option('shell', type : 'string', value : '/bin/sh',
description : 'Default posix compatible shell') description : 'Default posix compatible shell')
option('split-usr', type : 'combo',
choices : ['auto', 'true', 'false'],
description : '''/bin, /sbin aren't symlinks into /usr''')
option('sysvinit', type : 'boolean', value : false, option('sysvinit', type : 'boolean', value : false,
description : 'enable SysVinit compatibility (linux only)') description : 'enable SysVinit compatibility (linux only)')
option('termcap', type : 'combo',
choices :
[ '', 'ncurses', 'termcap' ],
description : 'the termcap library to use')
option('zsh-completions', type : 'boolean', option('zsh-completions', type : 'boolean',
description : 'install zsh completions') description : 'install zsh completions')

View File

@@ -35,7 +35,7 @@ cgroup_get_pids()
cgroup_pids= cgroup_pids=
cgroup_procs="$(cgroup2_find_path)" cgroup_procs="$(cgroup2_find_path)"
if [ -n "${cgroup_procs}" ]; then if [ -n "${cgroup_procs}" ]; then
cgroup_procs="${cgroup_procs}/${RC_SVCNAME}/cgroup.procs" cgroup_procs="${cgroup_procs}/openrc.${RC_SVCNAME}/cgroup.procs"
else else
cgroup_procs="/sys/fs/cgroup/openrc/${RC_SVCNAME}/tasks" cgroup_procs="/sys/fs/cgroup/openrc/${RC_SVCNAME}/tasks"
fi fi
@@ -154,7 +154,7 @@ cgroup_set_limits()
cgroup2_find_path() cgroup2_find_path()
{ {
if grep -qw cgroup2 /proc/filesystems; then if grep -qw cgroup2 /proc/filesystems; then
case "${rc_cgroup_mode:-hybrid}" in case "${rc_cgroup_mode:-unified}" in
hybrid) printf "/sys/fs/cgroup/unified" ;; hybrid) printf "/sys/fs/cgroup/unified" ;;
unified) printf "/sys/fs/cgroup" ;; unified) printf "/sys/fs/cgroup" ;;
esac esac
@@ -167,7 +167,7 @@ cgroup2_remove()
local cgroup_path rc_cgroup_path local cgroup_path rc_cgroup_path
cgroup_path="$(cgroup2_find_path)" cgroup_path="$(cgroup2_find_path)"
[ -z "${cgroup_path}" ] && return 0 [ -z "${cgroup_path}" ] && return 0
rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}" rc_cgroup_path="${cgroup_path}/openrc.${RC_SVCNAME}"
[ ! -d "${rc_cgroup_path}" ] || [ ! -d "${rc_cgroup_path}" ] ||
[ ! -e "${rc_cgroup_path}"/cgroup.events ] && [ ! -e "${rc_cgroup_path}"/cgroup.events ] &&
return 0 return 0
@@ -191,7 +191,7 @@ cgroup2_set_limits()
cgroup_path="$(cgroup2_find_path)" cgroup_path="$(cgroup2_find_path)"
[ -z "${cgroup_path}" ] && return 0 [ -z "${cgroup_path}" ] && return 0
mountinfo -q "${cgroup_path}"|| return 0 mountinfo -q "${cgroup_path}"|| return 0
rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}" rc_cgroup_path="${cgroup_path}/openrc.${RC_SVCNAME}"
[ ! -d "${rc_cgroup_path}" ] && mkdir "${rc_cgroup_path}" [ ! -d "${rc_cgroup_path}" ] && mkdir "${rc_cgroup_path}"
[ -f "${rc_cgroup_path}"/cgroup.procs ] && [ -f "${rc_cgroup_path}"/cgroup.procs ] &&
printf 0 > "${rc_cgroup_path}"/cgroup.procs printf 0 > "${rc_cgroup_path}"/cgroup.procs
@@ -210,7 +210,7 @@ cgroup2_kill_cgroup() {
local cgroup_path local cgroup_path
cgroup_path="$(cgroup2_find_path)" cgroup_path="$(cgroup2_find_path)"
[ -z "${cgroup_path}" ] && return 1 [ -z "${cgroup_path}" ] && return 1
rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}" rc_cgroup_path="${cgroup_path}/openrc.${RC_SVCNAME}"
if [ -f "${rc_cgroup_path}"/cgroup.kill ]; then if [ -f "${rc_cgroup_path}"/cgroup.kill ]; then
printf "%d" 1 > "${rc_cgroup_path}"/cgroup.kill printf "%d" 1 > "${rc_cgroup_path}"/cgroup.kill
fi fi

View File

@@ -30,6 +30,8 @@ supervise_start()
${chroot:+--chroot} $chroot \ ${chroot:+--chroot} $chroot \
${output_log+--stdout} ${output_log} \ ${output_log+--stdout} ${output_log} \
${error_log+--stderr} $error_log \ ${error_log+--stderr} $error_log \
${output_logger:+--stdout-logger \"$output_logger\"} \
${error_logger:+--stderr-logger \"$error_logger\"} \
${pidfile:+--pidfile} $pidfile \ ${pidfile:+--pidfile} $pidfile \
${respawn_delay:+--respawn-delay} $respawn_delay \ ${respawn_delay:+--respawn-delay} $respawn_delay \
${respawn_max:+--respawn-max} $respawn_max \ ${respawn_max:+--respawn-max} $respawn_max \
@@ -38,7 +40,7 @@ supervise_start()
${healthcheck_timer:+--healthcheck-timer} $healthcheck_timer \ ${healthcheck_timer:+--healthcheck-timer} $healthcheck_timer \
${capabilities+--capabilities} "$capabilities" \ ${capabilities+--capabilities} "$capabilities" \
${secbits:+--secbits} "$secbits" \ ${secbits:+--secbits} "$secbits" \
${no_new_privs:+--no_new_privs} \ ${no_new_privs:+--no-new-privs} \
${command_user+--user} $command_user \ ${command_user+--user} $command_user \
${umask+--umask} $umask \ ${umask+--umask} $umask \
${supervise_daemon_args-${start_stop_daemon_args}} \ ${supervise_daemon_args-${start_stop_daemon_args}} \

View File

@@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2007-2015 The OpenRC Authors. * Copyright (c) 2007-2024 The OpenRC Authors.
* See the Authors file at the top-level directory of this distribution and * See the Authors file at the top-level directory of this distribution and
* https://github.com/OpenRC/openrc/blob/HEAD/AUTHORS * https://github.com/OpenRC/openrc/blob/HEAD/AUTHORS
* *
@@ -26,9 +26,6 @@
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <syslog.h> #include <syslog.h>
#ifdef HAVE_TERMCAP
# include <termcap.h>
#endif
#include <unistd.h> #include <unistd.h>
#include "einfo.h" #include "einfo.h"
@@ -53,8 +50,7 @@
#define HILITE 6 #define HILITE 6
#define BRACKET 4 #define BRACKET 4
/* We fallback to these escape codes if termcap isn't available /* ANSI escape codes which mimic termcap */
* like say /usr isn't mounted */
#define AF "\033[3%dm" #define AF "\033[3%dm"
#define CE "\033[K" #define CE "\033[K"
#define CH "\033[%dC" #define CH "\033[%dC"
@@ -97,13 +93,7 @@ static char *goto_column = NULL;
static const char *term = NULL; static const char *term = NULL;
static bool term_is_cons25 = false; static bool term_is_cons25 = false;
/* Termcap buffers and pointers /* Hardcoded list of colour capable terms
* Static buffers suck hard, but some termcap implementations require them */
#ifdef HAVE_TERMCAP
static char termcapbuf[2048];
static char tcapbuf[512];
#else
/* No curses support, so we hardcode a list of colour capable terms
* Only terminals without "color" in the name need to be explicitly listed */ * Only terminals without "color" in the name need to be explicitly listed */
static const char *const color_terms[] = { static const char *const color_terms[] = {
"Eterm", "Eterm",
@@ -142,13 +132,11 @@ static const char *const color_terms[] = {
"wsvt25", "wsvt25",
"xterm", "xterm",
"xterm-debian", "xterm-debian",
"xterm-kitty",
NULL NULL
}; };
#endif
/* strlcat and strlcpy are nice, shame glibc does not define them */ #ifndef HAVE_STRLCPY
#ifdef __GLIBC__
# if !defined (__UCLIBC__) && !defined (__dietlibc__)
static size_t static size_t
strlcat(char *dst, const char *src, size_t size) strlcat(char *dst, const char *src, size_t size)
{ {
@@ -177,7 +165,6 @@ strlcat(char *dst, const char *src, size_t size)
return dst_n + (s - src); return dst_n + (s - src);
} }
#endif #endif
#endif
static bool static bool
yesno(const char *value) yesno(const char *value)
@@ -239,7 +226,6 @@ is_verbose(void)
} }
/* Fake tgoto call - very crapy, but works for our needs */ /* Fake tgoto call - very crapy, but works for our needs */
#ifndef HAVE_TERMCAP
static char * static char *
tgoto(const char *cap, int col, int line) tgoto(const char *cap, int col, int line)
{ {
@@ -302,7 +288,6 @@ tgoto(const char *cap, int col, int line)
*p = '\0'; *p = '\0';
return buf; return buf;
} }
#endif
static bool static bool
colour_terminal(FILE * EINFO_RESTRICT f) colour_terminal(FILE * EINFO_RESTRICT f)
@@ -315,9 +300,6 @@ colour_terminal(FILE * EINFO_RESTRICT f)
const char *bold; const char *bold;
char tmp[100]; char tmp[100];
unsigned int i = 0; unsigned int i = 0;
#ifdef HAVE_TERMCAP
char *bp;
#endif
if (f && !isatty(fileno(f))) if (f && !isatty(fileno(f)))
return false; return false;
@@ -339,25 +321,6 @@ colour_terminal(FILE * EINFO_RESTRICT f)
if (strcmp(term, "cons25") == 0) if (strcmp(term, "cons25") == 0)
term_is_cons25 = true; term_is_cons25 = true;
#ifdef HAVE_TERMCAP
/* Check termcap to see if we can do colour or not */
if (tgetent(termcapbuf, term) == 1) {
bp = tcapbuf;
_af = tgetstr("AF", &bp);
_ce = tgetstr("ce", &bp);
_ch = tgetstr("ch", &bp);
/* Our ch use also works with RI .... for now */
if (!_ch)
_ch = tgetstr("RI", &bp);
_md = tgetstr("md", &bp);
_me = tgetstr("me", &bp);
_up = tgetstr("up", &bp);
}
/* Cheat here as vanilla BSD has the whole termcap info in /usr
* which is not available to us when we boot */
if (term_is_cons25 || strcmp(term, "wsvt25") == 0) {
#else
if (strstr(term, "color")) if (strstr(term, "color"))
in_colour = 1; in_colour = 1;
@@ -372,7 +335,7 @@ colour_terminal(FILE * EINFO_RESTRICT f)
in_colour = 0; in_colour = 0;
return false; return false;
} }
#endif
if (!_af) if (!_af)
_af = AF; _af = AF;
if (!_ce) if (!_ce)
@@ -385,19 +348,6 @@ colour_terminal(FILE * EINFO_RESTRICT f)
_me = ME; _me = ME;
if (!_up) if (!_up)
_up = UP; _up = UP;
#ifdef HAVE_TERMCAP
}
if (!_af || !_ce || !_me || !_md || !_up) {
in_colour = 0;
return false;
}
/* Many termcap databases don't have ch or RI even though they
* do work */
if (!_ch)
_ch = CH;
#endif
/* Now setup our colours */ /* Now setup our colours */
p = ebuffer; p = ebuffer;

View File

@@ -1,9 +1,7 @@
libeinfo_version = '1' libeinfo_version = '1'
libeinfo = library('einfo', ['libeinfo.c'], libeinfo = library('einfo', ['libeinfo.c'],
c_args : termcap_flags,
include_directories : incdir, include_directories : incdir,
dependencies : termcap_dep,
link_depends : 'einfo.map', link_depends : 'einfo.map',
version : libeinfo_version, version : libeinfo_version,
install : true, install : true,

View File

@@ -402,7 +402,7 @@ rc_service_daemon_set(const char *service, const char *exec,
bool retval = false; bool retval = false;
DIR *dp; DIR *dp;
struct dirent *d; struct dirent *d;
RC_STRINGLIST *match; RC_STRINGLIST *match, *renamelist;
int i = 0; int i = 0;
FILE *fp; FILE *fp;
@@ -416,11 +416,17 @@ rc_service_daemon_set(const char *service, const char *exec,
/* Regardless, erase any existing daemon info */ /* Regardless, erase any existing daemon info */
if ((dp = opendir(dirpath))) { if ((dp = opendir(dirpath))) {
match = _match_list(exec, argv, pidfile); match = _match_list(exec, argv, pidfile);
renamelist = rc_stringlist_new();
while ((d = readdir(dp))) { while ((d = readdir(dp))) {
if (d->d_name[0] == '.') if (d->d_name[0] == '.')
continue; continue;
xasprintf(&file, "%s/%s", dirpath, d->d_name); xasprintf(&file, "%s/%s", dirpath, d->d_name);
if (rc_stringlist_find(renamelist, file)) {
free(file);
continue;
}
nfiles++; nfiles++;
if (!*oldfile) { if (!*oldfile) {
@@ -432,11 +438,15 @@ rc_service_daemon_set(const char *service, const char *exec,
} else { } else {
rename(file, oldfile); rename(file, oldfile);
strlcpy(oldfile, file, sizeof(oldfile)); strlcpy(oldfile, file, sizeof(oldfile));
/* Add renamed file to renamelist, as this new file name could
* be read again from readdir() */
rc_stringlist_add(renamelist, oldfile);
} }
free(file); free(file);
} }
closedir(dp); closedir(dp);
rc_stringlist_free(match); rc_stringlist_free(match);
rc_stringlist_free(renamelist);
} }
/* Now store our daemon info */ /* Now store our daemon info */

View File

@@ -6,12 +6,3 @@ executable('openrc-run',
include_directories: [incdir, einfo_incdir, rc_incdir], include_directories: [incdir, einfo_incdir, rc_incdir],
install: true, install: true,
install_dir: sbindir) install_dir: sbindir)
executable('runscript',
['openrc-run.c', misc_c, plugin_c, selinux_c, usage_c, version_h],
c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_selinux_flags],
link_with: [libeinfo, librc],
dependencies: [audit_dep, dl_dep, pam_dep, pam_misc_dep, selinux_dep, util_dep, crypt_dep],
include_directories: [incdir, einfo_incdir, rc_incdir],
install: true,
install_dir: sbindir)

View File

@@ -1097,7 +1097,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 = NULL; char *path = NULL;
@@ -1115,8 +1114,6 @@ int main(int argc, char **argv)
} }
applet = basename_c(argv[0]); 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",
@@ -1289,9 +1286,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

@@ -6,12 +6,3 @@ executable('openrc',
include_directories: [incdir, einfo_incdir, rc_incdir], include_directories: [incdir, einfo_incdir, rc_incdir],
install: true, install: true,
install_dir: sbindir) install_dir: sbindir)
executable('rc',
['rc.c', 'rc-logger.c', misc_c, plugin_c, usage_c, version_h],
c_args : cc_branding_flags,
link_with: [libeinfo, librc],
dependencies: [dl_dep, util_dep],
include_directories: [incdir, einfo_incdir, rc_incdir],
install: true,
install_dir: sbindir)

View File

@@ -527,7 +527,7 @@ runlevel_config(const char *service, const char *level)
char *conf, *dir; char *conf, *dir;
bool retval; bool retval;
dir = dirname(init); dir = dirname(dirname(init));
xasprintf(&conf, "%s/conf.d/%s.%s", dir, service, level); xasprintf(&conf, "%s/conf.d/%s.%s", dir, service, level);
retval = exists(conf); retval = exists(conf);
free(conf); free(conf);
@@ -837,8 +837,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

@@ -88,7 +88,7 @@ delete(const char *runlevel, const char *service)
errno = 0; errno = 0;
if (rc_service_delete(runlevel, service)) { if (rc_service_delete(runlevel, service)) {
einfo("service %s removed from runlevel %s", einfo("service %s deleted from runlevel %s",
service, runlevel); service, runlevel);
return 1; return 1;
} }
@@ -97,7 +97,7 @@ delete(const char *runlevel, const char *service)
eerror("%s: service `%s' is not in the runlevel `%s'", eerror("%s: service `%s' is not in the runlevel `%s'",
applet, service, runlevel); applet, service, runlevel);
else else
eerror("%s: failed to remove service `%s' from runlevel `%s': %s", eerror("%s: failed to delete service `%s' from runlevel `%s': %s",
applet, service, runlevel, strerror (errno)); applet, service, runlevel, strerror (errno));
return retval; return retval;
@@ -144,7 +144,7 @@ static int
delstack(const char *runlevel, const char *stack) delstack(const char *runlevel, const char *stack)
{ {
if (rc_runlevel_unstack(runlevel, stack)) { if (rc_runlevel_unstack(runlevel, stack)) {
einfo("runlevel %s removed from runlevel %s", stack, runlevel); einfo("runlevel %s deleted from runlevel %s", stack, runlevel);
return 1; return 1;
} }
@@ -152,7 +152,7 @@ delstack(const char *runlevel, const char *stack)
eerror("%s: runlevel `%s' is not in the runlevel `%s'", eerror("%s: runlevel `%s' is not in the runlevel `%s'",
applet, stack, runlevel); applet, stack, runlevel);
else else
eerror("%s: failed to remove runlevel `%s' from runlevel `%s': %s", eerror("%s: failed to delete runlevel `%s' from runlevel `%s': %s",
applet, stack, runlevel, strerror (errno)); applet, stack, runlevel, strerror (errno));
return -1; return -1;

View File

@@ -37,11 +37,9 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#ifdef __GLIBC__ #ifndef HAVE_STRLCPY
# if !defined (__UCLIBC__) && !defined (__dietlibc__)
# define strlcpy(dst, src, size) snprintf(dst, size, "%s", src) # define strlcpy(dst, src, size) snprintf(dst, size, "%s", src)
#endif #endif
#endif
#ifndef timespecsub #ifndef timespecsub
#define timespecsub(tsp, usp, vsp) \ #define timespecsub(tsp, usp, vsp) \

View File

@@ -10,6 +10,10 @@ schedules_c = files([
'schedules.c', 'schedules.c',
]) ])
pipes_c = files([
'pipes.c',
])
if selinux_dep.found() if selinux_dep.found()
selinux_c = files([ selinux_c = files([
'selinux.c', 'selinux.c',

View File

@@ -15,10 +15,18 @@
* except according to the terms contained in the LICENSE file. * except according to the terms contained in the LICENSE file.
*/ */
#ifdef HAVE_CLOSE_RANGE
/* For close_range() */
# define _GNU_SOURCE
#endif
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <limits.h> #include <limits.h>
#ifdef HAVE_LINUX_CLOSE_RANGE_H
# include <linux/close_range.h>
#endif
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -26,6 +34,7 @@
#include <sys/file.h> #include <sys/file.h>
#include <sys/time.h> #include <sys/time.h>
#ifdef __linux__ #ifdef __linux__
# include <sys/syscall.h> /* for close_range */
# include <sys/sysinfo.h> # include <sys/sysinfo.h>
#endif #endif
#include <sys/types.h> #include <sys/types.h>
@@ -500,3 +509,30 @@ pid_t get_pid(const char *applet,const char *pidfile)
return pid; return pid;
} }
#ifndef HAVE_CLOSE_RANGE
static inline int close_range(int first RC_UNUSED,
int last RC_UNUSED,
unsigned int flags RC_UNUSED)
{
#ifdef SYS_close_range
return syscall(SYS_close_range, first, last, flags);
#else
errno = ENOSYS;
return -1;
#endif
}
#endif
#ifndef CLOSE_RANGE_CLOEXEC
# define CLOSE_RANGE_CLOEXEC (1U << 2)
#endif
void
cloexec_fds_from(int first)
{
int i;
if (close_range(first, UINT_MAX, CLOSE_RANGE_CLOEXEC) < 0) {
for (i = getdtablesize() - 1; i >= first; --i)
fcntl(i, F_SETFD, FD_CLOEXEC);
}
}

View File

@@ -73,4 +73,6 @@ void from_time_t(char *time_string, time_t tv);
time_t to_time_t(char *timestring); time_t to_time_t(char *timestring);
pid_t get_pid(const char *applet, const char *pidfile); pid_t get_pid(const char *applet, const char *pidfile);
void cloexec_fds_from(int);
#endif #endif

View File

@@ -1,5 +1,5 @@
executable('start-stop-daemon', executable('start-stop-daemon',
['start-stop-daemon.c', 'pipes.c', misc_c, schedules_c, ['start-stop-daemon.c', pipes_c, misc_c, schedules_c,
selinux_c, usage_c, version_h], selinux_c, usage_c, version_h],
c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_cap_flags, cc_selinux_flags], c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_cap_flags, cc_selinux_flags],
link_with: [libeinfo, librc], link_with: [libeinfo, librc],

View File

@@ -1098,12 +1098,7 @@ int main(int argc, char **argv)
|| rc_yesno(getenv("EINFO_QUIET"))) || rc_yesno(getenv("EINFO_QUIET")))
dup2(stderr_fd, STDERR_FILENO); dup2(stderr_fd, STDERR_FILENO);
#ifdef HAVE_CLOSEFROM cloexec_fds_from(3);
closefrom(3);
#else
for (i = getdtablesize() - 1; i >= 3; --i)
close(i);
#endif
if (scheduler != NULL) { if (scheduler != NULL) {
int scheduler_index; int scheduler_index;

View File

@@ -1,5 +1,5 @@
executable('supervise-daemon', executable('supervise-daemon',
['supervise-daemon.c', misc_c, plugin_c, schedules_c, usage_c, version_h], ['supervise-daemon.c', pipes_c, misc_c, plugin_c, schedules_c, usage_c, version_h],
c_args : [cc_branding_flags, cc_pam_flags, cc_cap_flags, cc_selinux_flags], c_args : [cc_branding_flags, cc_pam_flags, cc_cap_flags, cc_selinux_flags],
link_with: [libeinfo, librc], link_with: [libeinfo, librc],
dependencies: [dl_dep, pam_dep, cap_dep, util_dep, selinux_dep], dependencies: [dl_dep, pam_dep, cap_dep, util_dep, selinux_dep],

View File

@@ -22,11 +22,6 @@
#define ONE_SECOND 1000000000 #define ONE_SECOND 1000000000
#define ONE_MS 1000000 #define ONE_MS 1000000
#ifdef HAVE_CLOSE_RANGE_CLOEXEC
/* For close_range() */
# define _GNU_SOURCE
#endif
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <getopt.h> #include <getopt.h>
@@ -67,6 +62,7 @@ static struct pam_conv conv = { NULL, NULL};
#include "queue.h" #include "queue.h"
#include "rc.h" #include "rc.h"
#include "misc.h" #include "misc.h"
#include "pipes.h"
#include "plugin.h" #include "plugin.h"
#include "schedules.h" #include "schedules.h"
#include "_usage.h" #include "_usage.h"
@@ -84,6 +80,8 @@ enum {
LONGOPT_OOM_SCORE_ADJ, LONGOPT_OOM_SCORE_ADJ,
LONGOPT_NO_NEW_PRIVS, LONGOPT_NO_NEW_PRIVS,
LONGOPT_SECBITS, LONGOPT_SECBITS,
LONGOPT_STDERR_LOGGER,
LONGOPT_STDOUT_LOGGER,
}; };
const char *applet = NULL; const char *applet = NULL;
@@ -115,6 +113,8 @@ const struct option longopts[] = {
{ "user", 1, NULL, 'u'}, { "user", 1, NULL, 'u'},
{ "stdout", 1, NULL, '1'}, { "stdout", 1, NULL, '1'},
{ "stderr", 1, NULL, '2'}, { "stderr", 1, NULL, '2'},
{ "stdout-logger",1, NULL, LONGOPT_STDOUT_LOGGER},
{ "stderr-logger",1, NULL, LONGOPT_STDERR_LOGGER},
{ "reexec", 0, NULL, '3'}, { "reexec", 0, NULL, '3'},
longopts_COMMON longopts_COMMON
}; };
@@ -143,6 +143,8 @@ const char * const longopts_help[] = {
"Change the process user", "Change the process user",
"Redirect stdout to file", "Redirect stdout to file",
"Redirect stderr to file", "Redirect stderr to file",
"Redirect stdout to process",
"Redirect stderr to process",
"reexec (used internally)", "reexec (used internally)",
longopts_help_COMMON longopts_help_COMMON
}; };
@@ -165,6 +167,8 @@ static int stdout_fd;
static int stderr_fd; static int stderr_fd;
static char *redirect_stderr = NULL; static char *redirect_stderr = NULL;
static char *redirect_stdout = NULL; static char *redirect_stdout = NULL;
static char *stderr_process = NULL;
static char *stdout_process = NULL;
#ifdef TIOCNOTTY #ifdef TIOCNOTTY
static int tty_fd = -1; static int tty_fd = -1;
#endif #endif
@@ -554,6 +558,12 @@ RC_NORETURN static void child_process(char *exec, char **argv)
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));
} else if (stdout_process) {
stdout_fd = rc_pipe_command(stdout_process);
if (stdout_fd == -1)
eerrorx("%s: unable to open the logging process"
" for stdout `%s': %s",
applet, stdout_process, strerror(errno));
} }
if (redirect_stderr) { if (redirect_stderr) {
if ((stderr_fd = open(redirect_stderr, if ((stderr_fd = open(redirect_stderr,
@@ -562,19 +572,22 @@ RC_NORETURN static void child_process(char *exec, char **argv)
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));
} else if (stderr_process) {
stderr_fd = rc_pipe_command(stderr_process);
if (stderr_fd == -1)
eerrorx("%s: unable to open the logging process"
" for stderr `%s': %s",
applet, stderr_process, strerror(errno));
} }
dup2(stdin_fd, STDIN_FILENO); dup2(stdin_fd, STDIN_FILENO);
if (redirect_stdout || rc_yesno(getenv("EINFO_QUIET"))) if (redirect_stdout || stdout_process || rc_yesno(getenv("EINFO_QUIET")))
dup2(stdout_fd, STDOUT_FILENO); dup2(stdout_fd, STDOUT_FILENO);
if (redirect_stderr || rc_yesno(getenv("EINFO_QUIET"))) if (redirect_stderr || stderr_process || rc_yesno(getenv("EINFO_QUIET")))
dup2(stderr_fd, STDERR_FILENO); dup2(stderr_fd, STDERR_FILENO);
#ifdef HAVE_CLOSE_RANGE_CLOEXEC cloexec_fds_from(3);
if (close_range(3, UINT_MAX, CLOSE_RANGE_CLOEXEC) < 0)
#endif
for (i = getdtablesize() - 1; i >= 3; --i)
fcntl(i, F_SETFD, FD_CLOEXEC);
cmdline = make_cmdline(argv); cmdline = make_cmdline(argv);
syslog(LOG_INFO, "Child command line: %s", cmdline); syslog(LOG_INFO, "Child command line: %s", cmdline);
free(cmdline); free(cmdline);
@@ -1047,6 +1060,14 @@ int main(int argc, char **argv)
reexec = true; reexec = true;
break; break;
case LONGOPT_STDOUT_LOGGER: /* --stdout-logger "command to run for stdout logging" */
stdout_process = optarg;
break;
case LONGOPT_STDERR_LOGGER: /* --stderr-logger "command to run for stderr logging" */
stderr_process = optarg;
break;
case_RC_COMMON_GETOPT case_RC_COMMON_GETOPT
} }

View File

@@ -1,50 +1,49 @@
Using supervise-daemon # Using supervise-daemon
======================
Beginning with OpenRC-0.21 we have our own daemon supervisor, Beginning with OpenRC-0.21 we have our own daemon supervisor,
supervise-daemon., which can start a daemon and restart it if it `supervise-daemon`, which can start a daemon and restart it if it
terminates unexpectedly. terminates unexpectedly.
The following is a brief guide on using this capability. The following is a brief guide on using this capability.
* Use Default start, stop and status functions * **Use Default start, stop and status functions**.
If you write your own start, stop and status functions in your service 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 script, none of this will work. You must allow OpenRC to use the default
functions. functions.
* Daemons must not fork * **Daemons must not fork**.
Any daemon that you would like to have monitored by supervise-daemon Any daemon that you would like to have monitored by `supervise-daemon`
must not fork. Instead, it must stay in the foreground. If the daemon must not fork. Instead, it must stay in the foreground. If the daemon
forks, the supervisor will be unable to monitor it. forks, the supervisor will be unable to monitor it.
If the daemon can be configured to not fork, this should be done in the 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 daemon's configuration file, or by adding a command line option that
instructs it not to fork to the command_args_foreground variable shown instructs it not to fork to the `command_args_foreground` variable shown
below. below.
# Health Checks ## Health checks
Health checks are a way to make sure a service monitored by Health checks are a way to make sure a service monitored by
supervise-daemon stays healthy. To configure a health check for a `supervise-daemon` stays healthy. To configure a health check for a
service, you need to write a healthcheck() function, and optionally an service, you need to write a `healthcheck()` function, and optionally an
unhealthy() function in the service script. Also, you will need to set `unhealthy()` function in the service script. Also, you will need to set
the healthcheck_timer and optionally healthcheck_delay variables. the `healthcheck_timer` and optionally `healthcheck_delay` variables.
## healthcheck() function ### healthcheck() function
The healthcheck() function is run repeatedly based on the settings of The `healthcheck()` function is run repeatedly based on the settings of
the healthcheck_* variables. This function should return zero if the the `healthcheck_*` variables. This function should return zero if the
service is currently healthy or non-zero otherwise. service is currently healthy or non-zero otherwise.
## unhealthy() function ### unhealthy() function
If the healthcheck() function returns non-zero, the unhealthy() function If the `healthcheck()` function returns non-zero, the `unhealthy()` function
is run, then the service is restarted. Since the service will be is run, then the service is restarted. Since the service will be
restarted by the supervisor, the unhealthy function should not try to restarted by the supervisor, the unhealthy function should not try to
restart it; the purpose of the function is to allow any cleanup tasks restart it; the purpose of the function is to allow any cleanup tasks
other than restarting the service to be run. other than restarting the service to be run.
# Variable Settings ## Variable settings
The most important setting is the supervisor variable. At the top of The most important setting is the supervisor variable. At the top of
your service script, you should set this variable as follows: your service script, you should set this variable as follows:
@@ -70,7 +69,7 @@ healthcheck_delay=seconds
``` ```
This is the delay, in seconds, before the first health check is run. This is the delay, in seconds, before the first health check is run.
If it is not set, we use the value of healthcheck_timer. If it is not set, we use the value of `healthcheck_timer`.
```sh ```sh
healthcheck_timer=seconds healthcheck_timer=seconds
@@ -99,13 +98,13 @@ The default is 10. 0 means unlimited.
respawn_period=seconds respawn_period=seconds
``` ```
This works in conjunction with respawn_max and respawn_delay above to This works in conjunction with `respawn_max` and `respawn_delay` above to
decide if a process should not be respawned for some reason. decide if a process should not be respawned for some reason.
For example, if respawn period is 10 and respawn_max is 2, the process For example, if respawn period is 10 and `respawn_max` is 2, the process
would need to die 3 times within 10 seconds to no longer be respawned. would need to die 3 times within 10 seconds to no longer be respawned.
Note that respawn_delay will delay all of this, so in the above scenario Note that `respawn_delay` will delay all of this, so in the above scenario
a respawn_delay of greater than 5 will cause infinite respawns. a `respawn_delay` of greater than 5 will cause infinite respawns.
By default, this is unset and respawn_max applies to the entire lifetime By default, this is unset and `respawn_max` applies to the entire lifetime
of the service. of the service.

View File

@@ -11,8 +11,7 @@ sysvinit="$4"
if [ "${os}" != Linux ]; then if [ "${os}" != Linux ]; then
install -d "${DESTDIR}/${rc_libexecdir}"/init.d install -d "${DESTDIR}/${rc_libexecdir}"/init.d
fi fi
install -d "${DESTDIR}/${rc_libexecdir}"/tmp
install -m 644 "${MESON_BUILD_ROOT}/src/shared/version" "${DESTDIR}/${rc_libexecdir}" install -m 644 "${MESON_BUILD_ROOT}/src/shared/version" "${DESTDIR}/${rc_libexecdir}"
if [ "${os}" = Linux ] && [ "${sysvinit}" = yes ]; then if [ "${os}" = Linux ] && [ "${sysvinit}" = yes ]; then
ln -s openrc-init "${DESTDIR}/${sbindir}"/init ln -sf openrc-init "${DESTDIR}/${sbindir}"/init
fi fi