net.tcp.listen が、内部的に [/proc/net/tcp] の完全なリストを読み取っていない
環境: linux 2.6 (CentOS 6.4) x86_64 / zabbix-2.0.11
関連する本家 BTS の ISSUE 番号 : ZBX-6790
ZBX-6790 によると、2.0.11 を含む最新版にて、[race condition] 不整合を起こす問題は修正済となっています
しかし、新たな不具合として、使用中ソケットの一覧となっている [/proc/net/tcp] を
完全に読み取っていないようです
そのため、多数のポートで [listen] している状態で、それぞれについて
net.tcp.listen[xxx] のチェックを行うと、一部は「正常(listen中)」、一部は「異常(listenしていない)」と
返ってきてしまっています
いろいろ調査してみたところ、[/proc/net/tcp] のサイズが 4KB を超えない場合 (おおよそ25 entry) には
正常に動作するようですが、それを超えてしまう場合、チェックが不完全になってしまうことが解りました
kernel系の特殊ファイルなのが理由か、read 関数に大きなバッファを与えていても、
一度の read 関数呼び出しでは、最大4KB (カーネルのページサイズ)を超えるデータは
返ってこず、複数回の read 呼び出しで処理をする必要があるみたいなのですが、
zabbix agent ソースコード [src/libs/zbxsysinfo/net.c] 内での記述を見る限り、
1度の read 読取で、処理を完了するようになっているようです
同等のコードを切り出して、複数台のホスト上で、strace を使って動作させてみた結果を添付します
複数回読み出すことについては、修正されるキッカケとなった [race condition] 問題の再発もあり得ると
思いますので、なかなかに厄介だと思います
本家 BTS にもありましたが、iproute2 ツールに含まれる ss ツールが、
別の方法で接続中ソケット一覧を取得しているようなので、そちらの方法が良いのやもしれません‥
#複数回読込のパッチを書こうとも思ったのですが、技量不足でした‥orz
- test1.c.txt (649 バイト)
- trace_success_small.txt (2.4 KB)
- trace_fail_large1.txt (13.91 KB)
- trace_fail_large2.txt (13.39 KB)
fripper - 投稿数: 495
先のコメントに添付した trace_fail_large1.txt のホスト上で動作させている
zabbix_agentd に、動作中に strace にてアタッチをかけて取得した
動作記録を添付します
1度の read 要求しか出されておらず、先頭 4K 程度しか読取りしていない(できていない)のが
見てとれます
fripper - 投稿数: 495
本問題、2.0.12 rc3 での changelog にて修正されたと報告のある ZBX-8108 にて、修正されている可能性が高いようです
まだ、rc3 使った動作確認試験が実施できていないため、確定情報ではありませんが、
ソースコード内の修正点 [src/libs/zbxsysinfo/net.c] 内を見る限り、
「4kBのみ、1度の read しか実施されていない」という点について、
対策が講じられているように見てとれます
https://support.zabbix.com/browse/ZBX-8108
時間が十分に確保できないため、すぐ動作確認してご報告、というわけにはいきませんが、速報として共有します。
fripper - 投稿数: 495
2.0.12がリリースされて結構経ってしまいました
手元環境にて、本問題の解決を無事確認できました
開発チームの方々に感謝感謝です
rc版・ベータ版ではなく、正式版という観点では、
2.0系は、2.0.12正式版にて修正完了済
2.2系は、2.2.4がまだrc版ですので、2.2.4正式版以降
ということになるでしょうか。