トラブル
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