From 42618905dd3a86740ee6e2928cfecc92c9281b3a Mon Sep 17 00:00:00 2001 From: Jaco Kroon Date: Mon, 4 Sep 2023 17:06:55 +0200 Subject: net-misc/asterisk-base: add 2 Fix core dump handling. Signed-off-by: Jaco Kroon Signed-off-by: Joonas Niilola --- net-misc/asterisk-base/files/asterisk_wrapper-2 | 227 ++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 net-misc/asterisk-base/files/asterisk_wrapper-2 (limited to 'net-misc/asterisk-base/files') diff --git a/net-misc/asterisk-base/files/asterisk_wrapper-2 b/net-misc/asterisk-base/files/asterisk_wrapper-2 new file mode 100644 index 000000000000..cd7d5ff6504e --- /dev/null +++ b/net-misc/asterisk-base/files/asterisk_wrapper-2 @@ -0,0 +1,227 @@ +#! /bin/sh +# Copyright 1999-2023 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +progname="$(basename "$0")" + +T="$(getopt -o "h" --long "help,corecompress:,corerename:,crashemail:,dumpcore:,instance:,maxfd:,nicelevel:,restartdelay:,rundir:,syslog,tty:" -n "$progname" -- "$@")" +eval set -- "${T}" + +# bash builtins are special ... +echo_e="$([ "${SHELL}" = "/bin/bash" ] && echo "echo -e" || echo echo)" + +rundir=/run/asterisk +restartdelay=5 +nicelevel=0 +maxfd=4096 +dumpcore=0 +unset tty instance syslog corecompress corerename crashemail + +usage() { + cat <&2 + usage >&2 + exit 1 + ;; + esac +done +shift # -- + +if ! matchreg "${restartdelay}" "^[1-9][0-9]*$"; then + echo "Invalid --restartdelay value ${restartdelay}, resetting to 5." >&2 + restartdelay=5 +fi + +if ! matchreg "${maxfd}" "^[1-9][0-9]*$"; then + echo "Invalid --maxfd value, resetting to 4096." >&2 + maxfd=4096 +fi + +if [ $maxfd -lt 1024 ]; then + echo "maxfd is guaranteed too low, bumping to at least 1024" >&2 + maxfd=1024 +fi + +if [ -n "${nicelevel}" ] && ! matchreg "${nicelevel}" -E "^-?[0-9]+$"; then + echo "Invalid --nicelevel which much be a valid integer (values from -20 to 20 makes sense)." + exit 1 +fi + +if [ -n "${corecompress}" -a ! -x "${corecompress}" ]; then + corecompress=$(which "${corecompress}" 2>/dev/null) + [ -z "${corecompress}" ] && echo "Error locating core compression tool, disabling core compression." >&2 +fi + +# Before here will still be output (potentially munged, to the terminal). +if [ -n "${syslog}" ]; then + tdir="$(mktemp -d)" + tfifo="${tdir}/asterisk_wrapper.logger.fifo" + mkfifo "${tfifo}" + logger -t "asterisk_wrapper${instance:+:}${instance}" --id=$$ >/dev/null 2>&1 <"${tfifo}" & + exec 1>"${tfifo}" + exec 2>&1 + + rm "${tfifo}" + rmdir "${tdir}" +fi + +echo "Initializing ${progname}" + +cleanup(){ + # There is a tiny race here, if this gets replaced inbetween the read and the rm. + # To fix this is quite complex in that we need to keep an fd, compare inode numbers + # and manage flock's. + [ -r "${rundir}/${progname}.pid" ] && \ + [ "$(cat "${rundir}/${progname}.pid")" = $$ ] && \ + rm "${rundir}/${progname}.pid" +} +trap cleanup EXIT + +# We could be clobbering an old version's pid, in which case it'll just terminate on +# it's next iteration. Towards this end, if asterisk.pid exists, attempt to find it's +# config file and request a core stop when convenient so that we can take over. +echo $$ > "${rundir}/${progname}.pid" +if [ -r "${rundir}/asterisk.pid" ]; then + ast_pid="$(cat "${rundir}/asterisk.pid")" + [ -r "/proc/${ast_pid}/cmdline" ] && ast_conf="$(tr '\0' '\n' < "/proc/${ast_pid}/cmdline" | grep -A1 '^-C$' | tail -n1)" && /usr/sbin/asterisk -C "${ast_conf:-/etc/asterisk/asterisk.conf}" -rx "core stop when convenient" + # We may hit a few (depending on how busy the server is a great many number) loop failures still ... +fi + +prlimit --core=${dumpcore} --pid=$$ +prlimit --nofile=${maxfd} --pid=$$ + +ast_cmd=/usr/sbin/asterisk +if [ -n "${nicelevel}" ]; then + ast_cmd="nice -n ${nicelevel} ${ast_cmd}" +fi + +while [ -r "${rundir}/${progname}.pid" ]; do + # Another instance is looking to replace us, so terminate. + if [ "$(cat "${rundir}/${progname}.pid")" != $$ ]; then + break + fi + + echo "Starting asterisk with ${ast_cmd} $*" + if [ -n "${tty+yes}" ]; then + /bin/stty -F "${tty}" sane + ${ast_cmd} "$@" >"${tty}" 2>&1 <"${tty}" + result=$? + else + # Purposefully leave stderr alone, this will under certain odd cases (like exceptions, + # and other odd cases logged from glibc) result in those logs at least being captured + # in syslog. + ${ast_cmd} "$@" /dev/null + result=$? + fi + + if [ "$result" -eq 0 ]; then + echo "Asterisk terminated normally." + break + fi + + if [ "$result" -gt 128 ]; then + signal="$(( result - 128 ))" + signame="$(kill -l $signal 2>/dev/null)" + MSG="Asterisk terminated with Signal: $signal (SIG${signame:-???})" + + # TODO: figure out how to use /proc/sys/kernel/core_pattern here, but if someone is using + # that, chances are they're already dealing with what we want here. + if [ -r core ]; then + if [ -n "${corerename+yes}" ]; then + core_target="$(echo "${corerename}" | sed -e "s/%h/$(hostname)/" \ + -e "s/%D/$(date +%Y%m%d)/" -e "s/%T/$(date +%H%M%S)/")" + mv core "${core_target}" + core_target=$(readlink -f "${core_target}") + else + core_target=$(readlink -f core) + fi + + if [ -n "${corecompress}" ] && [ -x "${corecompress}" ]; then + "${corecompress}" "${core_target}" + fi + + MSG="${MSG}, Core dumped: ${core_target}" + fi + else + MSG="Asterisk terminated with return code: $result" + fi + + [ -n "${tty+yes}" ] \ + && echo "${MSG}" >"${tty}" \ + || echo "${MSG}" + + if [ -n "${crashemail+yes}" ] && [ -x /usr/sbin/sendmail ]; then + $echo_e -n "Subject: Asterisk crashed\r\n${MSG}\r\n" |\ + /usr/sbin/sendmail "${crashemail}" + fi + echo "Restarting asterisk after ${restartdelay}s ..." + sleep "${restartdelay}" +done + +echo "Terminating $progname." +exit 0 -- cgit v1.2.3-65-gdbad