bin/177183: [bsnmpd] [patch] snmp_hostres modules does not support FS over 1TB
Eugene Grosbein
egrosbein at rdtc.ru
Thu Mar 21 09:40:01 UTC 2013
>Number: 177183
>Category: bin
>Synopsis: [bsnmpd] [patch] snmp_hostres modules does not support FS over 1TB
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Mar 21 09:40:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator: Eugene Grosbein
>Release: FreeBSD 8.3-STABLE i386
>Organization:
RDTC JSC
>Environment:
System: FreeBSD eg.sd.rdtc.ru 8.3-STABLE FreeBSD 8.3-STABLE #53: Wed Feb 13 18:22:34 NOVT 2013 root at eg.sd.rdtc.ru:/usr/local/obj/usr/local/src/sys/EG i386
>Description:
bsnmp(1) has snmp_hostres module to support HOSTRES MIB.
This SNMP MIB's hrStorageTable limits hrStorageSize and hrStorageUsed
parameters to 32 bit integer values, so file systems having more
than 2^31 allocation units cannot be shown correctly.
Let us follow net-snmp behaviour that (since 2011) translates
hrStorageSize/hrStorageUsed/hrStorageAllocationUnits triples
so that hrStorageAllocationUnits get bigger and other fit
under INT_MAX by default.
>How-To-Repeat:
This demonstrates the problem using holey file to mimic
3TB file system (this needs 18GB free in real fs):
# truncate -s 3T f
# mdconfig -af f
md0
# newfs -O2 -b 4096 -f 512 -i $((1024*1024*1024)) /dev/md0 >/dev/null
# mount /dev/md0 /mnt/tmp
# rmdir /mnt/tmp/.snap; dd if=/dev/zero bs=2048 count=1000 of=/mnt/tmp/f2
# df -k /mnt/tmp
Filesystem 1024-blocks Used Avail Capacity Mounted on
/dev/md0 3217454200 2004 2960055860 0% /mnt/tmp
Then look at snmpwalk's output and see hrStorageAllocationUnits
equals to 512 (fsize) and hrStorageSize is truncated to 2^31-1.
With the following patch you get result consistent with net-snmp:
HOST-RESOURCES-MIB::hrStorageType.393 = OID: HOST-RESOURCES-TYPES::hrFSBerkeleyFFS
HOST-RESOURCES-MIB::hrStorageDescr.393 = STRING: /mnt/tmp, type: ufs, dev: /dev/md0
HOST-RESOURCES-MIB::hrStorageAllocationUnits.393 = INTEGER: 2048 Bytes
HOST-RESOURCES-MIB::hrStorageSize.393 = INTEGER: 1608727100
HOST-RESOURCES-MIB::hrStorageUsed.393 = INTEGER: 1002
SNMP's data 2048*1608727100=3294673100800 equals to df's data:
1024*3217454200=3294673100800
>Fix:
--- usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c.orig 2013-03-21 13:42:16.000000000 +0700
+++ usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c 2013-03-21 14:15:51.000000000 +0700
@@ -442,7 +442,9 @@
storage_OS_get_fs(void)
{
struct storage_entry *entry;
- uint64_t used_blocks_count = 0;
+ uint64_t block_size = 0;
+ uint64_t free_blocks_count = 0;
+ uint64_t total_blocks_count = 0;
char fs_string[SE_DESC_MLEN];
int mounted_fs_count;
int i = 0;
@@ -473,6 +475,8 @@
fs_tbl_pre_refresh();
for (i = 0; i < mounted_fs_count; i++) {
+ int shift = 0;
+
snprintf(fs_string, sizeof(fs_string),
"%s, type: %s, dev: %s", fs_buf[i].f_mntonname,
fs_buf[i].f_fstypename, fs_buf[i].f_mntfromname);
@@ -488,23 +492,22 @@
entry->flags |= HR_STORAGE_FOUND;
entry->type = fs_get_type(&fs_buf[i]); /*XXX - This is wrong*/
- if (fs_buf[i].f_bsize > INT_MAX)
- entry->allocationUnits = INT_MAX;
- else
- entry->allocationUnits = fs_buf[i].f_bsize;
-
- if (fs_buf[i].f_blocks > INT_MAX)
- entry->size = INT_MAX;
- else
- entry->size = fs_buf[i].f_blocks;
-
- used_blocks_count = fs_buf[i].f_blocks - fs_buf[i].f_bfree;
-
- if (used_blocks_count > INT_MAX)
- entry->used = INT_MAX;
- else
- entry->used = used_blocks_count;
+ total_blocks_count = fs_buf[i].f_blocks;
+ block_size = fs_buf[i].f_bsize;
+ free_blocks_count = fs_buf[i].f_bfree;
+
+ while (total_blocks_count > INT_MAX) {
+ total_blocks_count >>= 1;
+ shift++;
+ }
+ if (shift) {
+ block_size <<= shift;
+ free_blocks_count >>= shift;
+ }
+ entry->size = total_blocks_count;
+ entry->allocationUnits = block_size;
+ entry->used = total_blocks_count - free_blocks_count;
entry->allocationFailures = 0;
/* take care of hrFSTable */
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list