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>
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 static const char *nfs4_procedures_names[] =
166 "setclientid_confirm",
171 static int nfs4_procedures_names_num = 39;
174 extern kstat_ctl_t *kc;
175 static kstat_t *nfs2_ksp_client;
176 static kstat_t *nfs2_ksp_server;
177 static kstat_t *nfs3_ksp_client;
178 static kstat_t *nfs3_ksp_server;
179 static kstat_t *nfs4_ksp_client;
180 static kstat_t *nfs4_ksp_server;
183 /* Possibly TODO: NFSv4 statistics */
186 static int nfs_init (void)
188 kstat_t *ksp_chain = NULL;
190 nfs2_ksp_client = NULL;
191 nfs2_ksp_server = NULL;
192 nfs3_ksp_client = NULL;
193 nfs3_ksp_server = NULL;
194 nfs4_ksp_client = NULL;
195 nfs4_ksp_server = NULL;
200 for (ksp_chain = kc->kc_chain; ksp_chain != NULL;
201 ksp_chain = ksp_chain->ks_next)
203 if (strncmp (ksp_chain->ks_module, "nfs", 3) != 0)
205 else if (strncmp (ksp_chain->ks_name, "rfsproccnt_v2", 13) == 0)
206 nfs2_ksp_server = ksp_chain;
207 else if (strncmp (ksp_chain->ks_name, "rfsproccnt_v3", 13) == 0)
208 nfs3_ksp_server = ksp_chain;
209 else if (strncmp (ksp_chain->ks_name, "rfsproccnt_v4", 13) == 0)
210 nfs4_ksp_server = ksp_chain;
211 else if (strncmp (ksp_chain->ks_name, "rfsreqcnt_v2", 12) == 0)
212 nfs2_ksp_client = ksp_chain;
213 else if (strncmp (ksp_chain->ks_name, "rfsreqcnt_v3", 12) == 0)
214 nfs3_ksp_client = ksp_chain;
215 else if (strncmp (ksp_chain->ks_name, "rfsreqcnt_v4", 12) == 0)
216 nfs4_ksp_client = ksp_chain;
226 static void nfs2_procedures_submit(unsigned long long *val,
227 const char *plugin_instance, char *nfs_ver, int len)
230 value_list_t vl = VALUE_LIST_INIT;
231 char pl_instance[30];
236 sstrncpy(vl.host, hostname_g, sizeof (vl.host));
237 sstrncpy(vl.plugin, "nfs", sizeof (vl.plugin));
238 sstrncpy(pl_instance, nfs_ver, strlen(nfs_ver) + 1);
239 strcat(pl_instance, plugin_instance);
240 sstrncpy(vl.plugin_instance, pl_instance,
241 sizeof (vl.plugin_instance));
242 sstrncpy(vl.type, "nfs_procedure", sizeof (vl.type));
245 for (i = 0; i < len; i++)
247 values[0].derive = val[i];
248 if (strcmp(nfs_ver, "nfs2") == 0)
249 sstrncpy(vl.type_instance, nfs2_procedures_names[i],
250 sizeof (vl.type_instance));
251 else if (strcmp(nfs_ver, "nfs3") == 0)
252 sstrncpy(vl.type_instance, nfs3_procedures_names[i],
253 sizeof (vl.type_instance));
254 else if (strcmp(nfs_ver, "nfs4") == 0) {
255 sstrncpy(vl.type_instance, nfs4_procedures_names[i],
256 sizeof (vl.type_instance));
259 DEBUG("%s-%s/nfs_procedure-%s = %lld",
260 vl.plugin, vl.plugin_instance,
261 vl.type_instance, val[i]);
262 plugin_dispatch_values (&vl);
267 static void nfs_procedures_submit (const char *plugin_instance,
268 unsigned long long *val, const char **names, int len)
272 value_list_t vl = VALUE_LIST_INIT;
277 sstrncpy(vl.host, hostname_g, sizeof (vl.host));
278 sstrncpy(vl.plugin, "nfs", sizeof (vl.plugin));
279 sstrncpy(vl.plugin_instance, plugin_instance,
280 sizeof (vl.plugin_instance));
281 sstrncpy(vl.type, "nfs_procedure", sizeof (vl.type));
283 for (i = 0; (val[i] != NULL) && (i < len); i++) {
284 values[0].derive = val[i];
285 sstrncpy(vl.type_instance, names[i],
286 sizeof (vl.type_instance));
287 DEBUG("%s-%s/nfs_procedure-%s = %llu",
288 vl.plugin, vl.plugin_instance,
289 vl.type_instance, val[i]);
290 plugin_dispatch_values(&vl);
292 } /* void nfs_procedures_submit */
294 static void nfs_read_stats_file (FILE *fh, char *inst)
296 char buffer[BUFSIZE];
298 char plugin_instance[DATA_MAX_NAME_LEN];
306 while (fgets (buffer, BUFSIZE, fh) != NULL)
308 numfields = strsplit (buffer, fields, 48);
310 if (((numfields - 2) != nfs2_procedures_names_num)
312 != nfs3_procedures_names_num))
315 if (strcmp (fields[0], "proc2") == 0)
318 unsigned long long *values;
320 if ((numfields - 2) != nfs2_procedures_names_num)
322 WARNING ("nfs plugin: Wrong "
323 "number of fields (= %i) "
324 "for NFSv2 statistics.",
329 ssnprintf (plugin_instance, sizeof (plugin_instance),
332 values = (unsigned long long *) malloc (nfs2_procedures_names_num * sizeof (unsigned long long));
336 ERROR ("nfs plugin: malloc "
338 sstrerror (errno, errbuf, sizeof (errbuf)));
342 for (i = 0; i < nfs2_procedures_names_num; i++)
343 values[i] = atoll (fields[i + 2]);
345 nfs_procedures_submit (plugin_instance, values,
346 nfs2_procedures_names,
347 nfs2_procedures_names_num);
351 else if (strncmp (fields[0], "proc3", 5) == 0)
354 unsigned long long *values;
356 if ((numfields - 2) != nfs3_procedures_names_num)
358 WARNING ("nfs plugin: Wrong "
359 "number of fields (= %i) "
360 "for NFSv3 statistics.",
365 ssnprintf (plugin_instance, sizeof (plugin_instance),
368 values = (unsigned long long *) malloc (nfs3_procedures_names_num * sizeof (unsigned long long));
372 ERROR ("nfs plugin: malloc "
374 sstrerror (errno, errbuf, sizeof (errbuf)));
378 for (i = 0; i < nfs3_procedures_names_num; i++)
379 values[i] = atoll (fields[i + 2]);
381 nfs_procedures_submit (plugin_instance, values,
382 nfs3_procedures_names,
383 nfs3_procedures_names_num);
387 } /* while (fgets (buffer, BUFSIZE, fh) != NULL) */
388 } /* void nfs_read_stats_file */
392 static void nfs2_read_kstat (kstat_t *ksp, char *inst)
394 unsigned long long values[nfs2_procedures_names_num];
396 kstat_read(kc, ksp, NULL);
397 values[0] = get_kstat_value (ksp, "null");
398 values[1] = get_kstat_value (ksp, "getattr");
399 values[2] = get_kstat_value (ksp, "setattr");
400 values[3] = get_kstat_value (ksp, "root");
401 values[4] = get_kstat_value (ksp, "lookup");
402 values[5] = get_kstat_value (ksp, "readlink");
403 values[6] = get_kstat_value (ksp, "read");
404 values[7] = get_kstat_value (ksp, "wrcache");
405 values[8] = get_kstat_value (ksp, "write");
406 values[9] = get_kstat_value (ksp, "create");
407 values[10] = get_kstat_value (ksp, "remove");
408 values[11] = get_kstat_value (ksp, "rename");
409 values[12] = get_kstat_value (ksp, "link");
410 values[13] = get_kstat_value (ksp, "symlink");
411 values[14] = get_kstat_value (ksp, "mkdir");
412 values[15] = get_kstat_value (ksp, "rmdir");
413 values[16] = get_kstat_value (ksp, "readdir");
414 values[17] = get_kstat_value (ksp, "statfs");
416 nfs2_procedures_submit (values, inst, "nfs2", nfs2_procedures_names_num);
419 static void nfs3_read_kstat(kstat_t *ksp, char *inst)
421 unsigned long long values[nfs3_procedures_names_num];
423 kstat_read(kc, ksp, NULL);
424 values[0] = get_kstat_value (ksp, "null");
425 values[1] = get_kstat_value (ksp, "getattr");
426 values[2] = get_kstat_value (ksp, "setattr");
427 values[3] = get_kstat_value (ksp, "lookup");
428 values[4] = get_kstat_value (ksp, "access");
429 values[5] = get_kstat_value (ksp, "readlink");
430 values[6] = get_kstat_value (ksp, "read");
431 values[7] = get_kstat_value (ksp, "write");
432 values[8] = get_kstat_value (ksp, "create");
433 values[9] = get_kstat_value (ksp, "mkdir");
434 values[10] = get_kstat_value (ksp, "symlink");
435 values[11] = get_kstat_value (ksp, "mknod");
436 values[12] = get_kstat_value (ksp, "remove");
437 values[13] = get_kstat_value (ksp, "rmdir");
438 values[14] = get_kstat_value (ksp, "rename");
439 values[15] = get_kstat_value (ksp, "link");
440 values[16] = get_kstat_value (ksp, "readdir");
441 values[17] = get_kstat_value (ksp, "readdirplus");
442 values[18] = get_kstat_value (ksp, "fsstat");
443 values[19] = get_kstat_value (ksp, "fsinfo");
444 values[20] = get_kstat_value (ksp, "pathconf");
445 values[21] = get_kstat_value (ksp, "commit");
447 nfs2_procedures_submit (values, inst, "nfs3", nfs3_procedures_names_num);
450 static void nfs4_read_kstat(kstat_t *ksp, char *inst)
452 unsigned long long values[nfs4_procedures_names_num];
454 kstat_read(kc, ksp, NULL);
456 values[0] = get_kstat_value (ksp, "null");
457 values[1] = get_kstat_value (ksp, "compound");
458 values[2] = get_kstat_value (ksp, "reserved");
459 values[3] = get_kstat_value (ksp, "access");
460 values[4] = get_kstat_value (ksp, "close");
461 values[5] = get_kstat_value (ksp, "commit");
462 values[6] = get_kstat_value (ksp, "create");
463 values[7] = get_kstat_value (ksp, "delegpurge");
464 values[8] = get_kstat_value (ksp, "delegreturn");
465 values[9] = get_kstat_value (ksp, "getattr");
466 values[10] = get_kstat_value (ksp, "getfh");
467 values[11] = get_kstat_value (ksp, "link");
468 values[12] = get_kstat_value (ksp, "lock");
469 values[13] = get_kstat_value (ksp, "lockt");
470 values[14] = get_kstat_value (ksp, "locku");
471 values[15] = get_kstat_value (ksp, "lookup");
472 values[16] = get_kstat_value (ksp, "lookupp");
473 values[17] = get_kstat_value (ksp, "nverify");
474 values[18] = get_kstat_value (ksp, "open");
475 values[19] = get_kstat_value (ksp, "openattr");
476 values[20] = get_kstat_value (ksp, "open_confirm");
477 values[21] = get_kstat_value (ksp, "open_downgrade");
478 values[22] = get_kstat_value (ksp, "putfh");
479 values[23] = get_kstat_value (ksp, "putpubfh");
480 values[24] = get_kstat_value (ksp, "putrootfh");
481 values[25] = get_kstat_value (ksp, "read");
482 values[26] = get_kstat_value (ksp, "readdir");
483 values[27] = get_kstat_value (ksp, "readlink");
484 values[28] = get_kstat_value (ksp, "remove");
485 values[29] = get_kstat_value (ksp, "rename");
486 values[30] = get_kstat_value (ksp, "renew");
487 values[31] = get_kstat_value (ksp, "restorefh");
488 values[32] = get_kstat_value (ksp, "savefh");
489 values[33] = get_kstat_value (ksp, "secinfo");
490 values[34] = get_kstat_value (ksp, "setattr");
491 values[35] = get_kstat_value (ksp, "setclientid");
492 values[36] = get_kstat_value (ksp, "setclientid_confirm");
493 values[37] = get_kstat_value (ksp, "verify");
494 values[38] = get_kstat_value (ksp, "write");
496 nfs2_procedures_submit (values, inst, "nfs4", nfs4_procedures_names_num);
500 static int nfs_read (void)
504 if ((fh = fopen ("/proc/net/rpc/nfs", "r")) != NULL)
506 nfs_read_stats_file (fh, "client");
510 if ((fh = fopen ("/proc/net/rpc/nfsd", "r")) != NULL)
512 nfs_read_stats_file (fh, "server");
518 if (nfs2_ksp_client != NULL)
519 nfs2_read_kstat (nfs2_ksp_client, "client");
520 if (nfs2_ksp_server != NULL)
521 nfs2_read_kstat (nfs2_ksp_server, "server");
522 if (nfs3_ksp_client != NULL)
523 nfs3_read_kstat (nfs3_ksp_client, "client");
524 if (nfs3_ksp_server != NULL)
525 nfs3_read_kstat (nfs3_ksp_server, "server");
526 if (nfs4_ksp_client != NULL)
527 nfs4_read_kstat (nfs4_ksp_client, "client");
528 if (nfs4_ksp_server != NULL)
529 nfs4_read_kstat (nfs4_ksp_server, "server");
530 /* nfs_kstat(nfs3_ksp_client); */
531 #endif /* defined(HAVE_LIBKSTAT) */
536 void module_register (void)
538 plugin_register_read ("nfs", nfs_read);
539 } /* void module_register */