3 * Copyright (C) 2005,2006 Jason Pepas
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; only version 2 of the License is applicable.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * Jason Pepas <cell at ices.utexas.edu>
20 * Florian octo Forster <octo at verplant.org>
28 # error "No applicable input method."
33 see http://www.missioncriticallinux.com/orph/NFS-Statistics
36 rpc_stat.netcnt Not used; always zero.
37 rpc_stat.netudpcnt Not used; always zero.
38 rpc_stat.nettcpcnt Not used; always zero.
39 rpc_stat.nettcpconn Not used; always zero.
42 rpc_stat.rpccnt The number of RPC calls.
43 rpc_stat.rpcretrans The number of retransmitted RPC calls.
44 rpc_stat.rpcauthrefresh The number of credential refreshes.
49 Procedure NFS Version NFS Version 3
50 Number Procedures Procedures
76 static const char *nfs2_procedures_names[] =
98 static int nfs2_procedures_names_num = 18;
100 static const char *nfs3_procedures_names[] =
126 static int nfs3_procedures_names_num = 22;
128 #if HAVE_LIBKSTAT && 0
129 extern kstat_ctl_t *kc;
130 static kstat_t *nfs2_ksp_client;
131 static kstat_t *nfs2_ksp_server;
132 static kstat_t *nfs3_ksp_client;
133 static kstat_t *nfs3_ksp_server;
134 static kstat_t *nfs4_ksp_client;
135 static kstat_t *nfs4_ksp_server;
138 /* Possibly TODO: NFSv4 statistics */
141 static int nfs_init (void)
143 #if HAVE_LIBKSTAT && 0
146 nfs2_ksp_client = NULL;
147 nfs2_ksp_server = NULL;
148 nfs3_ksp_client = NULL;
149 nfs3_ksp_server = NULL;
150 nfs4_ksp_client = NULL;
151 nfs4_ksp_server = NULL;
156 for (ksp_chain = kc->kc_chain; ksp_chain != NULL;
157 ksp_chain = ksp_chain->ks_next)
159 if (strncmp (ksp_chain->ks_module, "nfs", 3) != 0)
161 else if (strncmp (ksp_chain->ks_name, "rfsproccnt_v2", 13) == 0)
162 nfs2_ksp_server = ksp_chain;
163 else if (strncmp (ksp_chain->ks_name, "rfsproccnt_v3", 13) == 0)
164 nfs3_ksp_server = ksp_chain;
165 else if (strncmp (ksp_chain->ks_name, "rfsproccnt_v4", 13) == 0)
166 nfs4_ksp_server = ksp_chain;
167 else if (strncmp (ksp_chain->ks_name, "rfsreqcnt_v2", 12) == 0)
168 nfs2_ksp_client = ksp_chain;
169 else if (strncmp (ksp_chain->ks_name, "rfsreqcnt_v3", 12) == 0)
170 nfs3_ksp_client = ksp_chain;
171 else if (strncmp (ksp_chain->ks_name, "rfsreqcnt_v4", 12) == 0)
172 nfs4_ksp_client = ksp_chain;
181 static void nfs_procedures_submit (const char *plugin_instance,
182 unsigned long long *val, const char **names, int len)
185 value_list_t vl = VALUE_LIST_INIT;
190 vl.time = time (NULL);
191 sstrncpy (vl.host, hostname_g, sizeof (vl.host));
192 sstrncpy (vl.plugin, "nfs", sizeof (vl.plugin));
193 sstrncpy (vl.plugin_instance, plugin_instance,
194 sizeof (vl.plugin_instance));
195 sstrncpy (vl.type, "nfs_procedure", sizeof (vl.type));
197 for (i = 0; i < len; i++)
199 values[0].counter = val[i];
200 sstrncpy (vl.type_instance, names[i],
201 sizeof (vl.type_instance));
202 DEBUG ("%s-%s/nfs_procedure-%s = %llu",
203 vl.plugin, vl.plugin_instance,
204 vl.type_instance, val[i]);
205 plugin_dispatch_values (&vl);
207 } /* void nfs_procedures_submit */
209 static void nfs_read_stats_file (FILE *fh, char *inst)
211 char buffer[BUFSIZE];
213 char plugin_instance[DATA_MAX_NAME_LEN];
221 while (fgets (buffer, BUFSIZE, fh) != NULL)
223 numfields = strsplit (buffer, fields, 48);
225 if (((numfields - 2) != nfs2_procedures_names_num)
227 != nfs3_procedures_names_num))
230 if (strcmp (fields[0], "proc2") == 0)
233 unsigned long long *values;
235 if ((numfields - 2) != nfs2_procedures_names_num)
237 WARNING ("nfs plugin: Wrong "
238 "number of fields (= %i) "
239 "for NFSv2 statistics.",
244 ssnprintf (plugin_instance, sizeof (plugin_instance),
247 values = (unsigned long long *) malloc (nfs2_procedures_names_num * sizeof (unsigned long long));
251 ERROR ("nfs plugin: malloc "
253 sstrerror (errno, errbuf, sizeof (errbuf)));
257 for (i = 0; i < nfs2_procedures_names_num; i++)
258 values[i] = atoll (fields[i + 2]);
260 nfs_procedures_submit (plugin_instance, values,
261 nfs2_procedures_names,
262 nfs2_procedures_names_num);
266 else if (strncmp (fields[0], "proc3", 5) == 0)
269 unsigned long long *values;
271 if ((numfields - 2) != nfs3_procedures_names_num)
273 WARNING ("nfs plugin: Wrong "
274 "number of fields (= %i) "
275 "for NFSv3 statistics.",
280 ssnprintf (plugin_instance, sizeof (plugin_instance),
283 values = (unsigned long long *) malloc (nfs3_procedures_names_num * sizeof (unsigned long long));
287 ERROR ("nfs plugin: malloc "
289 sstrerror (errno, errbuf, sizeof (errbuf)));
293 for (i = 0; i < nfs3_procedures_names_num; i++)
294 values[i] = atoll (fields[i + 2]);
296 nfs_procedures_submit (plugin_instance, values,
297 nfs3_procedures_names,
298 nfs3_procedures_names_num);
302 } /* while (fgets (buffer, BUFSIZE, fh) != NULL) */
303 } /* void nfs_read_stats_file */
306 #if HAVE_LIBKSTAT && 0
307 static void nfs2_read_kstat (kstat_t *ksp, char *inst)
309 unsigned long long values[18];
311 values[0] = get_kstat_value (ksp, "null");
312 values[1] = get_kstat_value (ksp, "getattr");
313 values[2] = get_kstat_value (ksp, "setattr");
314 values[3] = get_kstat_value (ksp, "root");
315 values[4] = get_kstat_value (ksp, "lookup");
316 values[5] = get_kstat_value (ksp, "readlink");
317 values[6] = get_kstat_value (ksp, "read");
318 values[7] = get_kstat_value (ksp, "wrcache");
319 values[8] = get_kstat_value (ksp, "write");
320 values[9] = get_kstat_value (ksp, "create");
321 values[10] = get_kstat_value (ksp, "remove");
322 values[11] = get_kstat_value (ksp, "rename");
323 values[12] = get_kstat_value (ksp, "link");
324 values[13] = get_kstat_value (ksp, "symlink");
325 values[14] = get_kstat_value (ksp, "mkdir");
326 values[15] = get_kstat_value (ksp, "rmdir");
327 values[16] = get_kstat_value (ksp, "readdir");
328 values[17] = get_kstat_value (ksp, "statfs");
330 nfs2_procedures_submit (values, inst);
334 static int nfs_read (void)
338 if ((fh = fopen ("/proc/net/rpc/nfs", "r")) != NULL)
340 nfs_read_stats_file (fh, "client");
344 if ((fh = fopen ("/proc/net/rpc/nfsd", "r")) != NULL)
346 nfs_read_stats_file (fh, "server");
350 #if HAVE_LIBKSTAT && 0
351 if (nfs2_ksp_client != NULL)
352 nfs2_read_kstat (nfs2_ksp_client, "client");
353 if (nfs2_ksp_server != NULL)
354 nfs2_read_kstat (nfs2_ksp_server, "server");
355 #endif /* defined(HAVE_LIBKSTAT) */
360 void module_register (void)
362 plugin_register_read ("nfs", nfs_read);
363 } /* void module_register */