SNMPオブジェクトhrStorageSizeの取得について

お世話になります。初めて投稿させていただきます。

ZABBIX 2.4.2 で監視運用しています。

下記について、ご教授いただけますでしょうか。

【状況】
SNMPv2エージェントで、ディスク容量を監視していますが、先日監視対象のディスクを交換して11TBに容量を増やしたところ、
hrStorageSizeの取得で
Received value [-1462858351] is not suitable for value type [Numeric (unsigned)] and data type [Decimal]
とエラーになり取得不可となってしまいました。

zabbbixサーバからsnmpwalkで値を見たところ、以下のようになっています。

snmpwalk -v 2c -c public 10.1.0.14 hrStorageTable|grep .35
HOST-RESOURCES-MIB::hrStorageIndex.35 = INTEGER: 35
HOST-RESOURCES-MIB::hrStorageType.35 = OID: HOST-RESOURCES-TYPES::hrStorageFixedDisk
HOST-RESOURCES-MIB::hrStorageDescr.35 = STRING: /data
HOST-RESOURCES-MIB::hrStorageAllocationUnits.35 = INTEGER: 4096 Bytes
HOST-RESOURCES-MIB::hrStorageSize.35 = INTEGER: 2832108945
HOST-RESOURCES-MIB::hrStorageUsed.35 = INTEGER: 586240721
HOST-RESOURCES-MIB::hrStorageAllocationFailures.35 = Counter32: 0

snmpwalkでの取得値は、INTEGER: 2832108945なのですが、受け取ったzabbixサーバでは、-1462858351と負の値となりエラーとなっています。
zabbixでsnmpエージェントから受け取ることが出来る値は、データ型:数値(整数)では 2147483647 までなのでしょうか?
何か改善の方法はありますでしょうか?

【環境】
zabbixサーバ CentOS release 5.10.x86_64 zabbix-server-2.4.2(ソースからビルド)
snmpエージェント CentOS release 5.9.x86_64  net-snmp.x86_64 5.3.2.2-25.el5_11

【アイテム】
タイプ:   SNMPv2エージェント
キー:    hrStorageSize[{#SNMPVALUE}]
データ型: 数値 (整数)

以上、よろしくお願いいたします。

コメント表示オプション

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

この不具合ではないでしょうか?
https://support.zabbix.com/browse/ZBX-1274

2.3.0 で修正、とされていますので、2.4.x 系のみで修正された問題だと思います
2.0.x/2.2.x 系ではおそらく修正されていないと思います

Zabbix サーバ側での受け取った値の処理における不具合のようなので、
エージェント側を更新しても、改善しないと思います

ユーザー TKSS の写真

fripper様

早速のコメントありがとうございます。
確かにその不具合のようです。
現在使用しているのは2.4.2なのですが、修正が反映されていないのかも知れませんね…

ユーザー fripper の写真

NET-SNMP側の不具合も疑ってみましたが‥
https://rhn.redhat.com/errata/RHBA-2011-1076.html
https://bugzilla.redhat.com/show_bug.cgi?id=654384

ご利用になっている 5.3.2.2-25.el5_11 だと既に修正済の問題のようですね‥

1.zabbix-server が内部的に自ホスト上のnet-snmpライブラリをcallしてsnmp-getを実行
2.対象ホストの snmpd が問い合わせに答える
3.net-snmpライブラリが結果を受け取ってzabbix-serverへ渡す
4.zabbix-serverが処理‥

コマンドラインからsnmp-getを実行された場合は正しい結果とのことですので、「2」は問題無いとして‥
化け方が2832108945→-1462858351なので、32bit符号ビット問題(int/unsigned int)なのは確実ですね‥

1.2.4.2\src\zabbix_server\poller\checks_snmp.c 辺りを見てみたところ、
  libSNMPからの戻り値をデータ型に応じて処理しているらしい(567行目付近)
1.戻り値の型判定でOPAQUE_SPECIAL_TYPESの定義で処理が異なる
  →RHEL/CentOS5 のソースを見る限り「1」にdefineされているので有効(/usr/include/net-snmp/net-snmp-config-x86_64.h)
1.戻り値の型がASN_UINTEGER・ASN_UNSIGNED64等であれば、SET_UI64_RESULTへ行く
  ASN_INTEGER・ASN_INTEGER64だと、zbx_snprintfで扱われる模様(590行目付近)
1.CentOSのnet-snmp5322系ソースを見る限り、(src.rpm より:agent/mibgroup/host/hr_storage.c)
  ストレージのサイズを示すmibの型タイプはどうやらASN_INTEGER
     {HRSTORE_SIZE, ASN_INTEGER, RONLY, var_hrstore, 3, {3, 1, 5}},

んー、この辺りが怪しいですが‥Zabbix側のコードは32/64bit関係なく扱えるように
なっているように見えますが、どこかでおかしいのかもしれません。

libSNMPがASN_INTEGERで戻してくる、というのが‥(汗)
せめてASN_INTEGER64なら心配なさそうなんですけどね‥

ソース追ってみましたが、完全な「ここ」というポイントまではわかりませんでしたorz
お力になれず申し訳ないです‥

ユーザー TKSS の写真

fripper様

細かな調査ありがとうございます。
内容了解いたしました。

取り敢えず、増量したディスクの容量はまだ余裕がありますので、
不具合が解決されることを期待してしばらく待つことにします。

ユーザー fripper の写真

本家BTS では ZBX-1274 で修正済の扱いになっているようなので
修正漏れの可能性も踏まえ、ZBX-1274 のコメント、もしくは新規Issueとして
報告されることをお勧めします‥

ユーザー KAZ の写真
TKSSさん、fripperさん

fripperさんの指摘通り符号反転の問題ですが…

SNMPの戻りがINTEGER(Integer32)なので…
HOST-RESOURCES-MIB::hrStorageSize.35 = INTEGER: 2832108945

このルートに流れます。
#ifdef OPAQUE_SPECIAL_TYPES
	else if (ASN_INTEGER == var->type || ASN_INTEGER64 == var->type)
#else
	else if (ASN_INTEGER == var->type)
#endif
	{
		if (ITEM_VALUE_TYPE_UINT64 == value_type && 0 > *var->val.integer)
		{
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Received value [%d]"
					" is not suitable for value type [%s].",
					*var->val.integer, zbx_item_value_type_string(value_type)));
			ret = NOTSUPPORTED;
		}
		else
			SET_DBL_RESULT(result, *var->val.integer);
	}

Zabbix側は64bitですが、返ってきた値が符号付き32bitなので、NOTSUPPORTEDになります。

データ型を「数値(整数)」から「数値(浮動小数)」にすれば、
エラーはなくなりませんがNOTSUPPORTEDではなくなりますが、マイナス値が入ると思います。 2014-12-11 12:55修正










ユーザー KAZ の写真
TKSSさん、fripperさん

Zabbix的にはこのルートに流れてくれないと困るかと…

#ifdef OPAQUE_SPECIAL_TYPES
	else if (ASN_UINTEGER == var->type || ASN_COUNTER == var->type || ASN_UNSIGNED64 == var->type ||
			ASN_TIMETICKS == var->type || ASN_GAUGE == var->type)
#else
	else if (ASN_UINTEGER == var->type || ASN_COUNTER == var->type ||
			ASN_TIMETICKS == var->type || ASN_GAUGE == var->type)
#endif
	{
		SET_UI64_RESULT(result, (unsigned long)*var->val.integer);
	}
要するに、符号なしかCounterかGaugeで返さないと、符号反転するほうが仕様通りだと…A(^^;
ユーザー fripper の写真

ということは‥Net-SNMP側への修正要望として、挙げなくてはダメということですかね‥

31bit 値までならば、従来通りASN_INTEGER で正しく処理できるけれど、
32bit 値の場合には、せめて、ASN_UINTEGER のギリギリサイズの入れ物で返すようにしてもらうか
ASN_INTEGER64 / ASN_UNSIGNED64 等の余裕のある入れ物で返すようにしてもらうか‥ですかね‥

でも、MIB に対して、戻り値の型って決まっていて、仕様上・互換性上、簡単には変えられないはずですよね‥

ということは‥hrStorageSize64 のような、UI64 で戻り値が定義されるような、
新規の MIB を定義・実装してもらうしかない‥ということですか‥

厄介過ぎますね‥orz

ユーザー fripper の写真

net-snmp 側の情報を追いかけてみたところ、
http://sourceforge.net/p/net-snmp/bugs/1837/
を見つけました

5.3.x 系ではダメだけれど、5.4.2 で、AllocationUnits という値が導入されていて
AllocationUnits の値 x StorageSize の値 => 実際のストレージバイト数
となるように実装を変えるみたいですね‥

ユーザー TKSS の写真

fripperさん、KAZさん

ご教授ありがとうございます。

snmpで色々と試してみましたが、結局うまく行かないため、
監視対象のサーバでzabbixエージェントを動かして
vfs.fs.size[{#FSNAME},pfree] で空き容量を監視することにしました。

この度は色々とありがとうございました。
今後共よろしくお願いいたします。