Locked History Actions

qmail/Trouble

トラブル

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

参考