[Asterisk-code-review] ast coredumper: Refactor the pid determination process (asterisk[master])
Joshua C. Colp
asteriskteam at digium.com
Fri Jan 4 08:27:05 CST 2019
Joshua C. Colp has submitted this change and it was merged. ( https://gerrit.asterisk.org/10832 )
Change subject: ast_coredumper: Refactor the pid determination process
......................................................................
ast_coredumper: Refactor the pid determination process
In order to get a dump of the running process, we need to find the
pid of the main asterisk process. This can be tricky if there are
also instances of "asterisk -r" running or if an alternate location
for asterisk.conf was specified on the command line with the -C
option that also specified an alternation location for the pid file.
So now...
1. We find the asterisk executable with "which" or the --asterisk-bin
command line option.
2. If there's only 1 process with an executable path that matches,
we use that pid. If not...
3. We try "<asterisk-bin> -rx 'core show settings'" and parse the
output to find the pidfile, then read that for the pid. If that
didn't work...
4. We get a list of all the pids matching <asterisk-bin> and look
in /proc/<pid>/cmdline for a -C argument and retry the "core show
settings" using the same -C option. We can't parse the output
of "ps" to get the -C path because it may contain spaces. The
contents of /proc/<pid>/cmdline are delimited by NULLs. For BSDs
we may have to mount /proc first. :(
ASTERISK-28221
Reported by: Andrew Nagy
Change-Id: I8aa1f3f912f949df2b5348908803c636bde1d57c
---
M contrib/scripts/ast_coredumper
1 file changed, 84 insertions(+), 29 deletions(-)
Approvals:
Joshua C. Colp: Looks good to me, but someone else must approve; Approved for Submit
George Joseph: Looks good to me, approved
diff --git a/contrib/scripts/ast_coredumper b/contrib/scripts/ast_coredumper
index 0215edb..defb629 100755
--- a/contrib/scripts/ast_coredumper
+++ b/contrib/scripts/ast_coredumper
@@ -372,42 +372,97 @@
# Timestamp to use for output files
df=${tarball_uniqueid:-$(${DATEFORMAT})}
-if [ -z "$asterisk_bin" ]; then
+if [ x"$asterisk_bin" = x ]; then
asterisk_bin=$(which asterisk)
fi
if $running || $RUNNING ; then
# We need to go through some gyrations to find the pid of the running
# MAIN asterisk process and not someone or something running asterisk -r.
- # The pid file may NOT be in /var/run/asterisk so we need to find any
- # running asterisk process and see if -C was specified on the command
- # line. The chances of more than 1 asterisk instance running with
- # different -C options is so unlikely that we're going to ignore it.
- #
- # 'ps axo command' should work on Linux (back to CentOS6) and FreeBSD.
- # If asterisk was started with -C, get the asterisk.conf file.
- # If it wasn't, assume /etc/asterisk/asterisk.conf
- astetcconf=`ps axo command | sed -n -r -e "s/.*asterisk\s+.*-C\s+([^ ]+).*/\1/gp" | tail -1`
- [ x$astetcconf = x ] && astetcconf=/etc/asterisk/asterisk.conf
- # Now parse out astrundir and cat asterisk.pid
- astrundir=$(sed -n -r -e "s/astrundir\s+[=>]+\s+(.*)/\1/gp" $astetcconf)
- pid=$(cat $astrundir/asterisk.pid 2>/dev/null || : )
- if [ x$pid = x ] ; then
- echo "Asterisk is not running"
+
+ unset pid
+
+ # Simplest case first...
+ pids=$(pgrep -f "$asterisk_bin")
+ pidcount=$(echo $pids | wc -w)
+
+ if [ $pidcount -eq 0 ] ; then
+ >&2 echo "Asterisk is not running"
+ exit 1
+ fi
+
+ # Single process, great.
+ if [ $pidcount -eq 1 ] ; then
+ pid=$pids
+ echo "Found a single asterisk instance running as process $pid"
+ fi
+
+ # More than 1 asterisk process running
+ if [ x"$pid" = x ] ; then
+ # More than 1 process running, let's try asking asterisk for it's
+ # pidfile
+ pidfile=$("$asterisk_bin" -rx "core show settings" 2>/dev/null | sed -n -r -e "s/^\s*pid file:\s+(.*)/\1/gpi")
+ # We found it
+ if [ x"$pidfile" != x -a -f "$pidfile" ] ; then
+ pid=$(cat "$pidfile")
+ echo "Found pidfile $pidfile with process $pid"
+ fi
+ fi
+
+ # It's possible that asterisk was started with the -C option which means the
+ # control socket and pidfile might not be where we expect. We're going to
+ # have to parse the process arguments to see if -C was specified.
+ # The first process that has a -C argument determines which config
+ # file to use to find the pidfile of the main process.
+ # NOTE: The ps command doesn't quote command line arguments that it
+ # displays so we need to look in /proc/<pid>/cmdline.
+
+ if [ x"$pid" = x ] ; then
+ # BSDs might not mount /proc by default :(
+ mounted_proc=0
+ if uname -o | grep -qi "bsd" ; then
+ if ! mount | grep -qi "/proc" ; then
+ echo "Temporarily mounting /proc"
+ mounted_proc=1
+ mount -t procfs proc /proc
+ fi
+ fi
+
+ for p in $pids ; do
+ # Fields in cmdline are delimited by NULLs
+ astetcconf=$(sed -n -r -e "s/.*\x00-C\x00([^\x00]+).*/\1/gp" /proc/$p/cmdline)
+ if [ x"$astetcconf" != x ] ; then
+ pidfile=$("$asterisk_bin" -C "$astetcconf" -rx "core show settings" 2>/dev/null | sed -n -r -e "s/^\s*pid file:\s+(.*)/\1/gpi")
+ if [ x"$pidfile" != x -a -f "$pidfile" ] ; then
+ pid=$(cat "$pidfile")
+ echo "Found pidfile $pidfile the hard way with process $pid"
+ break
+ fi
+ fi
+ done
+ if [ $mounted_proc -eq 1 ] ; then
+ echo "Unmounting /proc"
+ umount /proc
+ fi
+ fi
+
+ if [ x"$pid" = x ] ; then
+ >&2 echo "Can't determine pid of the running asterisk instance"
+ exit 1
+ fi
+
+ if $RUNNING ; then
+ answer=Y
else
- if $RUNNING ; then
- answer=Y
- else
- read -p "WARNING: Taking a core dump of the running asterisk instance will suspend call processing while the dump is saved. Do you wish to continue? (y/N) " answer
- fi
- if [[ "$answer" =~ ^[Yy] ]] ; then
- cf="${OUTPUTDIR:-/tmp}/core-asterisk-running-$df"
- echo "Dumping running asterisk process to $cf"
- ${GDB} ${asterisk_bin} -p $pid -q --batch --ex "gcore $cf" >/dev/null 2>&1
- COREDUMPS+=("$cf")
- else
- echo "Skipping dump of running process"
- fi
+ read -p "WARNING: Taking a core dump of the running asterisk instance will suspend call processing while the dump is saved. Do you wish to continue? (y/N) " answer
+ fi
+ if [[ "$answer" =~ ^[Yy] ]] ; then
+ cf="${OUTPUTDIR:-/tmp}/core-asterisk-running-$df"
+ echo "Dumping running asterisk process to $cf"
+ ${GDB} ${asterisk_bin} -p $pid -q --batch --ex "gcore $cf" >/dev/null 2>&1
+ COREDUMPS+=("$cf")
+ else
+ echo "Skipping dump of running process"
fi
fi
--
To view, visit https://gerrit.asterisk.org/10832
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I8aa1f3f912f949df2b5348908803c636bde1d57c
Gerrit-Change-Number: 10832
Gerrit-PatchSet: 2
Gerrit-Owner: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Friendly Automation (1000185)
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua C. Colp <jcolp at digium.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20190104/e3580027/attachment-0001.html>
More information about the asterisk-code-review
mailing list