X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=utils%2Fnfsstat%2Fnfsstat.c;h=3b695f253612d3ba562a5eb98b5345f53739fb33;hb=93407d94dd7d74a0f083bc43656151901f1c62b0;hp=afd323ede6f1f269fba68e6d9ecf998cf8c78229;hpb=43180e51d5f19a6a6b9c908bfeeef0d8d0cc99fd;p=nfs-utils.git diff --git a/utils/nfsstat/nfsstat.c b/utils/nfsstat/nfsstat.c index afd323e..3b695f2 100644 --- a/utils/nfsstat/nfsstat.c +++ b/utils/nfsstat/nfsstat.c @@ -9,6 +9,8 @@ #define NFSSVCSTAT "/proc/net/rpc/nfsd" #define NFSCLTSTAT "/proc/net/rpc/nfs" +#define MOUNTSFILE "/proc/mounts" + #include #include #include @@ -59,8 +61,8 @@ static unsigned int svcfhinfo[6]; /* (for kernels >= 2.4.0) * 0 stale * 1 FH lookups * 2 'anon' FHs - * 3 noncached non-directories - * 4 noncached directories + * 3 noncached directories + * 4 noncached non-directories * leave hole to relocate stale for order * compatability. */ @@ -110,6 +112,7 @@ static int parse_statfile(const char *, struct statinfo *); static statinfo *get_stat_info(const char *, struct statinfo *); +static int mounts(const char *); #define PRNT_CALLS 0x0001 #define PRNT_RPC 0x0002 @@ -124,10 +127,12 @@ main(int argc, char **argv) int opt_all = 0, opt_srv = 0, opt_clt = 0, + srv_info = 0, + clt_info = 0, opt_prt = 0; int c; - while ((c = getopt(argc, argv, "acno:rsz")) != -1) { + while ((c = getopt(argc, argv, "acmno:rsz")) != -1) { switch (c) { case 'a': opt_all = 1; @@ -165,6 +170,8 @@ main(int argc, char **argv) fprintf(stderr, "nfsstat: zeroing of nfs statistics " "not yet supported\n"); return 2; + case 'm': + return mounts(MOUNTSFILE); } } @@ -184,9 +191,25 @@ main(int argc, char **argv) "server.\n"); } - if ((opt_srv && !parse_statfile(NFSSVCSTAT, svcinfo)) - || (opt_clt && !parse_statfile(NFSCLTSTAT, cltinfo))) - return 2; + if (opt_srv) { + srv_info = parse_statfile(NFSSVCSTAT, svcinfo); + if (srv_info == 0 && opt_clt == 0) { + fprintf(stderr, "Warning: No Server Stats (%s: %m).\n", NFSSVCSTAT); + return 2; + } + if (srv_info == 0) + opt_srv = 0; + } + + if (opt_clt) { + clt_info = parse_statfile(NFSCLTSTAT, cltinfo); + if (opt_srv == 0 && clt_info == 0) { + fprintf(stderr, "Warning: No Client Stats (%s: %m).\n", NFSCLTSTAT); + return 2; + } + if (clt_info == 0) + opt_clt = 0; + } if (opt_srv) { if (opt_prt & PRNT_NET) { @@ -214,11 +237,17 @@ main(int argc, char **argv) /* * 2.2 puts all fh-related info after the 'rc' header * 2.4 puts all fh-related info after the 'fh' header, but relocates - * 'stale' to the start :-( We keep it at the end. + * 'stale' to the start and swaps dir and nondir :-( + * We preseve the 2.2 order */ if (opt_prt & PRNT_FH) { if (get_stat_info("fh", svcinfo)) { /* >= 2.4 */ + int t = svcfhinfo[3]; + svcfhinfo[3]=svcfhinfo[4]; + svcfhinfo[4]=t; + svcfhinfo[5]=svcfhinfo[0]; /* relocate 'stale' */ + print_numbers( "Server file handle cache:\n" "lookup anon ncachedir ncachedir stale\n", @@ -301,7 +330,8 @@ static void print_callstats(const char *hdr, const char **names, unsigned int *info, unsigned int nr) { - unsigned int total; + unsigned long long total; + unsigned long long pct; int i, j; fputs(hdr, stdout); @@ -313,9 +343,10 @@ print_callstats(const char *hdr, const char **names, for (j = 0; j < 6 && i + j < nr; j++) printf("%-11s", names[i+j]); printf("\n"); - for (j = 0; j < 6 && i + j < nr; j++) - printf("%-6d %2d%% ", - info[i+j], 100 * info[i+j] / total); + 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("\n"); } printf("\n"); @@ -332,8 +363,8 @@ parse_statfile(const char *name, struct statinfo *statp) * be a fatal error -- it usually means the module isn't loaded. */ if ((fp = fopen(name, "r")) == NULL) { - fprintf(stderr, "Warning: %s: %m\n", name); - return 1; + // fprintf(stderr, "Warning: %s: %m\n", name); + return 0; } while (fgets(buffer, sizeof(buffer), fp) != NULL) { @@ -362,3 +393,51 @@ parse_statfile(const char *name, struct statinfo *statp) fclose(fp); return 1; } + +static int +mounts(const char *name) +{ + char buffer[4096], *next; + FILE *fp; + + /* Being unable to read e.g. the nfsd stats file shouldn't + * be a fatal error -- it usually means the module isn't loaded. + */ + if ((fp = fopen(name, "r")) == NULL) { + fprintf(stderr, "Warning: %s: %m\n", name); + return -1; + } + + while (fgets(buffer, sizeof(buffer), fp) != NULL) { + char *line = buffer; + char *device, *mount, *type, *flags; + + if ((next = strchr(line, '\n')) != NULL) + *next = '\0'; + + if (!(device = strtok(line, " \t"))) + continue; + + if (!(mount = strtok(NULL, " \t"))) + continue; + + if (!(type = strtok(NULL, " \t"))) + continue; + + if (strcmp(type, "nfs")) { + continue; + } + + if (!(flags = strtok(NULL, " \t"))) + continue; + + printf("%s from %s\n", mount, device); + printf(" Flags:\t%s\n", flags); + printf("\n"); + + continue; + } + + fclose(fp); + return 0; +}