commit 9fcd8f801b6aa575dbd5decff531007162269445 Author: Kerin Millar Date: Tue Jan 5 23:04:09 2021 +0000 Raise useful warnings in the case that ulimit fails Unfortunately, the means by which OpenRC allows for the configuration of resource limits is intrinsically non-portable. POSIX sh is only obligated to support the -f option. Consequently, any implemented extensions are prone to vary considerably. Further, popular implementations such as dash don't even necessarily allow for multiple option/value pairs. A better approach would be to use setrlimit(2). For now, try to raise meaningful warnings in the event of failure. This is accomplished by stashing the effective value of rc_ulimit both after importing the global config files and after importing any config files specific to the service. After ulimit is invoked, the exit status is checked. In the case that it has failed, a warning message is emitted which reports the sh implementation and the options that were given (because the shell might not report them). It also suggests that the configuration files most likely to be responsible for the issue be edited and advises the user of the service name, where appropriate. diff --git a/sh/openrc-run.sh.in b/sh/openrc-run.sh.in index 7e9064c2..7778f4ee 100644 --- a/sh/openrc-run.sh.in +++ b/sh/openrc-run.sh.in @@ -220,6 +220,10 @@ if [ -d "@SYSCONFDIR@/rc.conf.d" ]; then done fi +# Stash the globally defined rc_ulimit value so that we may later determine +# whether it was overridden by a service conf.d file. +_global_rc_ulimit=${rc_ulimit:-$RC_ULIMIT} + _conf_d=${RC_SERVICE%/*}/../conf.d # If we're net.eth0 or openvpn.work then load net or openvpn config _c=${RC_SVCNAME%%.*} @@ -236,6 +240,10 @@ if ! sourcex -e "$_conf_d/$RC_SVCNAME.$RC_RUNLEVEL"; then fi unset _conf_d +# Stash the rc_ulimit value defined in conf.d scope so that we may later +# determine whether the global value was overriden. +_local_rc_ulimit=${rc_ulimit:-$RC_ULIMIT} + # load service supervisor functions sourcex "@LIBEXECDIR@/sh/runit.sh" sourcex "@LIBEXECDIR@/sh/s6.sh" @@ -253,9 +261,24 @@ fi for _cmd; do if [ "$_cmd" != status -a "$_cmd" != describe ]; then - # Apply any ulimit defined - [ -n "${rc_ulimit:-$RC_ULIMIT}" ] && \ - ulimit ${rc_ulimit:-$RC_ULIMIT} + # Apply any ulimit defined. Unfortunately, this approach is + # intrinsically non-portable. POSIX sh is only obligated to + # support the -f option. Consequently, any implemented + # extensions are prone to vary considerably. Further, popular + # implementations such as dash don't even necessarily allow for + # multiple option/value pairs. A better approach would be to + # use setrlimit(2). For now, try to raise meaningful warnings + # in the event of failure. + if [ -n "${rc_ulimit:=$RC_ULIMIT}" ] && ! ulimit ${rc_ulimit}; then + _sh=$(readlink /bin/sh 2>/dev/null) || _sh=sh + ewarn "Your /bin/sh implementation ($_sh) failed to apply these rc_limit options: $rc_ulimit" + if [ "$_global_rc_ulimit" = "$_local_rc_ulimit" ]; then + ewarn "Please check your /etc/rc.conf and /etc/rc.conf.d files and adjust as necessary." + else + ewarn "Please check the conf.d file(s) for $RC_SVCNAME and adjust as necessary." + fi + fi + unset _sh _global_rc_ulimit _local_rc_ulimit # Apply cgroups settings if defined if [ "$(command -v cgroup_add_service)" = "cgroup_add_service" ] then