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