components/net-snmp/patches/027.7118090.hr_filesys.patch
branchs11u2-sru
changeset 4013 29dc96079508
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/net-snmp/patches/027.7118090.hr_filesys.patch	Tue Mar 24 10:15:01 2015 -0700
@@ -0,0 +1,253 @@
+This fix has been submitted upstream as part of a combined patch
+which has fixes for this CR (15758982) and another CR (16439911)
+with corresponding patch 048.16439911.hr_filesys.patch 
+This can be found in the following location.
+https://sourceforge.net/p/net-snmp/patches/1287/.
+
+This patch has not been accepted yet.
+/*
+ *  This patch fixes the performance issue observed while retrieving the
+ *  hrStorage parameters in systems with large number of mountpoints
+ *  parameters using snmpwalk.
+ *
+ *  This issue is happening due to the overhead of large number of
+ *  ioctl() system calls in getmntent() function called by the
+ *  Get_Next_HR_FileSys() function.
+ *
+ *  We see that in the Get_Next_HR_FileSys() function, inorder to access
+ *  the last mountpoint, the /etc/mnttab is opened and we walk through
+ *  all the mnttab entries for all filesystems till the end. This is the
+ *  reason we find a large number of the MNTIOC_GETMNTENT ioctl() calls.
+ *
+ *  To reduce the overhead of the getmntent() calls, we maintain a cache
+ *  of all the /etc/mnttab entries and walk through the cache instead of
+ *  opening /etc/mnttab and walking all the entries for each mountpoint.
+ *  This functionality is provided by the load_mnttab_cache_solaris()
+ *  function called from the Init_HR_FileSys() function.
+ */
+--- net-snmp-5.4.1.orig/agent/mibgroup/host/hr_filesys.c	2007-05-18 11:08:01.000000000 -0700
++++ net-snmp-5.4.1/agent/mibgroup/host/hr_filesys.c	2013-01-17 03:36:28.181493003 -0800
+@@ -31,6 +31,10 @@
+ #include <sys/mount.h>
+ #endif
+ 
++#ifdef solaris2
++#include <sys/stat.h>
++#endif
++
+ #include <ctype.h>
+ #if HAVE_STRING_H
+ #include <string.h>
+@@ -85,7 +89,11 @@
+ #ifdef solaris2
+ 
+ struct mnttab   HRFS_entry_struct;
+-struct mnttab  *HRFS_entry = &HRFS_entry_struct;
++struct mnttab  *HRFS_entry;
++struct mnttab	*HRFS_list;
++static int fscount;
++static time_t last_access = -1;
++
+ #define	HRFS_name	mnt_special
+ #define	HRFS_mount	mnt_mountp
+ #define	HRFS_type	mnt_fstype
+@@ -167,6 +175,9 @@
+ static u_char  *when_dumped(char *filesys, int level, size_t * length);
+ int             header_hrfilesys(struct variable *, oid *, size_t *, int,
+                                  size_t *, WriteMethod **);
++#ifdef solaris2
++static int      load_mnttab_cache_solaris(void);
++#endif
+ 
+         /*********************
+ 	 *
+@@ -606,8 +617,14 @@
+     HRFS_index = 1;
+     if (fp != NULL)
+         fclose(fp);
++#ifdef solaris2
++    if(!load_mnttab_cache_solaris())
++        return;
++#else    
+     fp = fopen(ETC_MNTTAB, "r");
+ #endif
++
++#endif
+ }
+ 
+ const char     *HRFS_ignores[] = {
+@@ -663,6 +680,117 @@
+     0
+ };
+ 
++#ifdef solaris2
++
++/*
++ *  This function has been introduced to reduce the overhead
++ *  of the getmntent() calls used to fetch the details of
++ *  the /etc/mnttab entries in Init_HR_FileSys().
++ *
++ *  We maintain a cache of all the /etc/mnttab entries and
++ *  walk through the cache instead of opening /etc/mnttab and
++ *  walking all the entries for each mountpoint.
++ */
++
++static int 
++load_mnttab_cache_solaris()
++{
++    char buf[512] = {NULL};
++    int i = 0;
++    struct stat file_stat;
++    const char **cpp;
++    char *ch;
++    int token_flag = 0;
++    int skip_flag = 0;
++    int ignore_flag = 0;
++    int j = 0;
++    int lines = 0;
++    int ret = 0;
++    HRFS_index = 0;
++
++    stat(ETC_MNTTAB, &file_stat);
++    if (last_access == -1 || last_access != file_stat.st_mtime) {
++        fp = fopen(ETC_MNTTAB, "r");
++        if(fp == NULL)
++        {
++            DEBUGMSGTL(("host/hr_filesys", "fopen failed for mnttab.\n"));
++            return -1;
++        }
++        
++        /* find the number of valid entries in mnttab. */
++        
++        while ((fgets((char *) &buf, sizeof(buf), fp)) != NULL) {
++            j = 0;
++            skip_flag = 0;
++            token_flag = 0;
++
++            /* tokenize the mnttab entries to fetch the fstype
++             * which determines the valid entries.
++             */
++
++            ch = strtok(buf, " \t");
++            while (ch != NULL) {
++                j++;
++                if(j == 3) {
++                    for (cpp = HRFS_ignores; *cpp != NULL; ++cpp) {
++                        if(!strncmp(ch, *cpp, strlen(ch))) {
++                            skip_flag = 1;
++                            break;
++                        }
++                    }
++                    token_flag = 1;
++                }
++                if(token_flag)
++                    break;
++                ch = strtok(NULL, " \t");
++             }
++             if(!skip_flag)
++                 lines++;
++        }
++        fclose(fp);
++
++        fscount = lines;
++        HRFS_list = (struct mnttab *) malloc (sizeof(struct mnttab) * fscount);
++        if(HRFS_list == NULL) {
++            DEBUGMSGTL(("host/hr_filesys", "Memory allocation for mnttab cache failed.\n"));
++            return -1;
++        }
++
++        fp = fopen(ETC_MNTTAB, "r");
++        if(fp == NULL) {
++            DEBUGMSGTL(("host/hr_filesys", "fopen failed for mnttab.\n"));
++            free(HRFS_list);
++            return -1;
++        }
++
++        while (i < fscount) {
++            if (getmntent(fp, &HRFS_entry_struct) == 0) {
++                 for (cpp = HRFS_ignores; *cpp != NULL; ++cpp) {
++                     if (!strcmp(HRFS_entry_struct.HRFS_type, *cpp)) {
++                         ignore_flag = 1;
++                         break;
++                     }
++                 }
++
++                 if(!ignore_flag) {
++                     HRFS_list[i].mnt_special = strdup(HRFS_entry_struct.mnt_special);
++                     HRFS_list[i].mnt_mountp = strdup(HRFS_entry_struct.mnt_mountp);
++                     HRFS_list[i].mnt_fstype = strdup(HRFS_entry_struct.mnt_fstype);
++                     HRFS_list[i].mnt_mntopts = strdup(HRFS_entry_struct.mnt_mntopts);
++                     i++;
++                 }
++
++                 ignore_flag = 0;
++            }
++        }
++
++        HRFS_entry = HRFS_list;
++        last_access = file_stat.st_mtime;
++    }
++    return ret;
++}
++#endif
++
+ int
+ Get_Next_HR_FileSys(void)
+ {
+@@ -699,17 +827,18 @@
+ #else
+     const char    **cpp;
+ 
+-    if (fp == NULL)
+-        return -1;
+ 
+ #ifdef solaris2
+-    if (getmntent(fp, HRFS_entry) != 0)
++    if (HRFS_index >= fscount)
+         return -1;
++    HRFS_entry = &HRFS_list[HRFS_index];
++        return ++HRFS_index;
+ #else
++    if (fp == NULL)
++        return -1;
+     HRFS_entry = getmntent(fp);
+     if (HRFS_entry == NULL)
+         return -1;
+-#endif                          /* solaris2 */
+ 
+     for (cpp = HRFS_ignores; *cpp != NULL; ++cpp)
+         if (!strcmp(HRFS_entry->HRFS_type, *cpp))
+@@ -728,6 +857,8 @@
+     }
+ 
+     return HRFS_index++;
++#endif
++
+ #endif                          /* HAVE_GETFSSTAT */
+ }
+ 
+@@ -791,9 +922,24 @@
+         HRFS_entry = NULL;
+     }
+ #else
++    int i = 0;
+     if (fp != NULL)
+         fclose(fp);
+     fp = NULL;
++
++#ifdef solaris2
++while (i < fscount) {
++    free(HRFS_list[i].mnt_special);
++    free(HRFS_list[i].mnt_mountp);
++    free(HRFS_list[i].mnt_fstype);
++    free(HRFS_list[i].mnt_mntopts);
++    i++;
++}
++    if (HRFS_list != NULL)
++        free(HRFS_list);
++    last_access = -1;
++#endif
++
+ #endif
+ }
+