patch-2.1.32 linux/net/sunrpc/stats.c
Next file: linux/net/sunrpc/sunrpc_syms.c
Previous file: linux/net/sunrpc/sched.c
Back to the patch index
Back to the overall index
- Lines: 268
- Date:
Fri Apr 4 12:08:27 1997
- Orig file:
v2.1.31/linux/net/sunrpc/stats.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.1.31/linux/net/sunrpc/stats.c linux/net/sunrpc/stats.c
@@ -0,0 +1,267 @@
+/*
+ * linux/net/sunrpc/stats.c
+ *
+ * procfs-based user access to RPC statistics
+ *
+ * Everything is complicated by the fact that procfs doesn't pass the
+ * proc_dir_info struct in the call to get_info. We need our own
+ * inode_ops for /proc/net/rpc (we want to have a write op for zeroing
+ * the current stats, anyway).
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/svcsock.h>
+
+#define RPCDBG_FACILITY RPCDBG_MISC
+
+/*
+ * Generic stats object (same for clnt and svc stats).
+ * Must agree with first two fields of either.
+ */
+struct stats {
+ struct stats * next;
+ struct proc_dir_entry * entry;
+};
+
+/* Code disabled until updated to new dynamic /proc code */
+#if 0
+
+static struct stats * rpc_stats = NULL;
+static struct stats * svc_stats = NULL;
+
+static struct proc_dir_entry proc_rpc = {
+ 0, 3, "rpc",
+ S_IFDIR | S_IRUGO | S_IXUGO, 1, 0, 0,
+ 0, NULL,
+ NULL, NULL,
+ NULL,
+ NULL, NULL,
+};
+
+/*
+ * Register/unregister a stats file
+ */
+static void
+stats_register(struct stats **q, struct stats *p)
+{
+ dprintk("RPC: registering /proc/net/rpc/%s\n",
+ p->entry->name);
+ /* return; */
+ if (p->entry->low_ino)
+ return;
+ p->next = *q;
+ *q = p;
+ proc_register_dynamic(&proc_rpc, p->entry);
+}
+
+static void
+stats_unregister(struct stats **q, struct stats *p)
+{
+ dprintk("RPC: unregistering /proc/net/rpc/%s\n",
+ p->entry->name);
+ /* return; */
+ if (!p->entry->low_ino)
+ return;
+ while (*q) {
+ if (*q == p) {
+ *q = p->next;
+ proc_unregister(&proc_rpc, p->entry->low_ino);
+ return;
+ }
+ q = &((*q)->next);
+ }
+}
+
+/*
+ * Client stats handling
+ */
+void
+rpcstat_register(struct rpc_stat *statp)
+{
+ stats_register(&rpc_stats, (struct stats *) statp);
+}
+
+void
+rpcstat_unregister(struct rpc_stat *statp)
+{
+ stats_unregister(&rpc_stats, (struct stats *) statp);
+}
+
+int
+rpcstat_get_info(struct rpc_stat *statp, char *buffer,
+ char **start, off_t offset, int length)
+{
+ struct rpc_program *prog = statp->program;
+ struct rpc_version *vers;
+ int len, i, j;
+
+ len = sprintf(buffer,
+ "net %d %d %d %d\n",
+ statp->netcnt,
+ statp->netudpcnt,
+ statp->nettcpcnt,
+ statp->nettcpconn);
+ len += sprintf(buffer + len,
+ "rpc %d %d %d\n",
+ statp->rpccnt,
+ statp->rpcretrans,
+ statp->rpcauthrefresh);
+
+ for (i = 0; i < prog->nrvers; i++) {
+ if (!(vers = prog->version[i]))
+ continue;
+ len += sprintf(buffer + len, "proc%d %d",
+ vers->number, vers->nrprocs);
+ for (j = 0; j < vers->nrprocs; j++)
+ len += sprintf(buffer + len, " %d",
+ vers->procs[j].p_count);
+ buffer[len++] = '\n';
+ }
+
+ if (offset >= len) {
+ *start = buffer;
+ return 0;
+ }
+ *start = buffer + offset;
+ len -= offset;
+ if (len > length)
+ len = length;
+ return len;
+}
+
+/*
+ * Server stats handling
+ */
+void
+svcstat_register(struct svc_stat *statp)
+{
+ stats_register(&svc_stats, (struct stats *) statp);
+}
+
+void
+svcstat_unregister(struct svc_stat *statp)
+{
+ stats_unregister(&svc_stats, (struct stats *) statp);
+}
+
+int
+svcstat_get_info(struct svc_stat *statp, char *buffer,
+ char **start, off_t offset, int length)
+{
+ struct svc_program *prog = statp->program;
+ struct svc_procedure *proc;
+ struct svc_version *vers;
+ int len, i, j;
+
+ len = sprintf(buffer,
+ "net %d %d %d %d\n",
+ statp->netcnt,
+ statp->netudpcnt,
+ statp->nettcpcnt,
+ statp->nettcpconn);
+ len += sprintf(buffer + len,
+ "rpc %d %d %d %d %d\n",
+ statp->rpccnt,
+ statp->rpcbadfmt+statp->rpcbadauth+statp->rpcbadclnt,
+ statp->rpcbadfmt,
+ statp->rpcbadauth,
+ statp->rpcbadclnt);
+
+ for (i = 0; i < prog->pg_nvers; i++) {
+ if (!(vers = prog->pg_vers[i]) || !(proc = vers->vs_proc))
+ continue;
+ len += sprintf(buffer + len, "proc%d %d", i, vers->vs_nproc);
+ for (j = 0; j < vers->vs_nproc; j++, proc++)
+ len += sprintf(buffer + len, " %d", proc->pc_count);
+ buffer[len++] = '\n';
+ }
+
+ if (offset >= len) {
+ *start = buffer;
+ return 0;
+ }
+ *start = buffer + offset;
+ if ((len -= offset) > length)
+ len = length;
+ return len;
+}
+
+/*
+ * Register /proc/net/rpc
+ */
+void
+rpcstat_init(void)
+{
+ dprintk("RPC: registering /proc/net/rpc\n");
+ proc_rpc.ops = proc_net.ops; /* cheat */
+ proc_register_dynamic(&proc_net, &proc_rpc);
+}
+
+/*
+ * Unregister /proc/net/rpc
+ */
+void
+rpcstat_exit(void)
+{
+ while (rpc_stats)
+ stats_unregister(&rpc_stats, rpc_stats);
+ while (svc_stats)
+ stats_unregister(&svc_stats, svc_stats);
+ dprintk("RPC: unregistering /proc/net/rpc\n");
+ proc_unregister(&proc_net, proc_rpc.low_ino);
+}
+
+#else
+
+/* Various dummy functions */
+
+int
+rpcstat_get_info(struct rpc_stat *statp, char *buffer,
+ char **start, off_t offset, int length)
+{
+ return 0;
+}
+
+int
+svcstat_get_info(struct svc_stat *statp, char *buffer,
+ char **start, off_t offset, int length)
+{
+ return 0;
+}
+
+void
+rpcstat_register(struct rpc_stat *statp)
+{
+}
+
+void
+rpcstat_unregister(struct rpc_stat *statp)
+{
+}
+
+void
+svcstat_register(struct svc_stat *statp)
+{
+}
+
+void
+svcstat_unregister(struct svc_stat *statp)
+{
+}
+
+void
+rpcstat_init(void)
+{
+}
+
+void
+rpcstat_exit(void)
+{
+}
+
+#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov