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

コメント表示オプション

お好みのコメント表示方法を選び「設定の保存」をクリックすると変更が反映されます。
ユーザー fripper の写真

先のコメントに添付した trace_fail_large1.txt のホスト上で動作させている
zabbix_agentd に、動作中に strace にてアタッチをかけて取得した
動作記録を添付します

1度の read 要求しか出されておらず、先頭 4K 程度しか読取りしていない(できていない)のが
見てとれます

ユーザー fripper の写真

本問題、2.0.12 rc3 での changelog にて修正されたと報告のある ZBX-8108 にて、修正されている可能性が高いようです

まだ、rc3 使った動作確認試験が実施できていないため、確定情報ではありませんが、
ソースコード内の修正点 [src/libs/zbxsysinfo/net.c] 内を見る限り、
「4kBのみ、1度の read しか実施されていない」という点について、
対策が講じられているように見てとれます

https://support.zabbix.com/browse/ZBX-8108

時間が十分に確保できないため、すぐ動作確認してご報告、というわけにはいきませんが、速報として共有します。

ユーザー fripper の写真

2.0.12がリリースされて結構経ってしまいました

手元環境にて、本問題の解決を無事確認できました
開発チームの方々に感謝感謝です

rc版・ベータ版ではなく、正式版という観点では、
2.0系は、2.0.12正式版にて修正完了済
2.2系は、2.2.4がまだrc版ですので、2.2.4正式版以降
ということになるでしょうか。