abrtdを使用している時は `ulimit -c` は効かない

abrtdを使用している時は ulimit -c は効かない

背景

Postfixの認証を担っているsaslauthdがクラッシュしてコアを吐いたのだが、設定が悪く保存されなかった。 再発した時にちゃんとコアが保存されるように設定する過程でネットで調べた情報が一部自分の環境(CentOS release 6.6)には適用されないことがわかった。

課題

表題の通り ulimit -cによるcore file sizeの上限が適用されないことが分かった。 soft limitの値が0、つまりコアを保存しない、という設定は適用されない。

結論

結果から言えば、CentOSはコアをabrtdというデーモンが受け取ってファイルに書き込む設定になっている。 abrtdが生成するコアのファイルサイズはulimitが指定する値は適用されない。

説明

以下のようにsaslauthdの Max core file size のsoft limitは0、hard limitはunlimitedである。 ということは本来saslauthdのコアは破棄されることになる。

$ ps aux | grep saslauth[d]                                                                                                            
root      2710  0.0  0.0  69948  1088 ?        Ss   20:06   0:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a httpform -c -t 60
root      2712  0.0  0.0  69948   772 ?        S    20:06   0:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a httpform -c -t 60
root      2713  0.0  0.0  69948   772 ?        S    20:06   0:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a httpform -c -t 60
root      2714  0.0  0.0  69948   772 ?        S    20:06   0:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a httpform -c -t 60
root      2715  0.0  0.0  69948   772 ?        S    20:06   0:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a httpform -c -t 60
$ sudo cat /proc/32411/limits | grep core
Max core file size        0                    unlimited            bytes  

しかし以下のように SIGABRT をプロセスに入れるとコアが生成される。

$ kill -ABRT 2710 
$ sudo tail /var/log/messages                                                                                                           
Jan 23 20:08:24 test001 abrtd: Directory 'ccpp-2017-01-23-20:08:24-2710' creation detected
Jan 23 20:08:24 test001 abrt[2756]: Saved core dump of pid 2710 (/usr/sbin/saslauthd) to /var/spool/abrt/ccpp-2017-01-23-20:08:24-2710 (1101824 bytes)

生成される事自体は問題ないが、 ulimit -c の値が適用されないのは気持ちが悪い。

調べた過程は省くがCentOSの場合は以下のような設定が適用されているため効かないようだ。

$ cat /proc/sys/kernel/core_pattern 
|/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t e

これでabrtdにコアが渡されている。

https://linuxjm.osdn.jp/html/LDP_man-pages/man5/core.5.html

このファイルの最初の文字がパイプ記号 (|) であれば、 その行の残りの部分は実行するプログラムとして解釈される。 コアダンプは、ディスク上のファイルに書き込まれるのではなく、 プログラムの標準入力として渡される。 以下の点に注意すること。 

このあたりでコアを標準出力でパイプを介してabrtdに渡しているから core file size が効かない(ファイルじゃないから)ということが薄々わかる。

あとはRedhatのabrtdのマニュアルを少し読み込むと以下のような記載がある。 https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sect-abrt-configuration-abrt.html

MakeCompatCore = yes/no
    This directive specifies whether ABRT's core catching hook should create a core file, as it could be done if ABRT would not be installed. The core file is typically created in the current directory of the crashed program but only if the ulimit -c setting allows it. The directive is set to yes by default. 

Coreとの互換性をもたせるオプション MakeCompatCore がyesの場合は ulimit -c が許可する場合だけコアを吐くようにできるとのこと。 つまり互換性を設定で有効にしない限り core file size の制限は効かないのが普通の動作だよ、ということである。

よく見ると、デフォルトでyesって書いてあるけど・・・? まぁいいか。