Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 20db51d70e6b59a061db97ce9b89c771 > files > 52

net-snmp-5.3.2.2-14.el5.src.rpm

664523 - [RFE] Monitoring capabilities for >= 4 TB disks/partitions

Source: upstream, simple copy of disk.c from SVN rev. 17361 + backporting

diff -up net-snmp-5.3.2.2/agent/mibgroup/ucd-snmp/disk.c.dsktable-64 net-snmp-5.3.2.2/agent/mibgroup/ucd-snmp/disk.c
--- net-snmp-5.3.2.2/agent/mibgroup/ucd-snmp/disk.c.dsktable-64	2011-01-21 11:04:20.299445887 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/ucd-snmp/disk.c	2011-01-21 12:19:11.299159267 +0100
@@ -4,6 +4,12 @@
 
 #include <net-snmp/net-snmp-config.h>
 
+/* workaround for bug in autoconf 2.60b and 2.61 */
+#ifdef HAVE_GETMNTENT
+#undef HAVE_GETMNTENT
+#define HAVE_GETMNTENT 1 /* previously might be only "#define HAVE_GETMNTENT" */
+#endif
+
 #include <stdio.h>
 
 #if HAVE_STDLIB_H
@@ -135,7 +141,7 @@
 
 #include "struct.h"
 #include "disk.h"
-#include "util_funcs.h"
+#include "util_funcs.h"
 #if USING_UCD_SNMP_ERRORMIB_MODULE
 #include "errormib.h"
 #else
@@ -163,36 +169,58 @@ struct diskpart {
     int             minpercent;
 };
 
+#define MAX_INT_32 0x7fffffff
+#define MAX_UINT_32 0xffffffff
+
 int             numdisks;
 int             allDisksIncluded = 0;
 int             maxdisks = 0;
 struct diskpart *disks;
 
 struct variable2 extensible_disk_variables[] = {
-  {MIBINDEX, ASN_INTEGER, RONLY, var_extensible_disk, 1, {MIBINDEX}},
-  {ERRORNAME, ASN_OCTET_STR, RONLY, var_extensible_disk, 1, {ERRORNAME}},
-  {DISKDEVICE, ASN_OCTET_STR, RONLY, var_extensible_disk, 1,
-   {DISKDEVICE}},
-  {DISKMINIMUM, ASN_INTEGER, RONLY, var_extensible_disk, 1,
-   {DISKMINIMUM}},
-  {DISKMINPERCENT, ASN_INTEGER, RONLY, var_extensible_disk, 1,
-   {DISKMINPERCENT}},
-  {DISKTOTAL, ASN_INTEGER, RONLY, var_extensible_disk, 1, {DISKTOTAL}},
-  {DISKAVAIL, ASN_INTEGER, RONLY, var_extensible_disk, 1, {DISKAVAIL}},
-  {DISKUSED, ASN_INTEGER, RONLY, var_extensible_disk, 1, {DISKUSED}},
-  {DISKPERCENT, ASN_INTEGER, RONLY, var_extensible_disk, 1,
-   {DISKPERCENT}},
-  {DISKPERCENTNODE, ASN_INTEGER, RONLY, var_extensible_disk, 1,
-   {DISKPERCENTNODE}},
-  {ERRORFLAG, ASN_INTEGER, RONLY, var_extensible_disk, 1, {ERRORFLAG}},
-  {ERRORMSG, ASN_OCTET_STR, RONLY, var_extensible_disk, 1, {ERRORMSG}}
+  {MIBINDEX, ASN_INTEGER, RONLY,
+   var_extensible_disk, 1, {MIBINDEX}},
+  {ERRORNAME, ASN_OCTET_STR, RONLY,
+   var_extensible_disk, 1, {ERRORNAME}},
+  {DISKDEVICE, ASN_OCTET_STR, RONLY,
+   var_extensible_disk, 1, {DISKDEVICE}},
+  {DISKMINIMUM, ASN_INTEGER, RONLY,
+   var_extensible_disk, 1, {DISKMINIMUM}},
+  {DISKMINPERCENT, ASN_INTEGER, RONLY,
+   var_extensible_disk, 1, {DISKMINPERCENT}},
+  {DISKTOTAL, ASN_INTEGER, RONLY,
+   var_extensible_disk, 1, {DISKTOTAL}},
+  {DISKAVAIL, ASN_INTEGER, RONLY,
+   var_extensible_disk, 1, {DISKAVAIL}},
+  {DISKUSED, ASN_INTEGER, RONLY,
+   var_extensible_disk, 1, {DISKUSED}},
+  {DISKPERCENT, ASN_INTEGER, RONLY,
+   var_extensible_disk, 1, {DISKPERCENT}},
+  {DISKPERCENTNODE, ASN_INTEGER, RONLY,
+   var_extensible_disk, 1, {DISKPERCENTNODE}},
+  {ERRORFLAG, ASN_INTEGER, RONLY,
+   var_extensible_disk, 1, {ERRORFLAG}},
+  {ERRORMSG, ASN_OCTET_STR, RONLY,
+   var_extensible_disk, 1, {ERRORMSG}},
+   {DISKTOTALLOW, ASN_UNSIGNED, RONLY,
+    var_extensible_disk, 1, {DISKTOTALLOW}},
+   {DISKTOTALHIGH, ASN_UNSIGNED, RONLY,
+    var_extensible_disk, 1, {DISKTOTALHIGH}},
+   {DISKAVAILLOW, ASN_UNSIGNED, RONLY,
+    var_extensible_disk, 1, {DISKAVAILLOW}},
+   {DISKAVAILHIGH, ASN_UNSIGNED, RONLY,
+    var_extensible_disk, 1, {DISKAVAILHIGH}},
+   {DISKUSEDLOW, ASN_UNSIGNED, RONLY,
+    var_extensible_disk, 1, {DISKUSEDLOW}},
+   {DISKUSEDHIGH, ASN_UNSIGNED, RONLY,
+    var_extensible_disk, 1, {DISKUSEDHIGH}},
 };
 
 /*
  * Define the OID pointer to the top of the mib tree that we're
  * registering underneath 
  */
-oid             disk_variables_oid[] = { UCDAVIS_MIB, DISKMIBNUM, 1 };
+oid             disk_variables_oid[] = { UCDAVIS_MIB, DISKMIBNUM, 1 };
 
 void
 init_disk(void)
@@ -273,7 +301,7 @@ disk_parse_config(const char *token, cha
    * read optional minimum disk usage spec 
    */
   if(cptr != NULL) {
-      if(strchr(cptr, '%') == 0) {
+      if(strchr(cptr, '%') == NULL) {
           minspace = atoi(cptr);
           minpercent = -1;
       }
@@ -328,7 +356,7 @@ disk_parse_config_all(const char *token,
    * read the minimum disk usage percent
    */
   if(cptr != NULL) {
-      if(strchr(cptr, '%') != 0) {
+      if(strchr(cptr, '%') != NULL) {
           minpercent = atoi(cptr);
       }
   }
@@ -394,12 +422,12 @@ add_device(char *path, char *device, int
   else if(index == -1){
     /* add if and only if the device was found */
     if(device[0] != 0) {
-      struct diskpart *disk = &disks[numdisks];
-      /* Following buffers are cleared above, no need to add '\0' */
-      strncpy(disk->path, path, sizeof(disk->path)-1);
-      strncpy(disk->device, device, sizeof(disk->device)-1);
-      disk->minimumspace = minspace;
-      disk->minpercent   = minpercent;
+      /* The following buffers are cleared above, no need to add '\0' */
+      strncpy(disks[numdisks].path, path, sizeof(disks[numdisks].path) - 1);
+      strncpy(disks[numdisks].device, device,
+              sizeof(disks[numdisks].device) - 1);
+      disks[numdisks].minimumspace = minspace;
+      disks[numdisks].minpercent   = minpercent;
       numdisks++;  
     }
     else {
@@ -460,7 +488,12 @@ find_and_add_allDisks(int minpercent)
 #if HAVE_GETMNTENT
 #if HAVE_SETMNTENT
   mntfp = setmntent(ETC_MNTTAB, "r");
-  while (NULL != (mntent = getmntent(mntfp))) {
+  if (!mntfp) {
+      snprintf( tmpbuf, sizeof(tmpbuf), "Can't open %s (setmntent)\n", ETC_MNTTAB );
+      config_perror(tmpbuf);
+      return;
+  }
+  while (mntfp && NULL != (mntent = getmntent(mntfp))) {
     add_device(mntent->mnt_dir, mntent->mnt_fsname, -1, minpercent, 0);
     dummy = 1;
   }
@@ -473,6 +506,11 @@ find_and_add_allDisks(int minpercent)
   }
 #else                           /* getmentent but not setmntent */
   mntfp = fopen(ETC_MNTTAB, "r");
+  if (!mntfp) {
+      snprintf( tmpbuf, sizeof(tmpbuf), "Can't open %s (fopen)\n", ETC_MNTTAB );
+      config_perror(tmpbuf);
+      return;
+  }
   while ((i = getmntent(mntfp, &mnttab)) == 0) {
     add_device(mnttab.mnt_mountp, mnttab.mnt_special, -1, minpercent, 0);
     dummy = 1;
@@ -557,10 +595,15 @@ find_device(char *path)
 #if HAVE_GETMNTENT
 #if HAVE_SETMNTENT
   mntfp = setmntent(ETC_MNTTAB, "r");
-  while (NULL != (mntent = getmntent(mntfp)))
+  if (!mntfp) {
+      snprintf( tmpbuf, sizeof(tmpbuf), "Can't open %s (setmntent)\n", ETC_MNTTAB );
+      config_perror(tmpbuf);
+      return NULL;
+  }
+  while (mntfp && NULL != (mntent = getmntent(mntfp)))
     if (strcmp(path, mntent->mnt_dir) == 0) {
-      copy_nword(mntent->mnt_fsname, device,
-		 sizeof(device));
+      strncpy(device, mntent->mnt_fsname, sizeof(device));
+      device[sizeof(device) - 1] = '\0';
       DEBUGMSGTL(("ucd-snmp/disk", "Disk:  %s\n",
 		  mntent->mnt_fsname));
       break;
@@ -572,6 +615,11 @@ find_device(char *path)
     endmntent(mntfp);
 #else                           /* getmentent but not setmntent */
   mntfp = fopen(ETC_MNTTAB, "r");
+  if (!mntfp) {
+      snprintf( tmpbuf, sizeof(tmpbuf), "Can't open %s (fopen)\n", ETC_MNTTAB );
+      config_perror(tmpbuf);
+      return NULL;
+  }
   while ((i = getmntent(mntfp, &mnttab)) == 0)
     if (strcmp(path, mnttab.mnt_mountp) == 0)
       break;
@@ -581,16 +629,16 @@ find_device(char *path)
     }
   fclose(mntfp);
   if (i == 0) {
-    copy_nword(mnttab.mnt_special, device,
-	       sizeof(device));
+    strncpy(device, mnttab.mnt_special, sizeof(device));
+    device[sizeof(device) - 1] = '\0';
   }
 #endif /* HAVE_SETMNTENT */
 #elif HAVE_FSTAB_H
   stat(path, &stat1);
   setfsent();
   if ((fstab = getfsfile(path))) {
-    copy_nword(fstab->fs_spec, device,
-	       sizeof(device));
+    strncpy(device, fstab->fs_spec, sizeof(device));
+    device[sizeof(device) - 1] = '\0';
   }
   endfsent();
   if (device[0] != '\0') {
@@ -601,7 +649,8 @@ find_device(char *path)
 
 #elif HAVE_STATFS
   if (statfs(path, &statf) == 0) {
-    copy_nword(statf.f_mntfromname, device, sizeof(device));
+    strncpy(device, statf.f_mntfromname, sizeof(device) - 1);
+    device[sizeof(device) - 1] = '\0';
     DEBUGMSGTL(("ucd-snmp/disk", "Disk:  %s\n",
 		statf.f_mntfromname));
   }
@@ -617,38 +666,31 @@ find_device(char *path)
   return device;
 }
 
-
 /*
- * var_extensible_disk(...
- * Arguments:
- * vp     IN      - pointer to variable entry that points here
- * name    IN/OUT  - IN/name requested, OUT/name found
- * length  IN/OUT  - length of IN/OUT oid's 
- * exact   IN      - TRUE if an exact match was requested
- * var_len OUT     - length of variable or 0 if function returned
- * write_method
- * 
+ * Part of UCD-SNMP-MIB::dskEntry, which is so hard to fill 
+ * (i.e. platform dependent parts).
+ */
+struct dsk_entry {
+    unsigned long long  dskTotal;
+    unsigned long long  dskUsed;
+    unsigned long long  dskAvail;
+    unsigned long       dskPercent;
+    unsigned long       dskPercentInode;
+    unsigned long       dskErrorFlag;
+};
+
+/**
+ * Fill in the provided dsk_entry structure.
+ * Returns -1 on error, 0 on success.
  */
-u_char         *
-var_extensible_disk(struct variable *vp,
-                    oid * name,
-                    size_t * length,
-                    int exact,
-                    size_t * var_len, WriteMethod ** write_method)
-{
 
-    int             percent, iserror, disknum = 0;
+static int
+fill_dsk_entry(int disknum, struct dsk_entry *entry)
+{
+    float           multiplier;
 #if !defined(HAVE_SYS_STATVFS_H) && !defined(HAVE_STATFS)
     double          totalblks, free, used, avail, availblks;
-#else
-    static long     avail;
-#if defined(STRUCT_STATVFS_HAS_F_FILES) || defined(STRUCT_STATFS_HAS_F_FILES)
-    int             percent_inode;
-#endif
 #endif
-    static long     long_ret;
-    static char     errmsg[300];
-    float           multiplier;
 
 #if defined(HAVE_STATVFS) || defined(HAVE_STATFS)
 #ifdef STAT_STATFS_FS_DATA
@@ -670,28 +712,8 @@ var_extensible_disk(struct variable *vp,
 #endif
 #endif
 
-tryAgain:
-    if (header_simple_table
-        (vp, name, length, exact, var_len, write_method, numdisks))
-        return (NULL);
-    disknum = name[*length - 1] - 1;
-    switch (vp->magic) {
-    case MIBINDEX:
-        long_ret = disknum + 1;
-        return ((u_char *) (&long_ret));
-    case ERRORNAME:            /* DISKPATH */
-        *var_len = strlen(disks[disknum].path);
-        return ((u_char *) disks[disknum].path);
-    case DISKDEVICE:
-        *var_len = strlen(disks[disknum].device);
-        return ((u_char *) disks[disknum].device);
-    case DISKMINIMUM:
-        long_ret = disks[disknum].minimumspace;
-        return ((u_char *) (&long_ret));
-    case DISKMINPERCENT:
-        long_ret = disks[disknum].minpercent;
-        return ((u_char *) (&long_ret));
-    }
+    entry->dskPercentInode = -1;
+
 #if defined(HAVE_STATVFS) || defined(HAVE_STATFS)
 #ifdef STAT_STATFS_FS_DATA
     if (statvfs(disks[disknum].path, &fsd) == -1)
@@ -702,9 +724,7 @@ tryAgain:
         snmp_log(LOG_ERR, "Couldn't open device %s\n",
                  disks[disknum].device);
         setPerrorstatus("statvfs dev/disk");
-        if (!exact)
-            goto tryAgain;
-        return NULL;
+        return -1;
     }
 #ifdef STAT_STATFS_FS_DATA
     vfs.f_blocks = fsd.fd_btot;
@@ -717,71 +737,37 @@ tryAgain:
     vfs.f_bfree = vfs.f_spare[1];
     vfs.f_bavail = vfs.f_spare[2];
 #endif
-    percent = 
+
+    multiplier = (float)vfs.f_bsize / (float)1024.0;
+#ifdef HAVE_STRUCT_STATVFS_F_FRSIZE
+    if (vfs.f_frsize > 255)
+        multiplier = (float)vfs.f_frsize / (float)1024.0;
+#endif
+
+    entry->dskTotal = (unsigned long long)(vfs.f_blocks * multiplier);
+    entry->dskAvail = (unsigned long long)(vfs.f_bavail * multiplier);
+    entry->dskUsed = (unsigned long long)((vfs.f_blocks - vfs.f_bfree) * multiplier);
+
+    entry->dskPercent = 
         vfs.f_blocks == 0 ? 0 :
         vfs.f_bavail <= 0 ? 100 :
         (int) ((double) (vfs.f_blocks - vfs.f_bfree) /
                (double) (vfs.f_blocks -
                          (vfs.f_bfree - vfs.f_bavail)) * 100.0 + 0.5);
-    multiplier = (float)vfs.f_bsize / (float)1024.0;
-#ifdef STRUCT_STATVFS_HAS_F_FRSIZE
-    if (vfs.f_frsize > 255)
-        multiplier = (float)vfs.f_frsize / (float)1024.0;
-#endif
-    avail = (long)(vfs.f_bavail * multiplier);
-    iserror = (disks[disknum].minimumspace >= 0 ?
-               avail < disks[disknum].minimumspace :
-               100 - percent <= disks[disknum].minpercent) ? 1 : 0;
-#if defined(STRUCT_STATVFS_HAS_F_FILES) || defined STRUCT_STATFS_HAS_F_FAVAIL
-    percent_inode = vfs.f_favail <= 0 ? 100 :
+
+#if defined(HAVE_STRUCT_STATVFS_F_FILES) || defined HAVE_STRUCT_STATFS_F_FAVAIL
+    entry->dskPercentInode = vfs.f_favail <= 0 ? 100 :
         (int) ((double) (vfs.f_files - vfs.f_ffree) /
                (double) (vfs.f_files -
                          (vfs.f_ffree - vfs.f_favail)) * 100.0 + 0.5);
 #else
-#if defined(STRUCT_STATFS_HAS_F_FILES) && defined(STRUCT_STATFS_HAS_F_FFREE)
-   percent_inode = vfs.f_files == 0 ? 100.0 :
+#if defined(HAVE_STRUCT_STATFS_F_FILES) && defined(HAVE_STRUCT_STATFS_F_FFREE)
+    entry->dskPercentInode = vfs.f_files == 0 ? 100.0 :
       (int) ((double) (vfs.f_files - vfs.f_ffree) /
-	          (double) (vfs.f_files) * 100.0 + 0.5);
+              (double) (vfs.f_files) * 100.0 + 0.5);
 #endif 
-#endif /* defined(STRUCT_STATVFS_HAS_F_FILES) */ 
-    switch (vp->magic) {
-    case DISKTOTAL:
-        long_ret = (long)(vfs.f_blocks * multiplier);
-        return ((u_char *) (&long_ret));
-    case DISKAVAIL:
-        return ((u_char *) (&avail));
-    case DISKUSED:
-        long_ret = (long)((vfs.f_blocks - vfs.f_bfree) * multiplier);
-        return ((u_char *) (&long_ret));
-    case DISKPERCENT:
-        long_ret = percent;
-        return ((u_char *) (&long_ret));
-#if defined(STRUCT_STATVFS_HAS_F_FILES) || defined (STRUCT_STATFS_HAS_F_FILES)
-    case DISKPERCENTNODE:
-        long_ret = percent_inode;
-        return ((u_char *) (&long_ret));
-#endif
-    case ERRORFLAG:
-        long_ret = iserror;
-        return ((u_char *) (&long_ret));
-    case ERRORMSG:
-        if (iserror) {
-            if (disks[disknum].minimumspace >= 0)
-                snprintf(errmsg, sizeof(errmsg),
-                        "%s: less than %d free (= %d)",
-                        disks[disknum].path, disks[disknum].minimumspace,
-                        (int) avail);
-            else
-                snprintf(errmsg, sizeof(errmsg),
-                        "%s: less than %d%% free (= %d%%)",
-                        disks[disknum].path, disks[disknum].minpercent,
-                        percent);
-            errmsg[ sizeof(errmsg)-1 ] = 0;
-        } else
-            errmsg[0] = 0;
-        *var_len = strlen(errmsg);
-        return ((u_char *) (errmsg));
-    }
+#endif /* defined(HAVE_STRUCT_STATVFS_F_FILES) */
+
 #else
 #if HAVE_FSTAB_H
     /*
@@ -791,9 +777,7 @@ tryAgain:
         snmp_log(LOG_ERR, "Couldn't open device %s\n",
                  disks[disknum].device);
         setPerrorstatus("open dev/disk");
-        if (!exact)
-            goto tryAgain;
-        return (NULL);
+        return -1;
     }
     lseek(file, (long) (SBLOCK * DEV_BSIZE), 0);
     if (read(file, (char *) &filesys, SBSIZE) != SBSIZE) {
@@ -801,61 +785,160 @@ tryAgain:
         snmp_log(LOG_ERR, "Error reading device %s\n",
                  disks[disknum].device);
         close(file);
-        if (!exact)
-            goto tryAgain;
-        return (NULL);
+        return -1;
     }
     close(file);
+
     totalblks = filesys.fs_dsize;
     free = filesys.fs_cstotal.cs_nbfree * filesys.fs_frag +
         filesys.fs_cstotal.cs_nffree;
     used = totalblks - free;
     availblks = totalblks * (100 - filesys.fs_minfree) / 100;
     avail = availblks > used ? availblks - used : 0;
-    percent =
+    entry->dskPercent =
         totalblks == 0 ? 0 :
         availblks == 0 ? 100 :
         (int) ((double) used / (double) totalblks * 100.0 + 0.5);
     multiplier = (float)filesys.fs_fsize / (float)1024.0;
-    iserror =
+    entry->dskTotal = (unsigned long long)(totalblks * multiplier);
+    entry->dskAvail = (unsigned long long)(avail * multiplier);
+    entry->dskUsed = (unsigned long long)(used * multiplier);
+#endif
+#endif
+
+    entry->dskErrorFlag =
         (disks[disknum].minimumspace >= 0
-            ? avail * multiplier < disks[disknum].minimumspace
-            : 100 - percent <= disks[disknum].minpercent) ? 1 : 0;
+            ? entry->dskAvail < disks[disknum].minimumspace
+            : 100 - entry->dskPercent <= disks[disknum].minpercent) ? 1 : 0;
+
+    return 0;
+}
+
+/*
+ * var_extensible_disk(...
+ * Arguments:
+ * vp     IN      - pointer to variable entry that points here
+ * name    IN/OUT  - IN/name requested, OUT/name found
+ * length  IN/OUT  - length of IN/OUT oid's 
+ * exact   IN      - TRUE if an exact match was requested
+ * var_len OUT     - length of variable or 0 if function returned
+ * write_method
+ * 
+ */
+u_char         *
+var_extensible_disk(struct variable *vp,
+                    oid * name,
+                    size_t * length,
+                    int exact,
+                    size_t * var_len, WriteMethod ** write_method)
+{
+    int             ret, disknum = 0;
+    struct dsk_entry entry;
+    static long     long_ret;
+    static char     errmsg[300];
+
+tryAgain:
+    if (header_simple_table
+        (vp, name, length, exact, var_len, write_method, numdisks))
+        return (NULL);
+    disknum = name[*length - 1] - 1;
+    switch (vp->magic) {
+    case MIBINDEX:
+        long_ret = disknum + 1;
+        return ((u_char *) (&long_ret));
+    case ERRORNAME:            /* DISKPATH */
+        *var_len = strlen(disks[disknum].path);
+        return ((u_char *) disks[disknum].path);
+    case DISKDEVICE:
+        *var_len = strlen(disks[disknum].device);
+        return ((u_char *) disks[disknum].device);
+    case DISKMINIMUM:
+        long_ret = disks[disknum].minimumspace;
+        return ((u_char *) (&long_ret));
+    case DISKMINPERCENT:
+        long_ret = disks[disknum].minpercent;
+        return ((u_char *) (&long_ret));
+    }
+
+    ret = fill_dsk_entry(disknum, &entry);
+    if (ret < 0) {
+        if (!exact)
+            goto tryAgain;
+        return NULL;
+    }
+
     switch (vp->magic) {
     case DISKTOTAL:
-        long_ret = (long)(totalblks * multiplier);
+        if (entry.dskTotal > MAX_INT_32)
+            long_ret = MAX_INT_32;
+        else
+            long_ret = (long)(entry.dskTotal);
+        return ((u_char *) (&long_ret));
+    case DISKTOTALLOW:
+        long_ret = entry.dskTotal & MAX_UINT_32;
         return ((u_char *) (&long_ret));
+    case DISKTOTALHIGH:
+        long_ret = entry.dskTotal >> 32;
+        return ((u_char *) (&long_ret));
+        
     case DISKAVAIL:
-        long_ret = (long)(avail * multiplier);
+        if (entry.dskAvail > MAX_INT_32)
+            long_ret = MAX_INT_32;
+        else
+            long_ret = (long)(entry.dskAvail);
+        return ((u_char *) (&long_ret));
+    case DISKAVAILLOW:
+        long_ret = entry.dskAvail & MAX_UINT_32;
+        return ((u_char *) (&long_ret));
+    case DISKAVAILHIGH:
+        long_ret = entry.dskAvail >> 32;
         return ((u_char *) (&long_ret));
+
     case DISKUSED:
-        long_ret = (long)(used * multiplier);
+        if (entry.dskUsed > MAX_INT_32)
+            long_ret = MAX_INT_32;
+        else
+            long_ret = (long)(entry.dskUsed);
+        return ((u_char *) (&long_ret));
+    case DISKUSEDLOW:
+        long_ret = entry.dskUsed & MAX_UINT_32;
+        return ((u_char *) (&long_ret));
+    case DISKUSEDHIGH:
+        long_ret = entry.dskUsed >> 32;
         return ((u_char *) (&long_ret));
+
     case DISKPERCENT:
-        long_ret = percent;
+        long_ret = entry.dskPercent;
         return ((u_char *) (&long_ret));
+
+    case DISKPERCENTNODE:
+        if (entry.dskPercentInode >= 0) {
+            long_ret = entry.dskPercentInode;
+            return ((u_char *) (&long_ret));
+        } else
+            return NULL;
+
     case ERRORFLAG:
-        long_ret = iserror;
+        long_ret = entry.dskErrorFlag;
         return ((u_char *) (&long_ret));
+
     case ERRORMSG:
-        if (iserror) {
+        if (entry.dskErrorFlag) {
             if (disks[disknum].minimumspace >= 0)
                 snprintf(errmsg, sizeof(errmsg),
                         "%s: less than %d free (= %d)",
                         disks[disknum].path, disks[disknum].minimumspace,
-                        avail * filesys.fs_fsize / 1024);
+                        (int) entry.dskAvail);
             else
                 snprintf(errmsg, sizeof(errmsg),
                         "%s: less than %d%% free (= %d%%)",
                         disks[disknum].path, disks[disknum].minpercent,
-                        percent);
+                        (int)entry.dskPercent);
             errmsg[ sizeof(errmsg)-1 ] = 0;
         } else
             errmsg[0] = 0;
         *var_len = strlen(errmsg);
         return ((u_char *) (errmsg));
     }
-#endif
-#endif
     return NULL;
 }
diff -up net-snmp-5.3.2.2/agent/mibgroup/ucd-snmp/disk.h.dsktable-64 net-snmp-5.3.2.2/agent/mibgroup/ucd-snmp/disk.h
--- net-snmp-5.3.2.2/agent/mibgroup/ucd-snmp/disk.h.dsktable-64	2004-02-03 10:56:07.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/ucd-snmp/disk.h	2011-01-21 11:09:56.000000000 +0100
@@ -7,7 +7,7 @@
 
 void            init_disk(void);
 
-config_require(util_funcs)
+config_require(util_funcs)
 
      extern FindVarMethod var_extensible_disk;
 
@@ -21,5 +21,11 @@ config_require(util_funcs)
 #define DISKUSED 8
 #define DISKPERCENT 9
 #define DISKPERCENTNODE 10
+#define DISKTOTALLOW 11
+#define DISKTOTALHIGH 12
+#define DISKAVAILLOW 13
+#define DISKAVAILHIGH 14
+#define DISKUSEDLOW 15
+#define DISKUSEDHIGH 16
 
 #endif                          /* _MIBGROUP_DISK_H */
diff -up net-snmp-5.3.2.2/mibs/UCD-SNMP-MIB.txt.dsktable-64 net-snmp-5.3.2.2/mibs/UCD-SNMP-MIB.txt
--- net-snmp-5.3.2.2/mibs/UCD-SNMP-MIB.txt.dsktable-64	2007-04-20 10:21:23.000000000 +0200
+++ net-snmp-5.3.2.2/mibs/UCD-SNMP-MIB.txt	2011-01-21 11:04:20.827454898 +0100
@@ -629,6 +629,60 @@ dskPercentNode OBJECT-TYPE
 	"Percentage of inodes used on disk"
     ::= { dskEntry 10 } 
 
+dskTotalLow OBJECT-TYPE
+    SYNTAX	Unsigned32
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION  
+	"Total size of the disk/partion (kBytes).
+	Together with dskTotalHigh composes 64-bit number."
+    ::= { dskEntry 11 }
+
+dskTotalHigh OBJECT-TYPE
+    SYNTAX	Unsigned32
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION  
+	"Total size of the disk/partion (kBytes).
+	Together with dskTotalLow composes 64-bit number."
+    ::= { dskEntry 12 }
+
+dskAvailLow OBJECT-TYPE
+    SYNTAX	Unsigned32
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION  
+	"Available space on the disk (kBytes).
+	Together with dskAvailHigh composes 64-bit number."
+    ::= { dskEntry 13 }
+
+dskAvailHigh OBJECT-TYPE
+    SYNTAX	Unsigned32
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION  
+	"Available space on the disk (kBytes).
+	Together with dskAvailLow composes 64-bit number."
+    ::= { dskEntry 14 }
+
+dskUsedLow OBJECT-TYPE
+    SYNTAX	Unsigned32
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION  
+	"Used space on the disk (kBytes).
+	Together with dskUsedHigh composes 64-bit number."
+    ::= { dskEntry 15 }
+
+dskUsedHigh OBJECT-TYPE
+    SYNTAX	Unsigned32
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION  
+	"Used space on the disk (kBytes).
+	Together with dskUsedLow composes 64-bit number."
+    ::= { dskEntry 16 }
+
 dskErrorFlag OBJECT-TYPE
     SYNTAX	Integer32
     MAX-ACCESS	read-only