トラブル
qmail-remoteがタイムアウトしない
qmail-remoteが何日だろうが、何ヶ月だろうが生きたままになっていることがある。 このようなプロセスが積み重なってくると、そのうちにconcurrencyremoteの数に到達してしまい一通のメールも送信できなくなってしまう。
このようなqmail-remoteを確認するコマンドは以下。
ps ax -o etime,pid,comm --no-heading | grep qmail-remote
これにより以下のような出力が得られる。
02:10:33 12986 qmail-remote 03:47:23 28958 qmail-remote
フィールドは左から、コマンド投入後経過時間、プロセス番号、コマンド名
本来であれば、timeoutconnect,timeoutremote,timeoutsmtpdの値によって、時間内に送信できない場合はqmail-remoteが終了するはずだが、そうならない理由は、送信先サーバがメールを受信するつもりがないのに、ACK等の制御コードだけは送ってくるからである。このため、timeoutremoteのタイムアウト値がリセットされてしまい、決してタイムアウトにならない。
qmail自体をパッチしてこの問題を修正することはできるが、ここでは時間のかかりすぎるqmail-remoteを「殺す」方策をとる。 参考リンクにこれを行うためのシェルスクリプトがあるが、文字が化けているため、コピーペーストはできない。正しくは以下。
また、--helpの文言が間違っている。「1時間以上経過したqmail-smtpdあるいはqmail-sendプロセスを殺す」とあるが、正しくは、qmail-smtpdあるいはqmail-remoteである。
# ===========================
# qmail zombie killer script
# Version: 1.0
# Author: L. Sheed
# Company: Computer Solutions
# URL: http://www.computersolutions.cn
# ===========================
PATH=/usr/bin:/bin
function short_usage
{
cat <<- _EOF_
$0: missing parameter
Try '$0 --help' for more information.
_EOF_
}
function usage
{
cat <<- _EOF_
Parameters:
--force kill qmail-smtpd and qmail-send processes (aka zombies) older than 1 hour
--test do a test run (no zombie processes will be harmed)
--help show this help page
Notes:
Strongly suggest test first to see if the ps line works correct on your system before killing any processes!
eg - Run the ps below on your system, and see if the output looks similar
ps ax -o etime,pid,comm --no-heading | grep qmail-smtp
04:40 6468 qmail-smtpd
01:47 7473 qmail-smtpd
01:00 8142 qmail-smtpd
01:00 8143 qmail-smtpd
00:46 8235 qmail-smtpd
00:36 8283 qmail-smtpd
00:19 8391 qmail-smtpd
00:11 8445 qmail-smtpd
00:07 8494 qmail-smtpd
_EOF_
}
function zap_the_bastards
{
PLIST=`ps ax -o etime,pid,comm --no-heading | grep $WHAT | grep ':[0-9][0-9]:' | awk '{print $2}'`
#In test mode, show what would be called also
if [ "$test" = "1" ]; then
echo "Running: ps ax -o etime,pid,comm --no-heading | grep $WHAT | grep ':[0-9][0-9]:' | awk '{print $2}'"
fi
if [ -n "${PLIST:-}" ]
then
echo "-=-=-=-=-=-=-=-=-=-=-"
echo "Found zombies, setting up shotgun."
echo "Killing $WHAT zombies"
for p in $PLIST
do
if [ "$force" = "1" ]; then
echo "Kabooom:"
kill -9 $p
fi
echo "kill -9 $p"
done
echo "-=-=-=-=-=-=-=-=-=-=-"
else
echo "Good news everybody. No $WHAT zombies found."
fi
}
## Main
#parse our parameters
if [ ! $# == 1 ]; then
short_usage
exit
fi
while [ "$1" != "" ]; do
case $1 in
--force )
echo "**Running in FORCE mode**"
force=1
;;
--help )
usage
exit
;;
--test )
echo "**Running in TEST mode**"
test=1
;;
esac
shift
done
#do the deed
targets=( "qmail-remote" "qmail-smtpd" )
for target in ${targets[@]}
do
WHAT=$target
zap_the_bastards
done
