rsyslog/tests/omprog-restart-terminated.sh
Rainer Gerhards 34241cc1c5
Merge pull request #3328 from jsiwrk/child_exit_report_option
report child process exit status according to config parameter
2018-12-30 12:55:28 +01:00

156 lines
4.4 KiB
Bash
Executable File

#!/bin/bash
# This file is part of the rsyslog project, released under ASL 2.0
# This test checks that omprog restarts the external program when it
# terminates prematurely, and that it does so without leaking file
# descriptors. Two cases are checked: termination of the program when
# omprog is going to write to the pipe (to send a message to the
# program), and when omprog is going to read from the pipe (when it
# is expecting the program to confirm the last message).
. ${srcdir:=.}/diag.sh init
check_command_available lsof
generate_conf
add_conf '
module(load="../plugins/omprog/.libs/omprog")
template(name="outfmt" type="string" string="%msg%\n")
:msg, contains, "msgnum:" {
action(
type="omprog"
binary="'$RSYSLOG_DYNNAME'.omprog-restart-terminated-bin.sh"
template="outfmt"
name="omprog_action"
queue.type="Direct" # the default; facilitates sync with the child process
confirmMessages="on" # facilitates sync with the child process
action.resumeRetryCount="3"
action.resumeInterval="1"
action.reportSuspensionContinuation="on"
signalOnClose="off"
)
}
syslog.* {
action(type="omfile" template="outfmt" file=`echo $RSYSLOG2_OUT_LOG`)
}
'
# We need a test-specific program name, as the test needs to signal the child process
cp -f $srcdir/testsuites/omprog-restart-terminated-bin.sh $RSYSLOG_DYNNAME.omprog-restart-terminated-bin.sh
# On Solaris 10, the output of ps is truncated for long process names; use /usr/ucb/ps instead:
if [[ $(uname) = "SunOS" && $(uname -r) = "5.10" ]]; then
function get_child_pid {
/usr/ucb/ps -awwx | grep "$RSYSLOG_DYNNAME.[o]mprog-restart-terminated-bin.sh" | awk '{ print $1 }'
}
else
function get_child_pid {
ps -ef | grep "$RSYSLOG_DYNNAME.[o]mprog-restart-terminated-bin.sh" | awk '{ print $2 }'
}
fi
startup
injectmsg 0 1
wait_queueempty
pid=$(getpid)
echo PID: $pid
start_fd_count=$(lsof -p $pid | wc -l)
injectmsg 1 1
injectmsg 2 1
wait_queueempty
child_pid_1=$(get_child_pid)
kill -s USR1 $child_pid_1
./msleep 100
injectmsg 3 1
injectmsg 4 1
wait_queueempty
child_pid_2=$(get_child_pid)
kill -s TERM $child_pid_2
./msleep 100
injectmsg 5 1
injectmsg 6 1
injectmsg 7 1
wait_queueempty
child_pid_3=$(get_child_pid)
kill -s KILL $child_pid_3
./msleep 100
injectmsg 8 1
injectmsg 9 1
wait_queueempty
end_fd_count=$(lsof -p $pid | wc -l)
child_pid_4=$(get_child_pid)
child_lsof=$(lsof -a -d 0-65535 -p $child_pid_4 | awk '$4 != "255r" { print $4 " " $9 }')
shutdown_when_empty
wait_shutdown
export EXPECTED="Starting
Received msgnum:00000000:
Received msgnum:00000001:
Received msgnum:00000002:
Received SIGUSR1, will terminate after the next message
Received msgnum:00000003:
Terminating without confirming the last message
Starting
Received msgnum:00000003:
Received msgnum:00000004:
Received SIGTERM, terminating
Starting
Received msgnum:00000005:
Received msgnum:00000006:
Received msgnum:00000007:
Starting
Received msgnum:00000008:
Received msgnum:00000009:
Terminating normally"
cmp_exact $RSYSLOG_OUT_LOG
if [[ "$start_fd_count" != "$end_fd_count" ]]; then
echo "file descriptor leak: started with $start_fd_count open files, ended with $end_fd_count"
error_exit 1
fi
# Check that the child process does not inherit open fds from rsyslog
# (apart from the pipes), and that stderr is redirected to /dev/null.
# Ignore fd 255, which bash opens for internal use.
EXPECTED_CHILD_LSOF="FD NAME
0r pipe
1w pipe
2w /dev/null"
# On Solaris, lsof gives this alternate output:
EXPECTED_CHILD_LSOF_2="FD NAME
0u (fifofs)
1u (fifofs)
2w "
if [[ "$child_lsof" != "$EXPECTED_CHILD_LSOF" && "$child_lsof" != "$EXPECTED_CHILD_LSOF_2" ]]; then
echo "unexpected open files for child process:"
echo "$child_lsof"
error_exit 1
fi
# Check also that child process terminations are reported correctly.
# When the reportChildProcessExits global parameter is "errors" (the default),
# only non-zero exit codes are reported.
content_check "(pid $child_pid_1) terminated; will be restarted" $RSYSLOG2_OUT_LOG
custom_assert_content_missing "(pid $child_pid_1) exited with status" $RSYSLOG2_OUT_LOG
content_check "(pid $child_pid_2) terminated; will be restarted" $RSYSLOG2_OUT_LOG
content_check "(pid $child_pid_2) exited with status 1" $RSYSLOG2_OUT_LOG
content_check "(pid $child_pid_3) terminated; will be restarted" $RSYSLOG2_OUT_LOG
content_check "(pid $child_pid_3) terminated by signal 9" $RSYSLOG2_OUT_LOG
exit_test