Compare commits
	
		
			42 Commits
		
	
	
		
			0.48
			...
			artix-conf
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9cabf69684 | |||
| db5559bb50 | |||
|   | 3d30b6fdda | ||
|   | 4574b5d8e4 | ||
|   | 6b42019697 | ||
|   | 42408e7488 | ||
|   | 957140cb78 | ||
|   | 536794dfad | ||
|   | 7ac2080e31 | ||
|   | 12e1e88475 | ||
|   | c45fe9fba5 | ||
|   | 961c479e1d | ||
|   | f9c92d7822 | ||
|   | 97689d6c44 | ||
|   | 439cce426d | ||
|   | bfdafe4463 | ||
|   | 179ff285ca | ||
|   | f9bbbfbf4b | ||
|   | 59a175541d | ||
|   | 65b13eb86f | ||
|   | fda9dcd1f2 | ||
|   | 6f180e9424 | ||
|   | 88e5d98d05 | ||
|   | 1433552435 | ||
|   | 554ccab718 | ||
|   | 228b3c6c99 | ||
|   | 965de92b37 | ||
|   | b85d771e1f | ||
|   | cf9286d2d8 | ||
|   | 9934e9f96e | ||
|   | f1e5510ccf | ||
|   | 1b72c3a7ab | ||
|   | c4785f1b99 | ||
|   | e447562aaa | ||
|   | c199c5cf6e | ||
|   | 5bfb592d75 | ||
|   | b2c4eb97b5 | ||
|   | e740913fcb | ||
|   | 1bc34a39cd | ||
|   | c1cd3c9830 | ||
|   | 86efc43d0e | ||
|   | cd53239701 | 
| @@ -4,8 +4,8 @@ | ||||
| test_task: | ||||
|   freebsd_instance: | ||||
|     matrix: | ||||
|       image: freebsd-13-1-release-amd64 | ||||
|       image: freebsd-12-4-release-amd64 | ||||
|       image: freebsd-13-2-release-amd64 | ||||
|       image: freebsd-13-3-release-amd64 | ||||
|   env: | ||||
|     OS: FreeBSD | ||||
|   procfs_script: > | ||||
|   | ||||
							
								
								
									
										48
									
								
								NEWS.md
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								NEWS.md
									
									
									
									
									
								
							| @@ -4,6 +4,54 @@ OpenRC NEWS | ||||
| This file will contain a list of notable changes for each release. Note | ||||
| 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 | ||||
|  | ||||
| This release is a maintenance release; it has no user-facing changes. | ||||
|   | ||||
| @@ -92,13 +92,11 @@ _rc_service() | ||||
| 			return 0 | ||||
| 		elif [[ ${COMP_CWORD} -eq 2 ]] && [[ ${prev} != -* ]]; then # if second word typed and we didn't type in a function | ||||
| 			rc-service --exists "$prev" || return | ||||
| 			shopt -s extglob | ||||
| 			while read -r _ line; do | ||||
| 				if [[ $line == +([[:alnum:]_]):* ]]; then | ||||
| 					opts+="${line%%:*} " | ||||
| 				fi | ||||
| 			done < <(rc-service "$prev" describe 2>&1) | ||||
| 			shopt -u extglob | ||||
| 			COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) | ||||
| 			return 0 | ||||
| 		fi | ||||
|   | ||||
							
								
								
									
										2
									
								
								conf.d/cgroups
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								conf.d/cgroups
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| # override cgroup mount options | ||||
| #cgroup_opts=nodev,noexec,nosuid | ||||
							
								
								
									
										11
									
								
								etc/rc.conf
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								etc/rc.conf
									
									
									
									
									
								
							| @@ -19,7 +19,7 @@ | ||||
| # If not specified we use $SHELL, otherwise the one specified in /etc/passwd, | ||||
| # otherwise /bin/sh | ||||
| # Linux users could specify /sbin/sulogin | ||||
| #rc_shell=/bin/sh | ||||
| rc_shell=/usr/bin/sulogin | ||||
|  | ||||
| # Do we allow any started service in the runlevel to satisfy the dependency | ||||
| # or do we want all of them regardless of state? For example, if net.eth0 | ||||
| @@ -48,7 +48,7 @@ | ||||
| # /var/log/rc.log | ||||
| # NOTE: Linux systems require the devfs service to be started before | ||||
| # logging can take place and as such cannot log the sysinit runlevel. | ||||
| #rc_logger="NO" | ||||
| rc_logger="YES" | ||||
|  | ||||
| # Through rc_log_path you can specify a custom log file. | ||||
| # The default value is: /var/log/rc.log | ||||
| @@ -89,7 +89,7 @@ | ||||
| # There variables are shared between many init scripts | ||||
|  | ||||
| # Set unicode to NO to turn off unicode support for keyboards and screens. | ||||
| #unicode="YES" | ||||
| unicode="YES" | ||||
|  | ||||
| # This is how long fuser should wait for a remote server to respond. The | ||||
| # default is 60 seconds, but  it can be adjusted here. | ||||
| @@ -199,7 +199,10 @@ rc_tty_number=12 | ||||
| # 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 | ||||
| #rc_cgroup_mode="hybrid" | ||||
| rc_cgroup_mode="unified" | ||||
|  | ||||
| # override cgroup controller name | ||||
| rc_cgroup_name="artix" | ||||
|  | ||||
| # This is a list of controllers which should be enabled for cgroups version 2 | ||||
| # when hybrid mode is being used. | ||||
|   | ||||
| @@ -11,7 +11,9 @@ | ||||
|  | ||||
| description="Mount the control groups." | ||||
|  | ||||
| cgroup_opts=nodev,noexec,nosuid | ||||
| : "${cgroup_opts:="nodev,noexec,nosuid"}" | ||||
|  | ||||
| rc_cgroup_name=${rc_cgroup_name:-openrc} | ||||
|  | ||||
| depend() | ||||
| { | ||||
| @@ -29,13 +31,13 @@ cgroup1_base() | ||||
| 		eend $? | ||||
| 	fi | ||||
|  | ||||
| 	if ! mountinfo -q /sys/fs/cgroup/openrc; then | ||||
| 	if ! mountinfo -q /sys/fs/cgroup/"${rc_cgroup_name}"; then | ||||
| 		local agent="${RC_LIBEXECDIR}/sh/cgroup-release-agent.sh" | ||||
| 		mkdir /sys/fs/cgroup/openrc | ||||
| 		mkdir /sys/fs/cgroup/"${rc_cgroup_name}" | ||||
| 		mount -n -t cgroup \ | ||||
| 			-o none,${cgroup_opts},name=openrc,release_agent="$agent" \ | ||||
| 			openrc /sys/fs/cgroup/openrc | ||||
| 		printf 1 > /sys/fs/cgroup/openrc/notify_on_release | ||||
| 			-o none,${cgroup_opts},name="${rc_cgroup_name}",release_agent="$agent" \ | ||||
| 			"${rc_cgroup_name}" /sys/fs/cgroup/"${rc_cgroup_name}" | ||||
| 		printf 1 > /sys/fs/cgroup/"${rc_cgroup_name}"/notify_on_release | ||||
| 	fi | ||||
| 	return 0 | ||||
| } | ||||
| @@ -74,6 +76,7 @@ cgroup2_base() | ||||
| 	mkdir -p "${base}" | ||||
| 	mount -t cgroup2 none -o "${cgroup_opts},nsdelegate" "${base}" 2> /dev/null || | ||||
| 		mount -t cgroup2 none -o "${cgroup_opts}" "${base}" | ||||
|  mkdir -p ${base}/"${rc_cgroup_name}" | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| @@ -81,13 +84,13 @@ cgroup2_controllers() | ||||
| { | ||||
| 	grep -qw cgroup2 /proc/filesystems || return 0 | ||||
| 	local active cgroup_path x y | ||||
| 	cgroup_path="$(cgroup2_find_path)" | ||||
| 	cgroup_path="$(cgroup2_find_path)/${rc_cgroup_name}" | ||||
| 	[ -z "${cgroup_path}" ] && return 0 | ||||
| 	[ ! -e "${cgroup_path}/cgroup.controllers" ] && return 0 | ||||
| 	[ ! -e "${cgroup_path}/cgroup.subtree_control" ]&& return 0 | ||||
| 	read -r active < "${cgroup_path}/cgroup.controllers" | ||||
| 	for x in ${active}; do | ||||
| 	case "$rc_cgroup_mode" in | ||||
| 	case "${rc_cgroup_mode:-unified}" in | ||||
| 		unified) | ||||
| 			echo "+${x}"  > "${cgroup_path}/cgroup.subtree_control" | ||||
| 			;; | ||||
| @@ -128,7 +131,7 @@ cgroups_unified() | ||||
|  | ||||
| mount_cgroups() | ||||
| { | ||||
| 	case "${rc_cgroup_mode:-hybrid}" in | ||||
| 	case "${rc_cgroup_mode:-unified}" in | ||||
| 	hybrid) cgroups_hybrid ;; | ||||
| 	legacy) cgroups_legacy ;; | ||||
| 	unified) cgroups_unified ;; | ||||
|   | ||||
| @@ -158,13 +158,6 @@ is true. | ||||
| prefixes the string | ||||
| .Fa prefix | ||||
| 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 | ||||
| .Va EINFO_QUIET | ||||
| when set to true makes the | ||||
|   | ||||
| @@ -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. | ||||
| .It Fl v , -verbose | ||||
| 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 | ||||
| Echo a . to the console for each second elapsed whilst waiting. | ||||
| .El | ||||
|   | ||||
| @@ -158,6 +158,23 @@ The logfile can also be a named pipe. | ||||
| The same thing as | ||||
| .Fl 1 , -stdout | ||||
| 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 | ||||
| Start the daemon with the listed inheritable, ambient and bounding capabilities. | ||||
| The format is the same as in cap_iab(3). | ||||
|   | ||||
							
								
								
									
										32
									
								
								meson.build
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								meson.build
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| project('OpenRC', 'c', | ||||
|   version : '0.48', | ||||
|   version : '0.54', | ||||
|   license: 'BSD-2', | ||||
|   default_options : [ | ||||
|     'c_std=c99', | ||||
| @@ -83,16 +83,9 @@ else | ||||
|   pkg_prefix = option_pkg_prefix | ||||
| 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_default = fs.is_symlink('/bin') ? '/usr' : '/' | ||||
| if rootprefix == '' | ||||
| rootprefix = rootprefix_default | ||||
| rootprefix = '/' | ||||
| endif | ||||
|  | ||||
| bindir = rootprefix / get_option('bindir') | ||||
| @@ -133,15 +126,6 @@ else | ||||
|   cc_selinux_flags = [] | ||||
| 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') | ||||
|   cc_debug_flags = ['-DRC_DEBUG'] | ||||
| 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') | ||||
| endif | ||||
|  | ||||
| if cc.has_function('closefrom', prefix: '#define _GNU_SOURCE\n#include <unistd.h>') | ||||
|   add_project_arguments('-DHAVE_CLOSEFROM', language: 'c') | ||||
| if cc.has_function('close_range', prefix: '#define _GNU_SOURCE\n#include <unistd.h>') | ||||
|   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 | ||||
| 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') | ||||
|   add_project_arguments('-DHAVE_CLOSE_RANGE_CLOEXEC', language: 'c') | ||||
|  | ||||
| if cc.has_function('strlcpy', prefix: '#define _GNU_SOURCE\n#include <string.h>') | ||||
|   add_project_arguments('-DHAVE_STRLCPY', language: 'c') | ||||
| endif | ||||
|  | ||||
| incdir = include_directories('src/shared') | ||||
|   | ||||
| @@ -26,14 +26,7 @@ option('selinux', type : 'feature', value : 'auto', | ||||
|   description : 'enable SELinux support') | ||||
| option('shell', type : 'string', value : '/bin/sh', | ||||
|   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, | ||||
|   description : 'enable SysVinit compatibility (linux only)') | ||||
| option('termcap', type : 'combo', | ||||
|   choices : | ||||
|     [ '', 'ncurses', 'termcap' ], | ||||
|   description : 'the termcap library to use') | ||||
| option('zsh-completions', type : 'boolean', | ||||
|   description : 'install zsh completions') | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| # This file may not be copied, modified, propagated, or distributed | ||||
| #    except according to the terms contained in the LICENSE file. | ||||
|  | ||||
| cgroup=/sys/fs/cgroup/openrc | ||||
| cgroup=/sys/fs/cgroup/"${rc_cgroup_name:-openrc}" | ||||
| PATH=/bin:/usr/bin:/sbin:/usr/sbin | ||||
| if [ -d ${cgroup}/"$1" ]; then | ||||
| 	rmdir ${cgroup}/"$1" | ||||
|   | ||||
| @@ -11,6 +11,8 @@ | ||||
| extra_stopped_commands="${extra_stopped_commands} cgroup_cleanup" | ||||
| description_cgroup_cleanup="Kill all processes in the cgroup" | ||||
|  | ||||
| cg2_sv_name="${RC_SVCNAME}.sv" | ||||
|  | ||||
| cgroup_find_path() | ||||
| { | ||||
| 	local OIFS name dir result | ||||
| @@ -35,9 +37,9 @@ cgroup_get_pids() | ||||
| 	cgroup_pids= | ||||
| 	cgroup_procs="$(cgroup2_find_path)" | ||||
| 	if [ -n "${cgroup_procs}" ]; then | ||||
| 		cgroup_procs="${cgroup_procs}/${RC_SVCNAME}/cgroup.procs" | ||||
| 		cgroup_procs="${cgroup_procs}/${rc_cgroup_name}/${cg2_sv_name}/cgroup.procs" | ||||
| 	else | ||||
| 		cgroup_procs="/sys/fs/cgroup/openrc/${RC_SVCNAME}/tasks" | ||||
| 		cgroup_procs="/sys/fs/cgroup/"${rc_cgroup_name}"/${RC_SVCNAME}/tasks" | ||||
| 	fi | ||||
| 	[ -f "${cgroup_procs}" ] || return 0 | ||||
| 	while read -r p; do | ||||
| @@ -51,7 +53,7 @@ cgroup_running() | ||||
| { | ||||
| 	[ -d "/sys/fs/cgroup/unified/${RC_SVCNAME}" ] || | ||||
| 			[ -d "/sys/fs/cgroup/${RC_SVCNAME}" ] || | ||||
| 			[ -d "/sys/fs/cgroup/openrc/${RC_SVCNAME}" ] | ||||
| 			[ -d "/sys/fs/cgroup/"${rc_cgroup_name}"/${RC_SVCNAME}" ] | ||||
| } | ||||
|  | ||||
| cgroup_set_values() | ||||
| @@ -61,7 +63,7 @@ cgroup_set_values() | ||||
| 	local controller h | ||||
| 	controller="$1" | ||||
| 	h=$(cgroup_find_path "$1") | ||||
| 	cgroup="/sys/fs/cgroup/${1}${h}openrc_${RC_SVCNAME}" | ||||
| 	cgroup="/sys/fs/cgroup/${1}${h}"${rc_cgroup_name}"_${RC_SVCNAME}" | ||||
| 	[ -d "$cgroup" ] || mkdir -p "$cgroup" | ||||
|  | ||||
| 	set -- $2 | ||||
| @@ -108,7 +110,7 @@ cgroup_add_service() | ||||
| 		[ -w "${d}"/tasks ] && printf "%d" 0 > "${d}"/tasks | ||||
| 	done | ||||
|  | ||||
| 	openrc_cgroup=/sys/fs/cgroup/openrc | ||||
| 	openrc_cgroup=/sys/fs/cgroup/"${rc_cgroup_name}" | ||||
| 	if [ -d "$openrc_cgroup" ]; then | ||||
| 		cgroup="$openrc_cgroup/$RC_SVCNAME" | ||||
| 		mkdir -p "$cgroup" | ||||
| @@ -154,7 +156,7 @@ cgroup_set_limits() | ||||
| cgroup2_find_path() | ||||
| { | ||||
| 	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" ;; | ||||
| 			unified) printf "/sys/fs/cgroup" ;; | ||||
| 		esac | ||||
| @@ -167,7 +169,7 @@ cgroup2_remove() | ||||
| 	local cgroup_path rc_cgroup_path | ||||
| 	cgroup_path="$(cgroup2_find_path)" | ||||
| 	[ -z "${cgroup_path}" ] && return 0 | ||||
| 	rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}" | ||||
| 	rc_cgroup_path="${cgroup_path}/${rc_cgroup_name}/${cg2_sv_name}" | ||||
| 	[ ! -d "${rc_cgroup_path}" ] || | ||||
| 		[ ! -e "${rc_cgroup_path}"/cgroup.events ] && | ||||
| 		return 0 | ||||
| @@ -191,7 +193,7 @@ cgroup2_set_limits() | ||||
| 	cgroup_path="$(cgroup2_find_path)" | ||||
| 	[ -z "${cgroup_path}" ] && return 0 | ||||
| 	mountinfo -q "${cgroup_path}"|| return 0 | ||||
| 	rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}" | ||||
| 	rc_cgroup_path="${cgroup_path}/${rc_cgroup_name}/${cg2_sv_name}" | ||||
| 	[ ! -d "${rc_cgroup_path}" ] && mkdir "${rc_cgroup_path}" | ||||
| 	[ -f "${rc_cgroup_path}"/cgroup.procs ] && | ||||
| 		printf 0 > "${rc_cgroup_path}"/cgroup.procs | ||||
| @@ -210,7 +212,7 @@ cgroup2_kill_cgroup() { | ||||
| 	local cgroup_path | ||||
| 	cgroup_path="$(cgroup2_find_path)" | ||||
| 	[ -z "${cgroup_path}" ] && return 1 | ||||
| 	rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}" | ||||
| 	rc_cgroup_path="${cgroup_path}/${rc_cgroup_name}/${cg2_sv_name}" | ||||
| 	if [ -f "${rc_cgroup_path}"/cgroup.kill ]; then | ||||
| 		printf "%d" 1 > "${rc_cgroup_path}"/cgroup.kill | ||||
| 	fi | ||||
|   | ||||
| @@ -30,6 +30,8 @@ supervise_start() | ||||
| 		${chroot:+--chroot} $chroot \ | ||||
| 		${output_log+--stdout} ${output_log} \ | ||||
| 		${error_log+--stderr} $error_log \ | ||||
| 		${output_logger:+--stdout-logger \"$output_logger\"} \ | ||||
| 		${error_logger:+--stderr-logger \"$error_logger\"} \ | ||||
| 		${pidfile:+--pidfile} $pidfile \ | ||||
| 		${respawn_delay:+--respawn-delay} $respawn_delay \ | ||||
| 		${respawn_max:+--respawn-max} $respawn_max \ | ||||
| @@ -38,7 +40,7 @@ supervise_start() | ||||
| 		${healthcheck_timer:+--healthcheck-timer} $healthcheck_timer \ | ||||
| 		${capabilities+--capabilities} "$capabilities" \ | ||||
| 		${secbits:+--secbits} "$secbits" \ | ||||
| 		${no_new_privs:+--no_new_privs} \ | ||||
| 		${no_new_privs:+--no-new-privs} \ | ||||
| 		${command_user+--user} $command_user \ | ||||
| 		${umask+--umask} $umask \ | ||||
| 		${supervise_daemon_args-${start_stop_daemon_args}} \ | ||||
|   | ||||
| @@ -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 | ||||
|  * https://github.com/OpenRC/openrc/blob/HEAD/AUTHORS | ||||
|  * | ||||
| @@ -26,9 +26,6 @@ | ||||
| #include <string.h> | ||||
| #include <strings.h> | ||||
| #include <syslog.h> | ||||
| #ifdef HAVE_TERMCAP | ||||
| # include <termcap.h> | ||||
| #endif | ||||
| #include <unistd.h> | ||||
|  | ||||
| #include "einfo.h" | ||||
| @@ -53,8 +50,7 @@ | ||||
| #define HILITE                  6 | ||||
| #define BRACKET                 4 | ||||
|  | ||||
| /* We fallback to these escape codes if termcap isn't available | ||||
|  * like say /usr isn't mounted */ | ||||
| /* ANSI escape codes which mimic termcap */ | ||||
| #define AF "\033[3%dm" | ||||
| #define CE "\033[K" | ||||
| #define CH "\033[%dC" | ||||
| @@ -97,13 +93,7 @@ static char *goto_column = NULL; | ||||
| static const char *term = NULL; | ||||
| static bool term_is_cons25 = false; | ||||
|  | ||||
| /* Termcap buffers and pointers | ||||
|  * 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 | ||||
| /* Hardcoded list of colour capable terms | ||||
|  * Only terminals without "color" in the name need to be explicitly listed */ | ||||
| static const char *const color_terms[] = { | ||||
| 	"Eterm", | ||||
| @@ -142,13 +132,11 @@ static const char *const color_terms[] = { | ||||
| 	"wsvt25", | ||||
| 	"xterm", | ||||
| 	"xterm-debian", | ||||
| 	"xterm-kitty", | ||||
| 	NULL | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| /* strlcat and strlcpy are nice, shame glibc does not define them */ | ||||
| #ifdef __GLIBC__ | ||||
| #  if !defined (__UCLIBC__) && !defined (__dietlibc__) | ||||
| #ifndef HAVE_STRLCPY | ||||
| static size_t | ||||
| strlcat(char *dst, const char *src, size_t size) | ||||
| { | ||||
| @@ -176,7 +164,6 @@ strlcat(char *dst, const char *src, size_t size) | ||||
|  | ||||
| 	return dst_n + (s - src); | ||||
| } | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| static bool | ||||
| @@ -239,7 +226,6 @@ is_verbose(void) | ||||
| } | ||||
|  | ||||
| /* Fake tgoto call - very crapy, but works for our needs */ | ||||
| #ifndef HAVE_TERMCAP | ||||
| static char * | ||||
| tgoto(const char *cap, int col, int line) | ||||
| { | ||||
| @@ -302,7 +288,6 @@ tgoto(const char *cap, int col, int line) | ||||
| 	*p = '\0'; | ||||
| 	return buf; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static bool | ||||
| colour_terminal(FILE * EINFO_RESTRICT f) | ||||
| @@ -315,9 +300,6 @@ colour_terminal(FILE * EINFO_RESTRICT f) | ||||
| 	const char *bold; | ||||
| 	char tmp[100]; | ||||
| 	unsigned int i = 0; | ||||
| #ifdef HAVE_TERMCAP | ||||
| 	char *bp; | ||||
| #endif | ||||
|  | ||||
| 	if (f && !isatty(fileno(f))) | ||||
| 		return false; | ||||
| @@ -339,65 +321,33 @@ colour_terminal(FILE * EINFO_RESTRICT f) | ||||
| 	if (strcmp(term, "cons25") == 0) | ||||
| 		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); | ||||
| 	} | ||||
| 	if (strstr(term, "color")) | ||||
| 		in_colour = 1; | ||||
|  | ||||
| 	/* 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")) | ||||
| 	while (color_terms[i] && in_colour != 1) { | ||||
| 		if (strcmp(color_terms[i], term) == 0) { | ||||
| 			in_colour = 1; | ||||
|  | ||||
| 		while (color_terms[i] && in_colour != 1) { | ||||
| 			if (strcmp(color_terms[i], term) == 0) { | ||||
| 				in_colour = 1; | ||||
| 			} | ||||
| 			i++; | ||||
| 		} | ||||
|  | ||||
| 		if (in_colour != 1) { | ||||
| 			in_colour = 0; | ||||
| 			return false; | ||||
| 		} | ||||
| #endif | ||||
| 		if (!_af) | ||||
| 			_af = AF; | ||||
| 		if (!_ce) | ||||
| 			_ce = CE; | ||||
| 		if (!_ch) | ||||
| 			_ch = CH; | ||||
| 		if (!_md) | ||||
| 			_md = MD; | ||||
| 		if (!_me) | ||||
| 			_me = ME; | ||||
| 		if (!_up) | ||||
| 			_up = UP; | ||||
| #ifdef HAVE_TERMCAP | ||||
| 		i++; | ||||
| 	} | ||||
|  | ||||
| 	if (!_af || !_ce || !_me || !_md || !_up) { | ||||
| 	if (in_colour != 1) { | ||||
| 		in_colour = 0; | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	/* Many termcap databases don't have ch or RI even though they | ||||
| 	 * do work */ | ||||
| 	if (!_af) | ||||
| 		_af = AF; | ||||
| 	if (!_ce) | ||||
| 		_ce = CE; | ||||
| 	if (!_ch) | ||||
| 		_ch = CH; | ||||
| #endif | ||||
| 	if (!_md) | ||||
| 		_md = MD; | ||||
| 	if (!_me) | ||||
| 		_me = ME; | ||||
| 	if (!_up) | ||||
| 		_up = UP; | ||||
|  | ||||
| 	/* Now setup our colours */ | ||||
| 	p = ebuffer; | ||||
|   | ||||
| @@ -1,9 +1,7 @@ | ||||
| libeinfo_version = '1' | ||||
|  | ||||
| libeinfo = library('einfo', ['libeinfo.c'], | ||||
|   c_args : termcap_flags, | ||||
|   include_directories : incdir, | ||||
|   dependencies : termcap_dep, | ||||
|   link_depends : 'einfo.map', | ||||
|   version : libeinfo_version, | ||||
|   install : true, | ||||
|   | ||||
| @@ -402,7 +402,7 @@ rc_service_daemon_set(const char *service, const char *exec, | ||||
| 	bool retval = false; | ||||
| 	DIR *dp; | ||||
| 	struct dirent *d; | ||||
| 	RC_STRINGLIST *match; | ||||
| 	RC_STRINGLIST *match, *renamelist; | ||||
| 	int i = 0; | ||||
| 	FILE *fp; | ||||
|  | ||||
| @@ -416,11 +416,17 @@ rc_service_daemon_set(const char *service, const char *exec, | ||||
| 	/* Regardless, erase any existing daemon info */ | ||||
| 	if ((dp = opendir(dirpath))) { | ||||
| 		match = _match_list(exec, argv, pidfile); | ||||
| 		renamelist = rc_stringlist_new(); | ||||
| 		while ((d = readdir(dp))) { | ||||
| 			if (d->d_name[0] == '.') | ||||
| 				continue; | ||||
|  | ||||
| 			xasprintf(&file, "%s/%s", dirpath, d->d_name); | ||||
| 			if (rc_stringlist_find(renamelist, file)) { | ||||
| 				free(file); | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			nfiles++; | ||||
|  | ||||
| 			if (!*oldfile) { | ||||
| @@ -432,11 +438,15 @@ rc_service_daemon_set(const char *service, const char *exec, | ||||
| 			} else { | ||||
| 				rename(file, 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); | ||||
| 		} | ||||
| 		closedir(dp); | ||||
| 		rc_stringlist_free(match); | ||||
| 		rc_stringlist_free(renamelist); | ||||
| 	} | ||||
|  | ||||
| 	/* Now store our daemon info */ | ||||
|   | ||||
| @@ -6,12 +6,3 @@ executable('openrc-run', | ||||
|   include_directories: [incdir, einfo_incdir, rc_incdir], | ||||
|   install: true, | ||||
|   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) | ||||
|   | ||||
| @@ -1097,7 +1097,6 @@ service_plugable(void) | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
| 	bool doneone = false; | ||||
| 	bool runscript = false; | ||||
| 	int retval, opt, depoptions = RC_DEP_TRACE; | ||||
| 	RC_STRING *svc; | ||||
| 	char *path = NULL; | ||||
| @@ -1115,8 +1114,6 @@ int main(int argc, char **argv) | ||||
| 	} | ||||
|  | ||||
| 	applet = basename_c(argv[0]); | ||||
| 	if (strcmp(applet, "runscript") == 0) | ||||
| 		runscript = true; | ||||
|  | ||||
| 	if (stat(argv[1], &stbuf) != 0) { | ||||
| 		fprintf(stderr, "openrc-run `%s': %s\n", | ||||
| @@ -1289,9 +1286,6 @@ int main(int argc, char **argv) | ||||
| 	applet_list = rc_stringlist_new(); | ||||
| 	rc_stringlist_add(applet_list, applet); | ||||
|  | ||||
| 	if (runscript) | ||||
| 		ewarn("%s uses runscript, please convert to openrc-run.", service); | ||||
|  | ||||
| 	/* Now run each option */ | ||||
| 	retval = EXIT_SUCCESS; | ||||
| 	while (optind < argc) { | ||||
|   | ||||
| @@ -6,12 +6,3 @@ executable('openrc', | ||||
|   include_directories: [incdir, einfo_incdir, rc_incdir], | ||||
|   install: true, | ||||
|   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) | ||||
|   | ||||
| @@ -527,7 +527,7 @@ runlevel_config(const char *service, const char *level) | ||||
| 	char *conf, *dir; | ||||
| 	bool retval; | ||||
|  | ||||
| 	dir = dirname(init); | ||||
| 	dir = dirname(dirname(init)); | ||||
| 	xasprintf(&conf, "%s/conf.d/%s.%s", dir, service, level); | ||||
| 	retval = exists(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++]; | ||||
| 	/* To make life easier, we only have the shutdown runlevel as | ||||
| 	 * nothing really needs to know that we're rebooting. | ||||
|   | ||||
| @@ -88,7 +88,7 @@ delete(const char *runlevel, const char *service) | ||||
|  | ||||
| 	errno = 0; | ||||
| 	if (rc_service_delete(runlevel, service)) { | ||||
| 		einfo("service %s removed from runlevel %s", | ||||
| 		einfo("service %s deleted from runlevel %s", | ||||
| 		    service, runlevel); | ||||
| 		return 1; | ||||
| 	} | ||||
| @@ -97,7 +97,7 @@ delete(const char *runlevel, const char *service) | ||||
| 		eerror("%s: service `%s' is not in the runlevel `%s'", | ||||
| 		    applet, service, runlevel); | ||||
| 	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)); | ||||
|  | ||||
| 	return retval; | ||||
| @@ -144,7 +144,7 @@ static int | ||||
| delstack(const char *runlevel, const char *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; | ||||
| 	} | ||||
|  | ||||
| @@ -152,7 +152,7 @@ delstack(const char *runlevel, const char *stack) | ||||
| 		eerror("%s: runlevel `%s' is not in the runlevel `%s'", | ||||
| 		    applet, stack, runlevel); | ||||
| 	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)); | ||||
|  | ||||
| 	return -1; | ||||
|   | ||||
| @@ -37,10 +37,8 @@ | ||||
|  | ||||
| #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) | ||||
|  | ||||
| #ifdef __GLIBC__ | ||||
| #  if !defined (__UCLIBC__) && !defined (__dietlibc__) | ||||
| #ifndef HAVE_STRLCPY | ||||
| #    define strlcpy(dst, src, size) snprintf(dst, size, "%s", src) | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| #ifndef timespecsub | ||||
|   | ||||
| @@ -10,6 +10,10 @@ schedules_c = files([ | ||||
|   'schedules.c', | ||||
|   ]) | ||||
|  | ||||
| pipes_c = files([ | ||||
| 	'pipes.c', | ||||
| 	]) | ||||
|  | ||||
| if selinux_dep.found() | ||||
|   selinux_c = files([ | ||||
|     'selinux.c', | ||||
|   | ||||
| @@ -15,10 +15,18 @@ | ||||
|  *    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 <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <limits.h> | ||||
| #ifdef HAVE_LINUX_CLOSE_RANGE_H | ||||
| #  include <linux/close_range.h> | ||||
| #endif | ||||
| #include <signal.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| @@ -26,6 +34,7 @@ | ||||
| #include <sys/file.h> | ||||
| #include <sys/time.h> | ||||
| #ifdef __linux__ | ||||
| #  include <sys/syscall.h> /* for close_range */ | ||||
| #  include <sys/sysinfo.h> | ||||
| #endif | ||||
| #include <sys/types.h> | ||||
| @@ -500,3 +509,30 @@ pid_t get_pid(const char *applet,const char *pidfile) | ||||
|  | ||||
| 	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); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -73,4 +73,6 @@ void from_time_t(char *time_string, time_t tv); | ||||
| time_t to_time_t(char *timestring); | ||||
| pid_t get_pid(const char *applet, const char *pidfile); | ||||
|  | ||||
| void cloexec_fds_from(int); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| 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], | ||||
|   c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_cap_flags, cc_selinux_flags], | ||||
|   link_with: [libeinfo, librc], | ||||
|   | ||||
| @@ -1098,12 +1098,7 @@ int main(int argc, char **argv) | ||||
| 				|| rc_yesno(getenv("EINFO_QUIET"))) | ||||
| 			dup2(stderr_fd, STDERR_FILENO); | ||||
|  | ||||
| #ifdef HAVE_CLOSEFROM | ||||
| 		closefrom(3); | ||||
| #else | ||||
| 		for (i = getdtablesize() - 1; i >= 3; --i) | ||||
| 			close(i); | ||||
| #endif | ||||
| 		cloexec_fds_from(3); | ||||
|  | ||||
| 		if (scheduler != NULL) { | ||||
| 			int scheduler_index; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| 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], | ||||
|   link_with: [libeinfo, librc], | ||||
|   dependencies: [dl_dep, pam_dep, cap_dep, util_dep, selinux_dep], | ||||
|   | ||||
| @@ -22,11 +22,6 @@ | ||||
| #define ONE_SECOND    1000000000 | ||||
| #define ONE_MS           1000000 | ||||
|  | ||||
| #ifdef HAVE_CLOSE_RANGE_CLOEXEC | ||||
| /* For close_range() */ | ||||
| # define _GNU_SOURCE | ||||
| #endif | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <getopt.h> | ||||
| @@ -67,6 +62,7 @@ static struct pam_conv conv = { NULL, NULL}; | ||||
| #include "queue.h" | ||||
| #include "rc.h" | ||||
| #include "misc.h" | ||||
| #include "pipes.h" | ||||
| #include "plugin.h" | ||||
| #include "schedules.h" | ||||
| #include "_usage.h" | ||||
| @@ -84,6 +80,8 @@ enum { | ||||
|   LONGOPT_OOM_SCORE_ADJ, | ||||
|   LONGOPT_NO_NEW_PRIVS, | ||||
|   LONGOPT_SECBITS, | ||||
|   LONGOPT_STDERR_LOGGER, | ||||
|   LONGOPT_STDOUT_LOGGER, | ||||
| }; | ||||
|  | ||||
| const char *applet = NULL; | ||||
| @@ -115,6 +113,8 @@ const struct option longopts[] = { | ||||
| 	{ "user",         1, NULL, 'u'}, | ||||
| 	{ "stdout",       1, NULL, '1'}, | ||||
| 	{ "stderr",       1, NULL, '2'}, | ||||
| 	{ "stdout-logger",1, NULL, LONGOPT_STDOUT_LOGGER}, | ||||
| 	{ "stderr-logger",1, NULL, LONGOPT_STDERR_LOGGER}, | ||||
| 	{ "reexec",       0, NULL, '3'}, | ||||
| 	longopts_COMMON | ||||
| }; | ||||
| @@ -143,6 +143,8 @@ const char * const longopts_help[] = { | ||||
| 	"Change the process user", | ||||
| 	"Redirect stdout to file", | ||||
| 	"Redirect stderr to file", | ||||
| 	"Redirect stdout to process", | ||||
| 	"Redirect stderr to process", | ||||
| 	"reexec (used internally)", | ||||
| 	longopts_help_COMMON | ||||
| }; | ||||
| @@ -165,6 +167,8 @@ static int stdout_fd; | ||||
| static int stderr_fd; | ||||
| static char *redirect_stderr = NULL; | ||||
| static char *redirect_stdout = NULL; | ||||
| static char *stderr_process = NULL; | ||||
| static char *stdout_process = NULL; | ||||
| #ifdef TIOCNOTTY | ||||
| static int tty_fd = -1; | ||||
| #endif | ||||
| @@ -554,6 +558,12 @@ RC_NORETURN static void child_process(char *exec, char **argv) | ||||
| 			eerrorx("%s: unable to open the logfile" | ||||
| 				    " for stdout `%s': %s", | ||||
| 				    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 ((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" | ||||
| 			    " for stderr `%s': %s", | ||||
| 			    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); | ||||
| 	if (redirect_stdout || rc_yesno(getenv("EINFO_QUIET"))) | ||||
| 	if (redirect_stdout || stdout_process || rc_yesno(getenv("EINFO_QUIET"))) | ||||
| 		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); | ||||
|  | ||||
| #ifdef HAVE_CLOSE_RANGE_CLOEXEC | ||||
| 	if (close_range(3, UINT_MAX, CLOSE_RANGE_CLOEXEC) < 0) | ||||
| #endif | ||||
| 		for (i = getdtablesize() - 1; i >= 3; --i) | ||||
| 			fcntl(i, F_SETFD, FD_CLOEXEC); | ||||
| 	cloexec_fds_from(3); | ||||
|  | ||||
| 	cmdline = make_cmdline(argv); | ||||
| 	syslog(LOG_INFO, "Child command line: %s", cmdline); | ||||
| 	free(cmdline); | ||||
| @@ -1047,6 +1060,14 @@ int main(int argc, char **argv) | ||||
| 			reexec = true; | ||||
| 			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 | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -1,55 +1,54 @@ | ||||
| Using supervise-daemon | ||||
| ====================== | ||||
| # 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 | ||||
| `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 | ||||
| * **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 daemon that you would like to have monitored by supervise-daemon | ||||
| * **Daemons must not fork**. | ||||
|   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 | ||||
|   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 | ||||
|   instructs it not to fork to the `command_args_foreground` variable shown | ||||
|   below. | ||||
|  | ||||
| # Health Checks | ||||
| ## Health checks | ||||
|  | ||||
| Health checks are a way to make sure a service monitored by | ||||
| supervise-daemon stays healthy. To configure a health check for a | ||||
| service, you need to write a healthcheck() function, and optionally an | ||||
| unhealthy() function in the service script. Also, you will need to set | ||||
| the healthcheck_timer and optionally healthcheck_delay variables. | ||||
| `supervise-daemon` stays healthy. To configure a health check for a | ||||
| service, you need to write a `healthcheck()` function, and optionally an | ||||
| `unhealthy()` function in the service script. Also, you will need to set | ||||
| 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_* variables. This function should return zero if the | ||||
| The `healthcheck()` function is run repeatedly based on the settings of | ||||
| the `healthcheck_*` variables. This function should return zero if the | ||||
| 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 | ||||
| restarted by the supervisor, the unhealthy function should not try to | ||||
| restart it; the purpose of the function is to allow any cleanup tasks | ||||
| other than restarting the service to be run. | ||||
|  | ||||
| # Variable Settings | ||||
| ## Variable settings | ||||
|  | ||||
| The most important setting is the supervisor variable. At the top of | ||||
| your service script, you should set this variable as follows: | ||||
|  | ||||
| ``` sh | ||||
| ```sh | ||||
| supervisor=supervise-daemon | ||||
| ``` | ||||
|  | ||||
| @@ -57,29 +56,29 @@ 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: | ||||
|  | ||||
| ``` sh | ||||
| ```sh | ||||
| command_args_foreground="arguments" | ||||
| ``` | ||||
|  | ||||
| This 	should be used if the daemon you want to monitor | ||||
| This 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. | ||||
|  | ||||
| ``` sh | ||||
| ```sh | ||||
| healthcheck_delay=seconds | ||||
| ``` | ||||
|  | ||||
| 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 | ||||
| ``` | ||||
|  | ||||
| This is the  number of seconds between health checks. If it is not set, | ||||
| no health checks will be run. | ||||
|  | ||||
| ``` sh | ||||
| ```sh | ||||
| respawn_delay | ||||
| ``` | ||||
|  | ||||
| @@ -87,7 +86,7 @@ This is the number of seconds to delay before attempting to respawn a | ||||
| supervised process after it dies unexpectedly. | ||||
| The default is to respawn immediately. | ||||
|  | ||||
| ``` sh | ||||
| ```sh | ||||
| respawn_max=x | ||||
| ``` | ||||
|  | ||||
| @@ -95,17 +94,17 @@ This is the maximum number of times to respawn a supervised process | ||||
| during the given respawn period. | ||||
| The default is 10. 0 means unlimited. | ||||
|  | ||||
| ``` sh | ||||
| ```sh | ||||
| 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. | ||||
|  | ||||
| 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. | ||||
| 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. | ||||
| 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. | ||||
|  | ||||
| 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. | ||||
|   | ||||
| @@ -11,8 +11,7 @@ sysvinit="$4" | ||||
| if [ "${os}" != Linux ]; then | ||||
| 	install -d "${DESTDIR}/${rc_libexecdir}"/init.d | ||||
| fi | ||||
| install -d "${DESTDIR}/${rc_libexecdir}"/tmp | ||||
| install -m 644 "${MESON_BUILD_ROOT}/src/shared/version" "${DESTDIR}/${rc_libexecdir}" | ||||
| if [ "${os}" = Linux ] && [ "${sysvinit}" = yes ]; then | ||||
| 	ln -s openrc-init "${DESTDIR}/${sbindir}"/init | ||||
| 	ln -sf openrc-init "${DESTDIR}/${sbindir}"/init | ||||
| fi | ||||
|   | ||||
		Reference in New Issue
	
	Block a user