本文记录的是如何使用 64-bit 的mib计算Linux设备的存储大小。

为了解决snmp采集大容量(>2T)Linux设备时dskTotal越界的问题, 在snmp5.5+版本中引入了64bit的mibs, 包括 (UCD-SNMP-MIB::dskTotalLow,UCD-SNMP-MIB::dskTotalHigh),(UCD-SNMP-MIB::dskAvailLow,UCD-SNMP-MIB::dskAvailHigh),(UCD-SNMP-MIB::dskUsedLow,UCD-SNMP-MIB::dskUsedHigh), 那么如何利用64bit的mibs计算存储大小呢?

先看看dskTotalLow的说明:

1
2
3
4
5
6
7
8
9
10
CaryaLiu-MacBook-Pro:gitblog carya$ snmptranslate -On -Td UCD-SNMP-MIB::dskTotalLow
.1.3.6.1.4.1.2021.9.1.11
dskTotalLow OBJECT-TYPE
-- FROM UCD-SNMP-MIB
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Total size of the disk/partion (kBytes).
Together with dskTotalHigh composes 64-bit number."
::= { iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) ucdavis(2021) dskTable(9) dskEntry(1) 11 }

从说明中可以看出,要计算Linux设备的存储大小,需要将dskTotalLow的低32位与dskTotalHigh的高32位组合起来,怎么处理呢,看下面的例子。

例如,采集到如下数据:

1
2
UCD-SNMP-MIB::dskTotalLow.1 = Gauge32: 1071652864
UCD-SNMP-MIB::dskTotalHigh.1 = Gauge32: 11

低32位转换为十六进制为0x3FE0 2000(=1,071,652,864),高32位转换为十六进制为0x0B(=11),将它们组合起来就是0x0B 3FE0 2000, 然后再将其转换为10进制就得到了设备的存储大小了。

使用Java处理如下:

1
2
3
4
5
6
7
8
9
Long dskTotalLow = 1071652864L;
Long dskTotalHigh = 11L;

String dskTotalLowStr = Long.toHexString(dskTotalLow);
String dskTotalHighStr = Long.toHexString(dskTotalHigh);

Long dskTotal = Long.parseLong(dskTotalHighStr + dskTotalLowStr, 16);
System.out.println("the size of disk is " + dskTotal + "kBytes.");
System.out.printf("the size of disk is %d G", dskTotal/1024/1024);

控制台输出内容如下:

1
2
the size of disk is 48316293120kBytes.
the size of disk is 46078 G

参考: SNMP UCD dskTotalLow + dskTotalHigh