/*
* nfsstat.c Output NFS statistics
*
- * Copyright (C) 1995, 1996, 1999 Olaf Kirch <okir@monad.swb.de>
+ * Copyright (C) 1995-2005 Olaf Kirch <okir@suse.de>
*/
#include "config.h"
#define NFSSVCSTAT "/proc/net/rpc/nfsd"
#define NFSCLTSTAT "/proc/net/rpc/nfs"
-#define MOUNTSFILE "/proc/mounts"
+#define MOUNTSFILE "/proc/mounts"
#include <stdlib.h>
#include <stdio.h>
#define MAXNRVALS 32
-static unsigned int svcv2info[19]; /* NFSv2 call counts ([0] == 18) */
-static unsigned int cltv2info[19]; /* NFSv2 call counts ([0] == 18) */
-static unsigned int svcv3info[23]; /* NFSv3 call counts ([0] == 22) */
-static unsigned int cltv3info[23]; /* NFSv3 call counts ([0] == 22) */
-static unsigned int svcnetinfo[4]; /* 0 # of received packets
+static unsigned int svcv2info[20]; /* NFSv2 call counts ([0] == 18) */
+static unsigned int cltv2info[20]; /* NFSv2 call counts ([0] == 18) */
+static unsigned int svcv3info[24]; /* NFSv3 call counts ([0] == 22) */
+static unsigned int cltv3info[24]; /* NFSv3 call counts ([0] == 22) */
+static unsigned int svcv4info[4]; /* NFSv4 call counts ([0] == 2) */
+static unsigned int cltv4info[34]; /* NFSv4 call counts ([0] == 32) */
+static unsigned int svcnetinfo[5]; /* 0 # of received packets
* 1 UDP packets
* 2 TCP packets
* 3 TCP connections
*/
-static unsigned int cltnetinfo[4]; /* 0 # of received packets
+static unsigned int cltnetinfo[5]; /* 0 # of received packets
* 1 UDP packets
* 2 TCP packets
* 3 TCP connections
*/
-static unsigned int svcrpcinfo[5]; /* 0 total # of RPC calls
+static unsigned int svcrpcinfo[6]; /* 0 total # of RPC calls
* 1 total # of bad calls
* 2 bad format
* 3 authentication failed
* 4 unknown client
*/
-static unsigned int cltrpcinfo[3]; /* 0 total # of RPC calls
+static unsigned int cltrpcinfo[4]; /* 0 total # of RPC calls
* 1 retransmitted calls
* 2 cred refreshs
*/
-static unsigned int svcrcinfo[8]; /* 0 repcache hits
+static unsigned int svcrcinfo[9]; /* 0 repcache hits
* 1 repcache hits
* 2 uncached reqs
* (for pre-2.4 kernels:)
* 7 stale
*/
-static unsigned int svcfhinfo[6]; /* (for kernels >= 2.4.0)
+static unsigned int svcfhinfo[7]; /* (for kernels >= 2.4.0)
* 0 stale
* 1 FH lookups
* 2 'anon' FHs
"fsstat", "fsinfo", "pathconf", "commit"
};
+static const char * nfssvrv4name[2] = {
+ "null",
+ "compound",
+};
+
+static const char * nfscltv4name[32] = {
+ "null", "read", "write", "commit", "open", "open_conf",
+ "open_noat", "open_dgrd", "close", "setattr", "fsinfo", "renew",
+ "setclntid", "confirm", "lock",
+ "lockt", "locku", "access", "getattr", "lookup", "lookup_root",
+ "remove", "rename", "link", "symlink", "create", "pathconf",
+ "statfs", "readlink", "readdir", "server_caps", "delegreturn",
+};
+
typedef struct statinfo {
char *tag;
int nrvals;
unsigned int * valptr;
} statinfo;
+#define STRUCTSIZE(x) sizeof(x)/sizeof(*x)
+
static statinfo svcinfo[] = {
- { "net", 4, svcnetinfo },
- { "rpc", 5, svcrpcinfo },
- { "rc", 8, svcrcinfo },
- { "fh", 5, svcfhinfo },
- { "proc2", 19, svcv2info },
- { "proc3", 23, svcv3info },
- { NULL, 0, 0 }
+ { "net", STRUCTSIZE(svcnetinfo), svcnetinfo },
+ { "rpc", STRUCTSIZE(svcrpcinfo), svcrpcinfo },
+ { "rc", STRUCTSIZE(svcrcinfo), svcrcinfo },
+ { "fh", STRUCTSIZE(svcfhinfo), svcfhinfo },
+ { "proc2", STRUCTSIZE(svcv2info), svcv2info },
+ { "proc3", STRUCTSIZE(svcv3info), svcv3info },
+ { "proc4", STRUCTSIZE(svcv4info), svcv4info },
+ { NULL, 0, NULL }
};
static statinfo cltinfo[] = {
- { "net", 4, cltnetinfo },
- { "rpc", 3, cltrpcinfo },
- { "proc2", 19, cltv2info },
- { "proc3", 23, cltv3info },
- { NULL, 0, 0 }
+ { "net", STRUCTSIZE(cltnetinfo), cltnetinfo },
+ { "rpc", STRUCTSIZE(cltrpcinfo), cltrpcinfo },
+ { "proc2", STRUCTSIZE(cltv2info), cltv2info },
+ { "proc3", STRUCTSIZE(cltv3info), cltv3info },
+ { "proc4", STRUCTSIZE(cltv4info), cltv4info },
+ { NULL, 0, NULL }
};
static void print_numbers(const char *, unsigned int *,
#define PRNT_NET 0x0004
#define PRNT_FH 0x0008
#define PRNT_RC 0x0010
-#define PRNT_ALL 0xffff
+#define PRNT_ALL 0x0fff
int
main(int argc, char **argv)
opt_prt |= PRNT_RC;
else if (!strcmp(optarg, "fh"))
opt_prt |= PRNT_FH;
+ else if (!strcmp(optarg, "all"))
+ opt_prt |= PRNT_CALLS | PRNT_RPC | PRNT_NET | PRNT_RC | PRNT_FH;
else {
fprintf(stderr, "nfsstat: unknown category: "
"%s\n", optarg);
"packets udp tcp tcpconn\n",
svcnetinfo, 4
);
+ printf("\n");
}
if (opt_prt & PRNT_RPC) {
print_numbers(
"calls badcalls badauth badclnt xdrcall\n",
svcrpcinfo, 5
);
+ printf("\n");
}
if (opt_prt & PRNT_RC) {
print_numbers(
"hits misses nocache\n",
svcrcinfo, 3
);
+ printf("\n");
}
/*
print_numbers(
"Server file handle cache:\n"
- "lookup anon ncachedir ncachedir stale\n",
+ "lookup anon ncachedir ncachedir stale\n",
svcfhinfo + 1, 5);
} else /* < 2.4 */
print_numbers(
"Server file handle cache:\n"
- "lookup anon ncachedir ncachedir stale\n",
+ "lookup anon ncachedir ncachedir stale\n",
svcrcinfo + 3, 5);
+ printf("\n");
}
if (opt_prt & PRNT_CALLS) {
print_callstats(
"Server nfs v2:\n",
- nfsv2name, svcv2info + 1, 18
+ nfsv2name, svcv2info + 1, sizeof(nfsv2name)/sizeof(char *)
);
- if (svcv3info[0])
+ if (svcv3info[0])
print_callstats(
"Server nfs v3:\n",
- nfsv3name, svcv3info + 1, 22
+ nfsv3name, svcv3info + 1, sizeof(nfsv3name)/sizeof(char *)
+ );
+ if (svcv4info[0])
+ print_callstats(
+ "Server nfs v4:\n",
+ nfssvrv4name, svcv4info + 1, sizeof(nfssvrv4name)/sizeof(char *)
);
}
}
"packets udp tcp tcpconn\n",
cltnetinfo, 4
);
+ printf("\n");
}
if (opt_prt & PRNT_RPC) {
print_numbers(
"calls retrans authrefrsh\n",
cltrpcinfo, 3
);
+ printf("\n");
}
if (opt_prt & PRNT_CALLS) {
print_callstats(
"Client nfs v2:\n",
- nfsv2name, cltv2info + 1, 18
+ nfsv2name, cltv2info + 1, sizeof(nfsv2name)/sizeof(char *)
);
- if (cltv3info[0])
+ if (cltv3info[0])
print_callstats(
"Client nfs v3:\n",
- nfsv3name, cltv3info + 1, 22
+ nfsv3name, cltv3info + 1, sizeof(nfsv3name)/sizeof(char *)
+ );
+ if (cltv4info[0])
+ print_callstats(
+ "Client nfs v4:\n",
+ nfscltv4name, cltv4info + 1, sizeof(nfscltv4name)/sizeof(char *)
);
}
}
total = 1;
for (i = 0; i < nr; i += 6) {
for (j = 0; j < 6 && i + j < nr; j++)
- printf("%-11s", names[i+j]);
+ printf("%-13s", names[i+j]);
printf("\n");
for (j = 0; j < 6 && i + j < nr; j++) {
pct = ((unsigned long long) info[i+j]*100)/total;
- printf("%-6d %2llu%% ", info[i+j], pct);
+ printf("%-8d%3llu%% ", info[i+j], pct);
}
printf("\n");
}
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
struct statinfo *ip;
char *sp, *line = buffer;
- int i, cnt;
+ unsigned int i, cnt;
+ unsigned int total = 0;
if ((next = strchr(line, '\n')) != NULL)
*next++ = '\0';
if (!(sp = strtok(NULL, " \t")))
break;
ip->valptr[i] = atoi(sp);
+ total += ip->valptr[i];
}
+ ip->valptr[i] = total;
}
fclose(fp);
*/
if ((fp = fopen(name, "r")) == NULL) {
fprintf(stderr, "Warning: %s: %m\n", name);
- return -1;
+ return 0;
}
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
}
fclose(fp);
- return 0;
+ return 1;
}