components/net-snmp/patches/027.7118090.hr_filesys.patch
changeset 1650 ce501c11d5fa
parent 1306 11b376b53ac1
child 1679 51291a5fd692
equal deleted inserted replaced
1649:81d624418adc 1650:ce501c11d5fa
     1 /*
     1 /*
       
     2  *  Version 2 - Modified the patch file to make it work for the newer
       
     3  *  revision in net-snmp 5.7.2. Some fragments of the patch had gone
       
     4  *  into the community net-snmp source. So this patch file has been
       
     5  *  updated with the correct diffs.
       
     6  *
     2  *  This patch fixes the performance issue observed while retrieving the
     7  *  This patch fixes the performance issue observed while retrieving the
     3  *  hrStorage parameters in systems with large number of mountpoints
     8  *  hrStorage parameters in systems with large number of mountpoints
     4  *  parameters using snmpwalk.
     9  *  parameters using snmpwalk.
     5  *
    10  *
     6  *  This issue is happening due to the overhead of large number of
    11  *  This issue is happening due to the overhead of large number of
     7  *  ioctl() system calls in getmntent() function called by the
    12  *  ioctl() system calls in getmntent() function called by the
     8  *  Get_Next_HR_FileSys() function.
    13  *  Get_Next_HR_FileSys() function.
     9  *
    14  *
    10  *  We see that in the Get_Next_HR_FileSys() function, inorder to access
    15  *  We see that in the Get_Next_HR_FileSys() function, inorder to access
    11  *  the last mountpoint, the /etc/mnttab is opened and we walk through
    16  *  the last mountpoint, the /etc/mnttab is opened and we walk through 
    12  *  all the mnttab entries for all filesystems till the end. This is the
    17  *  all the mnttab entries for all filesystems till the end. This is the 
    13  *  reason we find a large number of the MNTIOC_GETMNTENT ioctl() calls.
    18  *  reason we find a large number of the MNTIOC_GETMNTENT ioctl() calls.  
    14  *
    19  *
    15  *  To reduce the overhead of the getmntent() calls, we maintain a cache
    20  *  To reduce the overhead of the getmntent() calls, we maintain a cache
    16  *  of all the /etc/mnttab entries and walk through the cache instead of
    21  *  of all the /etc/mnttab entries and walk through the cache instead of 
    17  *  opening /etc/mnttab and walking all the entries for each mountpoint.
    22  *  opening /etc/mnttab and walking all the entries for each mountpoint.
    18  *  This functionality is provided by the load_mnttab_cache_solaris()
    23  *  This functionality is provided by the load_mnttab_cache_solaris()
    19  *  function called from the Init_HR_FileSys() function.
    24  *  function called from the Init_HR_FileSys() function.
    20  */
    25  */
    21 --- net-snmp-5.4.1.orig/agent/mibgroup/host/hr_filesys.c	2007-05-18 11:08:01.000000000 -0700
    26 
    22 +++ net-snmp-5.4.1/agent/mibgroup/host/hr_filesys.c	2013-01-17 03:36:28.181493003 -0800
    27 --- net-snmp/agent/mibgroup/host/hr_filesys.c	Sun Dec 30 22:37:05 2012
    23 @@ -31,6 +31,10 @@
    28 +++ net-snmp/agent/mibgroup/host/hr_filesys.c	Mon Dec 31 00:55:29 2012
       
    29 @@ -46,6 +46,10 @@
    24  #include <sys/mount.h>
    30  #include <sys/mount.h>
    25  #endif
    31  #endif
    26  
    32  
    27 +#ifdef solaris2
    33 +#ifdef solaris2
    28 +#include <sys/stat.h>
    34 +#include <sys/stat.h>
    29 +#endif
    35 +#endif
    30 +
    36 +
    31  #include <ctype.h>
    37  #include <ctype.h>
    32  #if HAVE_STRING_H
    38  #if HAVE_STRING_H
    33  #include <string.h>
    39  #include <string.h>
    34 @@ -85,7 +89,11 @@
    40 @@ -108,7 +112,11 @@
    35  #ifdef solaris2
    41  #ifdef solaris2
    36  
    42  
    37  struct mnttab   HRFS_entry_struct;
    43  struct mnttab   HRFS_entry_struct;
    38 -struct mnttab  *HRFS_entry = &HRFS_entry_struct;
    44 -struct mnttab  *HRFS_entry = &HRFS_entry_struct;
    39 +struct mnttab  *HRFS_entry;
    45 +struct mnttab  *HRFS_entry;
    40 +struct mnttab	*HRFS_list;
    46 +struct mnttab	*HRFS_list;
    41 +static int fscount;
    47 +static int fscount;
    42 +static time_t last_access = -1;
    48 +static time_t last_access=-1;
    43 +
    49 +
    44  #define	HRFS_name	mnt_special
    50  #define	HRFS_name	mnt_special
    45  #define	HRFS_mount	mnt_mountp
    51  #define	HRFS_mount	mnt_mountp
    46  #define	HRFS_type	mnt_fstype
    52  #define	HRFS_type	mnt_fstype
    47 @@ -167,6 +175,9 @@
    53 @@ -619,6 +627,12 @@
    48  static u_char  *when_dumped(char *filesys, int level, size_t * length);
    54  void
    49  int             header_hrfilesys(struct variable *, oid *, size_t *, int,
    55  Init_HR_FileSys(void)
    50                                   size_t *, WriteMethod **);
    56  {
    51 +#ifdef solaris2
    57 +#ifdef solaris2
    52 +static int      load_mnttab_cache_solaris(void);
    58 +	char buf[512]={NULL};
       
    59 +	int lines=0, i=0;
       
    60 +	struct stat file_stat;
    53 +#endif
    61 +#endif
    54  
    62 +
    55          /*********************
    63  #if HAVE_GETFSSTAT
    56  	 *
    64  #if defined(HAVE_STATVFS) && defined(__NetBSD__)
    57 @@ -606,8 +617,14 @@
    65      fscount = getvfsstat(NULL, 0, ST_NOWAIT);
       
    66 @@ -662,7 +676,59 @@
    58      HRFS_index = 1;
    67      HRFS_index = 1;
    59      if (fp != NULL)
    68      if (fp != NULL)
    60          fclose(fp);
    69          fclose(fp);
       
    70 -    fp = fopen(ETC_MNTTAB, "r");
    61 +#ifdef solaris2
    71 +#ifdef solaris2
    62 +    if(!load_mnttab_cache_solaris())
    72 +	HRFS_index = 0;
    63 +        return;
    73 +	stat(ETC_MNTTAB, &file_stat);
       
    74 +	if (last_access == -1 || last_access != file_stat.st_mtime) { 
       
    75 +    		fp = fopen(ETC_MNTTAB, "r");
       
    76 +		if(fp == NULL)
       
    77 +		{
       
    78 +			DEBUGMSGTL(("host/hr_filesys", "fopen failed for mnttab.\n"));
       
    79 +			return;
       
    80 +		}
       
    81 +
       
    82 +		while ( (fgets((char *)&buf,sizeof(buf),fp)) != NULL) {
       
    83 +			lines++;
       
    84 +		}	
       
    85 +		fclose(fp);
       
    86 +	
       
    87 +		HRFS_list = (struct mnttab *) malloc (sizeof(struct mnttab) * lines);
       
    88 +		
       
    89 +		if(HRFS_list == NULL)
       
    90 +		{
       
    91 +			DEBUGMSGTL(("host/hr_filesys", "Memory allocation for mnttab cache failed.\n"));
       
    92 +			return;
       
    93 +		}				
       
    94 +
       
    95 +    		fp = fopen(ETC_MNTTAB, "r");
       
    96 +		
       
    97 +		if(fp == NULL)
       
    98 +                {
       
    99 +			DEBUGMSGTL(("host/hr_filesys", "fopen failed for mnttab.\n"));
       
   100 +			free(HRFS_list);
       
   101 +			return;
       
   102 +                }
       
   103 +
       
   104 +		fscount = lines;
       
   105 +		while (i < fscount)
       
   106 +    		{
       
   107 +			if (getmntent(fp, &HRFS_entry_struct) == 0)
       
   108 +        		{
       
   109 +				HRFS_list[i].mnt_special = strdup(HRFS_entry_struct.mnt_special);
       
   110 +				HRFS_list[i].mnt_mountp = strdup(HRFS_entry_struct.mnt_mountp);
       
   111 +				HRFS_list[i].mnt_fstype = strdup(HRFS_entry_struct.mnt_fstype);
       
   112 +				HRFS_list[i].mnt_mntopts = strdup(HRFS_entry_struct.mnt_mntopts);
       
   113 +        			i++;
       
   114 +        		}
       
   115 +    		}
       
   116 +	
       
   117 +		HRFS_entry = HRFS_list;
       
   118 +		last_access = file_stat.st_mtime;
       
   119 +	}
    64 +#else    
   120 +#else    
    65      fp = fopen(ETC_MNTTAB, "r");
   121 +	fp = fopen(ETC_MNTTAB, "r");
    66  #endif
       
    67 +
       
    68 +#endif
       
    69  }
       
    70  
       
    71  const char     *HRFS_ignores[] = {
       
    72 @@ -663,6 +680,117 @@
       
    73      0
       
    74  };
       
    75  
       
    76 +#ifdef solaris2
       
    77 +
       
    78 +/*
       
    79 + *  This function has been introduced to reduce the overhead
       
    80 + *  of the getmntent() calls used to fetch the details of
       
    81 + *  the /etc/mnttab entries in Init_HR_FileSys().
       
    82 + *
       
    83 + *  We maintain a cache of all the /etc/mnttab entries and
       
    84 + *  walk through the cache instead of opening /etc/mnttab and
       
    85 + *  walking all the entries for each mountpoint.
       
    86 + */
       
    87 +
       
    88 +static int 
       
    89 +load_mnttab_cache_solaris()
       
    90 +{
       
    91 +    char buf[512] = {NULL};
       
    92 +    int i = 0;
       
    93 +    struct stat file_stat;
       
    94 +    const char **cpp;
       
    95 +    char *ch;
       
    96 +    int token_flag = 0;
       
    97 +    int skip_flag = 0;
       
    98 +    int ignore_flag = 0;
       
    99 +    int j = 0;
       
   100 +    int lines = 0;
       
   101 +    int ret = 0;
       
   102 +    HRFS_index = 0;
       
   103 +
       
   104 +    stat(ETC_MNTTAB, &file_stat);
       
   105 +    if (last_access == -1 || last_access != file_stat.st_mtime) {
       
   106 +        fp = fopen(ETC_MNTTAB, "r");
       
   107 +        if(fp == NULL)
       
   108 +        {
       
   109 +            DEBUGMSGTL(("host/hr_filesys", "fopen failed for mnttab.\n"));
       
   110 +            return -1;
       
   111 +        }
       
   112 +        
       
   113 +        /* find the number of valid entries in mnttab. */
       
   114 +        
       
   115 +        while ((fgets((char *) &buf, sizeof(buf), fp)) != NULL) {
       
   116 +            j = 0;
       
   117 +            skip_flag = 0;
       
   118 +            token_flag = 0;
       
   119 +
       
   120 +            /* tokenize the mnttab entries to fetch the fstype
       
   121 +             * which determines the valid entries.
       
   122 +             */
       
   123 +
       
   124 +            ch = strtok(buf, " \t");
       
   125 +            while (ch != NULL) {
       
   126 +                j++;
       
   127 +                if(j == 3) {
       
   128 +                    for (cpp = HRFS_ignores; *cpp != NULL; ++cpp) {
       
   129 +                        if(!strncmp(ch, *cpp, strlen(ch))) {
       
   130 +                            skip_flag = 1;
       
   131 +                            break;
       
   132 +                        }
       
   133 +                    }
       
   134 +                    token_flag = 1;
       
   135 +                }
       
   136 +                if(token_flag)
       
   137 +                    break;
       
   138 +                ch = strtok(NULL, " \t");
       
   139 +             }
       
   140 +             if(!skip_flag)
       
   141 +                 lines++;
       
   142 +        }
       
   143 +        fclose(fp);
       
   144 +
       
   145 +        fscount = lines;
       
   146 +        HRFS_list = (struct mnttab *) malloc (sizeof(struct mnttab) * fscount);
       
   147 +        if(HRFS_list == NULL) {
       
   148 +            DEBUGMSGTL(("host/hr_filesys", "Memory allocation for mnttab cache failed.\n"));
       
   149 +            return -1;
       
   150 +        }
       
   151 +
       
   152 +        fp = fopen(ETC_MNTTAB, "r");
       
   153 +        if(fp == NULL) {
       
   154 +            DEBUGMSGTL(("host/hr_filesys", "fopen failed for mnttab.\n"));
       
   155 +            free(HRFS_list);
       
   156 +            return -1;
       
   157 +        }
       
   158 +
       
   159 +        while (i < fscount) {
       
   160 +            if (getmntent(fp, &HRFS_entry_struct) == 0) {
       
   161 +                 for (cpp = HRFS_ignores; *cpp != NULL; ++cpp) {
       
   162 +                     if (!strcmp(HRFS_entry_struct.HRFS_type, *cpp)) {
       
   163 +                         ignore_flag = 1;
       
   164 +                         break;
       
   165 +                     }
       
   166 +                 }
       
   167 +
       
   168 +                 if(!ignore_flag) {
       
   169 +                     HRFS_list[i].mnt_special = strdup(HRFS_entry_struct.mnt_special);
       
   170 +                     HRFS_list[i].mnt_mountp = strdup(HRFS_entry_struct.mnt_mountp);
       
   171 +                     HRFS_list[i].mnt_fstype = strdup(HRFS_entry_struct.mnt_fstype);
       
   172 +                     HRFS_list[i].mnt_mntopts = strdup(HRFS_entry_struct.mnt_mntopts);
       
   173 +                     i++;
       
   174 +                 }
       
   175 +
       
   176 +                 ignore_flag = 0;
       
   177 +            }
       
   178 +        }
       
   179 +
       
   180 +        HRFS_entry = HRFS_list;
       
   181 +        last_access = file_stat.st_mtime;
       
   182 +    }
       
   183 +    return ret;
       
   184 +}
       
   185 +#endif
   122 +#endif
   186 +
   123 +
   187  int
   124      if (!fp) {
   188  Get_Next_HR_FileSys(void)
   125        netsnmp_config_error("Can't open mnttab %s\n", ETC_MNTTAB);
   189  {
   126      }
   190 @@ -699,17 +827,18 @@
   127 @@ -758,17 +824,20 @@
   191  #else
   128  #else
   192      const char    **cpp;
   129      const char    **cpp;
   193  
   130  
   194 -    if (fp == NULL)
   131 -    if (fp == NULL)
   195 -        return -1;
   132 -        return -1;
   196  
   133  
   197  #ifdef solaris2
   134  #ifdef solaris2
   198 -    if (getmntent(fp, HRFS_entry) != 0)
   135 -    if (getmntent(fp, HRFS_entry) != 0)
   199 +    if (HRFS_index >= fscount)
   136 -        return -1;
   200          return -1;
   137 +
   201 +    HRFS_entry = &HRFS_list[HRFS_index];
   138 +	if (HRFS_index >= fscount)
   202 +        return ++HRFS_index;
   139 +		return -1;
       
   140 +	HRFS_entry = &HRFS_list[HRFS_index];
       
   141 +		return ++HRFS_index;
       
   142 +
   203  #else
   143  #else
   204 +    if (fp == NULL)
   144 +	if (fp == NULL)
   205 +        return -1;
   145 +                return -1;
   206      HRFS_entry = getmntent(fp);
   146      HRFS_entry = getmntent(fp);
   207      if (HRFS_entry == NULL)
   147      if (HRFS_entry == NULL)
   208          return -1;
   148          return -1;
   209 -#endif                          /* solaris2 */
   149 -#endif                          /* solaris2 */
   210  
   150  
   211      for (cpp = HRFS_ignores; *cpp != NULL; ++cpp)
   151      for (cpp = HRFS_ignores; *cpp != NULL; ++cpp)
   212          if (!strcmp(HRFS_entry->HRFS_type, *cpp))
   152          if (!strcmp(HRFS_entry->HRFS_type, *cpp))
   213 @@ -728,6 +857,8 @@
   153 @@ -787,6 +856,8 @@
   214      }
   154      }
   215  
   155  
   216      return HRFS_index++;
   156      return HRFS_index++;
   217 +#endif
   157 +#endif
   218 +
   158 +
   219  #endif                          /* HAVE_GETFSSTAT */
   159  #endif                          /* HAVE_GETFSSTAT */
   220  }
   160  }
   221  
   161  
   222 @@ -791,9 +922,24 @@
   162 @@ -854,10 +925,24 @@
   223          HRFS_entry = NULL;
   163          HRFS_entry = NULL;
   224      }
   164      }
   225  #else
   165  #else
   226 +    int i = 0;
   166 +    int i=0;
   227      if (fp != NULL)
   167      if (fp != NULL)
   228          fclose(fp);
   168          fclose(fp);
   229      fp = NULL;
   169      fp = NULL;
   230 +
   170 +
   231 +#ifdef solaris2
   171 +#ifdef solaris2
   232 +while (i < fscount) {
   172 +	while (i < fscount) {
   233 +    free(HRFS_list[i].mnt_special);
   173 +		free(HRFS_list[i].mnt_special);
   234 +    free(HRFS_list[i].mnt_mountp);
   174 +		free(HRFS_list[i].mnt_mountp);
   235 +    free(HRFS_list[i].mnt_fstype);
   175 +		free(HRFS_list[i].mnt_fstype);
   236 +    free(HRFS_list[i].mnt_mntopts);
   176 +		free(HRFS_list[i].mnt_mntopts);
   237 +    i++;
   177 +		i++;
   238 +}
   178 +	}
   239 +    if (HRFS_list != NULL)
   179 +	if (HRFS_list != NULL)
   240 +        free(HRFS_list);
   180 +		free(HRFS_list);
   241 +    last_access = -1;
   181  #endif
       
   182 +
   242 +#endif
   183 +#endif
   243 +
       
   244  #endif
       
   245  }
   184  }
   246  
   185  
       
   186