diff -r 47a52afcc302 -r a7e552aeef46 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 #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 -@@ -563,6 +571,12 @@ - void - Init_HR_FileSys(void) - { +@@ -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 -+ 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); -@@ -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 - } - -@@ -699,21 +765,24 @@ + int + Get_Next_HR_FileSys(void) + { +@@ -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 -@@ -728,6 +797,8 @@ + for (cpp = HRFS_ignores; *cpp != NULL; ++cpp) + if (!strcmp(HRFS_entry->HRFS_type, *cpp)) +@@ -728,6 +857,8 @@ } return HRFS_index++; @@ -167,49 +219,26 @@ #endif /* HAVE_GETFSSTAT */ } -@@ -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; +@@ -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