15818955 SUNBT7201487 snmpd cores multiple times during walk with service ending in maint
authorLijo George - Oracle Corporation - Bangalore India <lijo.x.george@oracle.com>
Thu, 17 Jan 2013 10:06:47 -0800
changeset 1126 a7e552aeef46
parent 1125 47a52afcc302
child 1127 b128479be783
15818955 SUNBT7201487 snmpd cores multiple times during walk with service ending in maint
components/net-snmp/patches/027.7118090.hr_filesys.patch
--- a/components/net-snmp/patches/027.7118090.hr_filesys.patch	Thu Jan 17 09:36:55 2013 -0800
+++ b/components/net-snmp/patches/027.7118090.hr_filesys.patch	Thu Jan 17 10:06:47 2013 -0800
@@ -1,23 +1,25 @@
 /*
- *  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.  
+ *  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 
+ *  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	2012-08-17 01:23:04.781860694 -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
@@ -37,92 +39,155 @@
 +struct mnttab  *HRFS_entry;
 +struct mnttab	*HRFS_list;
 +static int fscount;
-+static time_t last_access=-1;
++static time_t last_access = -1;
 +
  #define	HRFS_name	mnt_special
  #define	HRFS_mount	mnt_mountp
  #define	HRFS_type	mnt_fstype
[email protected]@ -563,6 +571,12 @@
- void
- Init_HR_FileSys(void)
- {
[email protected]@ -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
+ 
+         /*********************
+ 	 *
[email protected]@ -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[] = {
[email protected]@ -663,6 +680,117 @@
+     0
+ };
+ 
 +#ifdef solaris2
-+	char buf[512]={NULL};
-+	int lines=0, i=0;
-+	struct stat file_stat;
++
++/*
++ *  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
 +
- #if HAVE_GETFSSTAT
- #if defined(HAVE_STATVFS) && defined(__NetBSD__)
-     fscount = getvfsstat(NULL, 0, ST_NOWAIT);
[email protected]@ -603,10 +617,62 @@
-         }
-     }
- #else
--    HRFS_index = 1;
--    if (fp != NULL)
--        fclose(fp);
--    fp = fopen(ETC_MNTTAB, "r");
-+    	HRFS_index = 1;
-+	if (fp != NULL)
-+        	fclose(fp);
-+#ifdef solaris2
-+	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;
-+		}
-+
-+		while ( (fgets((char *)&buf,sizeof(buf),fp)) != NULL) {
-+			lines++;
-+		}	
-+		fclose(fp);
-+	
-+		HRFS_list = (struct mnttab *) malloc (sizeof(struct mnttab) * lines);
-+		
-+		if(HRFS_list == NULL)
-+		{
-+			DEBUGMSGTL(("host/hr_filesys", "Memory allocation for mnttab cache failed.\n"));
-+			return;
-+		}				
-+
-+    		fp = fopen(ETC_MNTTAB, "r");
-+		
-+		if(fp == NULL)
-+                {
-+			DEBUGMSGTL(("host/hr_filesys", "fopen failed for mnttab.\n"));
-+			free(HRFS_list);
-+			return;
-+                }
-+
-+		fscount = lines;
-+		while (i < fscount)
-+    		{
-+			if (getmntent(fp, &HRFS_entry_struct) == 0)
-+        		{
-+				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++;
-+        		}
-+    		}
-+	
-+		HRFS_entry = HRFS_list;
-+		last_access = file_stat.st_mtime;
-+	}
-+#else    
-+	fp = fopen(ETC_MNTTAB, "r");
-+#endif
-+
- #endif
- }
- 
[email protected]@ -699,21 +765,24 @@
+ int
+ Get_Next_HR_FileSys(void)
+ {
[email protected]@ -699,17 +827,18 @@
  #else
      const char    **cpp;
  
@@ -131,34 +196,21 @@
  
  #ifdef solaris2
 -    if (getmntent(fp, HRFS_entry) != 0)
--        return -1;
-+
-+	if (HRFS_index >= fscount)
-+		return -1;
-+	HRFS_entry = &HRFS_list[HRFS_index];
-+		return ++HRFS_index;
-+
++    if (HRFS_index >= fscount)
+         return -1;
++    HRFS_entry = &HRFS_list[HRFS_index];
++        return ++HRFS_index;
  #else
--    HRFS_entry = getmntent(fp);
--    if (HRFS_entry == NULL)
--        return -1;
++    if (fp == NULL)
++        return -1;
+     HRFS_entry = getmntent(fp);
+     if (HRFS_entry == NULL)
+         return -1;
 -#endif                          /* solaris2 */
-+	if (fp == NULL)
-+                return -1;
-+        HRFS_entry = getmntent(fp);
-+        if (HRFS_entry == NULL)
-+                return -1;
  
--    for (cpp = HRFS_ignores; *cpp != NULL; ++cpp)
--        if (!strcmp(HRFS_entry->HRFS_type, *cpp))
--            return Get_Next_HR_FileSys();
-+	for (cpp = HRFS_ignores; *cpp != NULL; ++cpp)
-+		if (!strcmp(HRFS_entry->HRFS_type, *cpp))
-+			return Get_Next_HR_FileSys();
- 
-     /*
-      * Try and ensure that index values are persistent
[email protected]@ -728,6 +797,8 @@
+     for (cpp = HRFS_ignores; *cpp != NULL; ++cpp)
+         if (!strcmp(HRFS_entry->HRFS_type, *cpp))
[email protected]@ -728,6 +857,8 @@
      }
  
      return HRFS_index++;
@@ -167,49 +219,26 @@
  #endif                          /* HAVE_GETFSSTAT */
  }
  
[email protected]@ -780,20 +851,34 @@
- End_HR_FileSys(void)
- {
- #ifdef HAVE_GETFSSTAT
--    if (fsstats)
--        free((char *) fsstats);
--    fsstats = NULL;
-+	if (fsstats)
-+		free((char *) fsstats);
-+	fsstats = NULL;
- #elif defined(aix4) || defined(aix5)
--    if(aixmnt != NULL) {
--        free(aixmnt);
--        aixmnt = NULL;
--        aixcurr = NULL;
--        HRFS_entry = NULL;
--    }
--#else
--    if (fp != NULL)
--        fclose(fp);
--    fp = NULL;
-+	if(aixmnt != NULL) {
-+		free(aixmnt);
-+		aixmnt = NULL;
-+		aixcurr = NULL;
-+		HRFS_entry = NULL;
-+	}
-+#else
-+	int i=0;
-+	if (fp != NULL)
-+		fclose(fp);
-+	fp = NULL;
[email protected]@ -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);
++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