From 9cd4f3a55f2a6d6f69c7b6d26e397c1a5e05f45c Mon Sep 17 00:00:00 2001 From: ajacoutot Date: Sat, 27 Feb 2021 09:28:04 +0000 Subject: [PATCH] Add logger(1) support for daemons that are logging to stdout/stderr (mostly from the go ecosystem). Properly handle failing daemon startup now that we have pipefail. To take advantage of this new feature, just add foo_logger=facility to the daemon rc.d(8) script or in rc.conf.local(8) or use rcctl: rcctl set foo logger daemon.info tweak for checking flags in rcctl(8) from martijn@ "this looks pretty good" deraadt@ ok sthen@ --- etc/rc.d/rc.subr | 14 +++++++++----- share/man/man8/rc.d.8 | 9 +++++++-- share/man/man8/rc.subr.8 | 11 +++++++++-- usr.sbin/rcctl/rcctl.8 | 6 ++++-- usr.sbin/rcctl/rcctl.sh | 30 ++++++++++++++++++++++-------- 5 files changed, 51 insertions(+), 19 deletions(-) diff --git a/etc/rc.d/rc.subr b/etc/rc.d/rc.subr index 0268e0a9722..5bd7ba3f2c0 100644 --- a/etc/rc.d/rc.subr +++ b/etc/rc.d/rc.subr @@ -1,6 +1,6 @@ -# $OpenBSD: rc.subr,v 1.135 2020/07/12 14:35:38 jca Exp $ +# $OpenBSD: rc.subr,v 1.136 2021/02/27 09:28:04 ajacoutot Exp $ # -# Copyright (c) 2010, 2011, 2014-2017 Antoine Jacoutot +# Copyright (c) 2010, 2011, 2014-2021 Antoine Jacoutot # Copyright (c) 2010, 2011 Ingo Schwarze # Copyright (c) 2010, 2011, 2014 Robert Nagy # @@ -49,6 +49,7 @@ _rc_write_runfile() { cat >${_RC_RUNFILE} <&1 | + logger -ip ${daemon_logger} -t ${_name}}" } rc_check() { @@ -288,6 +290,7 @@ _RC_RUNFILE=${_RC_RUNDIR}/${_name} _rc_do _rc_parse_conf eval _rcflags=\${${_name}_flags} +eval _rclogger=\${${_name}_logger} eval _rcrtable=\${${_name}_rtable} eval _rctimeout=\${${_name}_timeout} eval _rcuser=\${${_name}_user} @@ -304,6 +307,7 @@ getcap -f /etc/login.conf ${_name} 1>/dev/null 2>&1 && daemon_class=${_name} || unset _rcflags [ -n "${_rcflags}" ] && daemon_flags=${_rcflags} +[ -n "${_rclogger}" ] && daemon_logger=${_rclogger} [ -n "${_rcrtable}" ] && daemon_rtable=${_rcrtable} [ -n "${_rctimeout}" ] && daemon_timeout=${_rctimeout} [ -n "${_rcuser}" ] && daemon_user=${_rcuser} @@ -315,7 +319,7 @@ if [ -n "${_RC_DEBUG}" ]; then fi readonly daemon_class -unset _rcflags _rcrtable _rctimeout _rcuser +unset _rcflags _rclogger _rcrtable _rctimeout _rcuser # the shell will strip the quotes from daemon_flags when starting a daemon; # make sure pexp matches the process (i.e. doesn't include the quotes) pexp="$(eval echo ${daemon}${daemon_flags:+ ${daemon_flags}})" diff --git a/share/man/man8/rc.d.8 b/share/man/man8/rc.d.8 index e0af34085ab..95f56725916 100644 --- a/share/man/man8/rc.d.8 +++ b/share/man/man8/rc.d.8 @@ -1,5 +1,6 @@ -.\" $OpenBSD: rc.d.8,v 1.35 2019/08/27 20:05:02 awolk Exp $ +.\" $OpenBSD: rc.d.8,v 1.36 2021/02/27 09:28:05 ajacoutot Exp $ .\" +.\" Copyright (c) 2021 Antoine Jacoutot .\" Copyright (c) 2011 Robert Nagy, Antoine Jacoutot, Ingo Schwarze .\" All rights reserved. .\" @@ -24,7 +25,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 27 2019 $ +.Dd $Mdocdate: February 27 2021 $ .Dt RC.D 8 .Os .Sh NAME @@ -110,6 +111,10 @@ is set to .Dq NO , it will prevent the daemon from starting even when listed in .Va pkg_scripts . +.It Ar daemon Ns _logger +Redirect standard output and error to +.Xr logger 1 +using the configured priority (e.g. "daemon.info"). .It Ar daemon Ns _rtable Routing table to run the daemon under, using .Xr route 8 . diff --git a/share/man/man8/rc.subr.8 b/share/man/man8/rc.subr.8 index af7bd55226d..27f54bebdbb 100644 --- a/share/man/man8/rc.subr.8 +++ b/share/man/man8/rc.subr.8 @@ -1,5 +1,6 @@ -.\" $OpenBSD: rc.subr.8,v 1.37 2020/02/21 00:47:21 kn Exp $ +.\" $OpenBSD: rc.subr.8,v 1.38 2021/02/27 09:28:05 ajacoutot Exp $ .\" +.\" Copyright (c) 2021 Antoine Jacoutot .\" Copyright (c) 2011 Robert Nagy, Antoine Jacoutot, Ingo Schwarze .\" All rights reserved. .\" @@ -24,7 +25,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: February 21 2020 $ +.Dd $Mdocdate: February 27 2021 $ .Dt RC.SUBR 8 .Os .Sh NAME @@ -247,6 +248,10 @@ If no such login class exists then will be used. .It Va daemon_flags Arguments to call the daemon with. +.It Ar daemon Ns _logger +Redirect standard output and error to +.Xr logger 1 +using the configured priority (e.g. "daemon.info"). .It Va daemon_rtable Routing table to run the daemon under, using .Xr route 8 . @@ -333,6 +338,7 @@ Global defaults are provided by .Bd -literal -offset indent daemon_class=daemon daemon_flags= +daemon_logger= daemon_rtable=0 daemon_timeout=30 daemon_user=root @@ -352,6 +358,7 @@ site-specific values provided in .Xr rc.conf.local 8 for .Va daemon_flags , +.Va daemon_logger , .Va daemon_rtable , .Va daemon_timeout , and diff --git a/usr.sbin/rcctl/rcctl.8 b/usr.sbin/rcctl/rcctl.8 index 9f7a90e3224..c6ed8b9909f 100644 --- a/usr.sbin/rcctl/rcctl.8 +++ b/usr.sbin/rcctl/rcctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: rcctl.8,v 1.35 2018/09/20 12:24:14 solene Exp $ +.\" $OpenBSD: rcctl.8,v 1.36 2021/02/27 09:28:04 ajacoutot Exp $ .\" .\" Copyright (c) 2014 Antoine Jacoutot .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 20 2018 $ +.Dd $Mdocdate: February 27 2021 $ .Dt RCCTL 8 .Os .Sh NAME @@ -58,6 +58,7 @@ The following commands are available can be one of .Cm class , .Cm flags , +.Cm logger , .Cm status , .Cm timeout or @@ -198,6 +199,7 @@ flags: # rcctl get apmd apmd_class=daemon apmd_flags=-A +apmd_logger= apmd_rtable=0 apmd_timeout=30 apmd_user=root diff --git a/usr.sbin/rcctl/rcctl.sh b/usr.sbin/rcctl/rcctl.sh index 954f32890e5..699737ff6cc 100644 --- a/usr.sbin/rcctl/rcctl.sh +++ b/usr.sbin/rcctl/rcctl.sh @@ -1,8 +1,8 @@ #!/bin/ksh # -# $OpenBSD: rcctl.sh,v 1.109 2021/02/18 06:17:35 ajacoutot Exp $ +# $OpenBSD: rcctl.sh,v 1.110 2021/02/27 09:28:04 ajacoutot Exp $ # -# Copyright (c) 2014, 2015 Antoine Jacoutot +# Copyright (c) 2014, 2015-2021 Antoine Jacoutot # Copyright (c) 2014 Ingo Schwarze # # Permission to use, copy, modify, and distribute this software for any @@ -251,7 +251,8 @@ svc_get() [ -n "${_svc}" ] || return local _status=0 _val _var=$2 - local daemon_class daemon_flags daemon_rtable daemon_timeout daemon_user + local daemon_class daemon_flags daemon_logger daemon_rtable + local daemon_timeout daemon_user if svc_is_special ${_svc}; then daemon_flags="$(eval echo \${${_svc}})" @@ -277,6 +278,12 @@ svc_get() [ -z "${daemon_flags}" ] && \ daemon_flags="$(svc_getdef ${_svc} flags)" fi + if [ -z "${_var}" -o "${_var}" = "logger" ]; then + [ -z "${daemon_logger}" ] && \ + daemon_logger="$(eval echo \"\${${_svc}_logger}\")" + [ -z "${daemon_logger}" ] && \ + daemon_logger="$(svc_getdef ${_svc} logger)" + fi if [ -z "${_var}" -o "${_var}" = "rtable" ]; then [ -z "${daemon_rtable}" ] && \ daemon_rtable="$(eval echo \"\${${_svc}_rtable}\")" @@ -311,6 +318,7 @@ svc_get() else echo "${_svc}_class=${daemon_class}" echo "${_svc}_flags=${daemon_flags}" + echo "${_svc}_logger=${daemon_logger}" echo "${_svc}_rtable=${daemon_rtable}" echo "${_svc}_timeout=${daemon_timeout}" echo "${_svc}_user=${daemon_user}" @@ -326,7 +334,8 @@ svc_getdef() [ -n "${_svc}" ] || return local _status=0 _val _var=$2 - local daemon_class daemon_flags daemon_rtable daemon_timeout daemon_user + local daemon_class daemon_flags daemon_logger daemon_rtable + local daemon_timeout daemon_user if svc_is_special ${_svc}; then # unconditionally parse: we always output flags and/or status @@ -367,6 +376,7 @@ svc_getdef() else echo "${_svc}_class=${daemon_class}" echo "${_svc}_flags=${daemon_flags}" + echo "${_svc}_logger=${daemon_logger}" echo "${_svc}_rtable=${daemon_rtable}" echo "${_svc}_timeout=${daemon_timeout}" echo "${_svc}_user=${daemon_user}" @@ -386,7 +396,7 @@ svc_rm() ( svc_getdef ${_svc} status ) && \ echo "${_svc}=NO" >>${_TMP_RCCONF} else - grep -Ev "^${_svc}_(flags|rtable|timeout|user).*=" \ + grep -Ev "^${_svc}_(flags|logger|rtable|timeout|user).*=" \ /etc/rc.conf.local >${_TMP_RCCONF} ( svc_getdef ${_svc} status ) && \ echo "${_svc}_flags=NO" >>${_TMP_RCCONF} @@ -439,6 +449,10 @@ svc_set() fi if [ -n "${_args}" ]; then + if [ "${_var}" = "logger" ]; then + logger -p "${_args}" /dev/null 2>&1 || + rcctl_err "unknown priority name: \"${_args}\"" + fi if [ "${_var}" = "rtable" ]; then [[ ${_args} != +([[:digit:]]) || ${_args} -lt 0 ]] && \ rcctl_err "\"${_args}\" is not an integer" @@ -518,13 +532,13 @@ case ${action} in rcctl_err "service ${svc} does not exist" 2 if [ -n "${var}" ]; then [ "${svc}" = "all" ] && usage - [[ ${var} != @(class|flags|status|rtable|timeout|user) ]] && usage + [[ ${var} != @(class|flags|logger|rtable|status|timeout|user) ]] && usage if svc_is_meta ${svc}; then [ "${var}" != "status" ] && \ rcctl_err "/etc/rc.d/${svc} is a meta script, cannot \"${action} ${var}\"" fi if svc_is_special ${svc}; then - [[ ${var} == @(class|rtable|timeout|user) ]] && \ + [[ ${var} == @(class|logger|rtable|timeout|user) ]] && \ rcctl_err "\"${svc}\" is a special variable, cannot \"${action} ${var}\"" fi fi @@ -540,7 +554,7 @@ case ${action} in svc_is_avail ${svc} || \ rcctl_err "service ${svc} does not exist" 2 fi - [[ ${var} != @(class|flags|rtable|status|timeout|user) ]] && usage + [[ ${var} != @(class|flags|logger|rtable|status|timeout|user) ]] && usage svc_is_meta ${svc} && [ "${var}" != "status" ] && \ rcctl_err "/etc/rc.d/${svc} is a meta script, cannot \"${action} ${var}\"" [[ ${var} = flags && ${args} = NO ]] && \ -- 2.20.1