2 * Get or set RPC debug flags.
4 * I would have loved to write this without recourse to the sysctl
5 * interface, but the only plausible approach (reading and writing
6 * /dev/kmem at the offsets indicated by the _debug symbols from
7 * /proc/ksyms) didn't work, because /dev/kmem doesn't translate virtual
8 * addresses on write. Unfortunately, modules are stuffed into memory
9 * allocated via vmalloc.
11 * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
12 * (C) 2004 <frederic.jolly@bull.ext.net>
14 * 06/15/2004: updated for NFSv4
18 /* #include "config.h" */
20 #include <sys/types.h>
30 #include <sunrpc/debug.h> */
32 #include <nfs_fs.h> */
33 /* NFSD and NLM debug flags
34 #include <nfsd/debug.h> */
35 #include <nfs/debug.h>
37 static int verbose = 0;
40 static unsigned int find_flag(char **module, char *name);
41 static unsigned int get_flags(char *);
42 static unsigned int set_flags(char *, unsigned int value);
43 static void print_flags(FILE *, char *, unsigned int, int);
44 static char * strtolower(char *str);
45 static void usage(int excode, char *module);
48 main(int argc, char **argv)
52 unsigned int flags = 0, oflags;
56 cdename = malloc(strlen(basename(argv[0])));
57 if (cdename == NULL) {
58 fprintf(stderr, "failed in malloc\n");
61 strcpy(cdename, basename(argv[0]));
63 if (!strcmp(cdename, "nfsdebug")) {
66 else if (!strcmp(cdename, "nfsddebug")) {
70 while ((c = getopt(argc, argv, "chm:sv")) != EOF) {
87 fprintf(stderr, "%s: unknown option -%c\n", cdename, optopt);
92 if (opt_c + opt_s > 1) {
93 fprintf(stderr, "You can use at most one of -c and -s\n");
98 fprintf(stderr, "%s: no module name specified.\n", cdename);
102 if (strcmp(module, "nfsd") &&
103 strcmp(module, "nfs") &&
104 strcmp(module, "nlm") &&
105 strcmp(module, "rpc")) {
106 fprintf(stderr, "%s: unknown module: %s\n", cdename, module);
110 if (argc == optind) {
111 flags = ~(unsigned int) 0;
113 for (; optind < argc; optind++)
114 flags |= find_flag(&module, argv[optind]);
119 oflags = get_flags(module);
122 oflags = set_flags(module, oflags & ~flags);
124 oflags = set_flags(module, oflags | flags);
126 print_flags(stdout, module, oflags, 0);
128 fprintf(stdout, "\nModule Valid flags\n");
129 print_flags(stdout, module, ~(unsigned int) 0, 1);
135 #define FLAG(mname, fname) \
136 { #mname, #fname, mname##DBG_##fname }
138 static struct flagmap {
161 FLAG(NFS, LOOKUPCACHE),
162 FLAG(NFS, PAGECACHE),
180 FLAG(NFSD, REPCACHE),
193 FLAG(NLM, HOSTCACHE),
201 find_flag(char **module, char *name)
204 unsigned int value = 0;
207 for (i = 0; flagmap[i].module; i++) {
208 if ((mod && strcasecmp(mod, flagmap[i].module))
209 || strcasecmp(name, flagmap[i].name))
213 "%s: ambiguous symbol name %s.\n"
214 "This name is used by more than one module, "
215 "please specify the module name using\n"
220 value = flagmap[i].value;
223 mod = flagmap[i].module;
229 "%s: unknown module or flag %s/%s\n",
230 cdename, *module, name);
233 "%s: unknown flag %s\n",
243 get_flags(char *module)
245 char buffer[256], filename[256];
248 snprintf(filename, 256, "/proc/sys/sunrpc/%s_debug", module);
250 if ((sysfd = open(filename, O_RDONLY)) < 0) {
254 if ((len = read(sysfd, buffer, sizeof(buffer))) < 0) {
259 buffer[len - 1] = '\0';
261 return strtoul(buffer, NULL, 0);
265 set_flags(char *module, unsigned int value)
267 char buffer[64], filename[256];
270 snprintf(filename, 256, "/proc/sys/sunrpc/%s_debug", module);
272 len = sprintf(buffer, "%d", value);
273 if ((sysfd = open(filename, O_WRONLY)) < 0) {
277 if ((ret = write(sysfd, buffer, len)) < 0) {
282 fprintf(stderr, "error: short write in set_flags!\n");
291 strtolower(char *str)
293 static char temp[64];
297 for (sp = temp; *sp; sp++)
303 print_flags(FILE *ofp, char *module, unsigned int flags, int show_all)
305 char *lastmod = NULL;
306 unsigned int shown = 0;
310 fprintf(ofp, "%-10s", strtolower(module));
312 fprintf(ofp, "<no flags set>\n");
317 for (i = 0, shown = 0; flagmap[i].module; i++) {
319 if (strcasecmp(flagmap[i].module, module))
321 } else if (!lastmod || strcmp(lastmod, flagmap[i].module)) {
326 fprintf(ofp, "%-10s", strtolower(flagmap[i].module));
327 lastmod = flagmap[i].module;
329 if (!(flags & flagmap[i].value)
330 || (!show_all && (shown & flagmap[i].value))
331 || (module && !strcasecmp(flagmap[i].name, "all")))
333 fprintf(ofp, " %s", strtolower(flagmap[i].name));
334 shown |= flagmap[i].value;
340 usage(int excode, char *module)
343 fprintf(stderr, "usage: %s [-v] [-h] [-s flags...|-c flags...]\n", cdename);
345 fprintf(stderr, "usage: %s [-v] [-h] [-m module] [-s flags...|-c flags...]\n", cdename);
346 fprintf(stderr, " set or cancel debug flags.\n");
348 fprintf(stderr, "\nModule Valid flags\n");
349 print_flags(stderr, module, ~(unsigned int) 0, 1);
352 fprintf(stderr, " (use %s -vh to get a list of valid flags)\n", cdename);
354 fprintf(stderr, " (use %s -vh to get a list of modules and valid flags)\n", cdename);