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
20 #include <sys/types.h>
29 #include <sunrpc/debug.h> */
31 #include <nfs_fs.h> */
32 /* NFSD and NLM debug flags
33 #include <nfsd/debug.h> */
34 #include <nfs/debug.h>
36 static int verbose = 0;
39 static unsigned int find_flag(char **module, char *name);
40 static unsigned int get_flags(char *);
41 static unsigned int set_flags(char *, unsigned int value);
42 static void print_flags(FILE *, char *, unsigned int, int);
43 static char * strtolower(char *str);
44 static void usage(int excode, char *module);
47 main(int argc, char **argv)
51 unsigned int flags = 0, oflags;
55 cdename = malloc(strlen(basename(argv[0])));
56 if (cdename == NULL) {
57 fprintf(stderr, "failed in malloc\n");
60 strcpy(cdename, basename(argv[0]));
62 if (!strcmp(cdename, "nfsdebug")) {
65 else if (!strcmp(cdename, "nfsddebug")) {
69 while ((c = getopt(argc, argv, "chm:sv")) != EOF) {
86 fprintf(stderr, "%s: unknown option -%c\n", cdename, optopt);
91 if (opt_c + opt_s > 1) {
92 fprintf(stderr, "You can use at most one of -c and -s\n");
97 fprintf(stderr, "%s: no module name specified.\n", cdename);
101 if (strcmp(module, "nfsd") &&
102 strcmp(module, "nfs") &&
103 strcmp(module, "nlm") &&
104 strcmp(module, "rpc")) {
105 fprintf(stderr, "%s: unknown module: %s\n", cdename, module);
109 if (argc == optind) {
110 flags = ~(unsigned int) 0;
112 for (; optind < argc; optind++)
113 flags |= find_flag(&module, argv[optind]);
118 oflags = get_flags(module);
121 oflags = set_flags(module, oflags & ~flags);
123 oflags = set_flags(module, oflags | flags);
125 print_flags(stdout, module, oflags, 0);
127 fprintf(stdout, "\nModule Valid flags\n");
128 print_flags(stdout, module, ~(unsigned int) 0, 1);
134 #define FLAG(mname, fname) \
135 { #mname, #fname, mname##DBG_##fname }
137 static struct flagmap {
158 FLAG(NFS, LOOKUPCACHE),
159 FLAG(NFS, PAGECACHE),
164 // FLAG(NFS, CALLBACK),
175 FLAG(NFSD, REPCACHE),
188 FLAG(NLM, HOSTCACHE),
195 find_flag(char **module, char *name)
198 unsigned int value = 0;
201 for (i = 0; flagmap[i].module; i++) {
202 if ((mod && strcasecmp(mod, flagmap[i].module))
203 || strcasecmp(name, flagmap[i].name))
207 "%s: ambiguous symbol name %s.\n"
208 "This name is used by more than one module, "
209 "please specify the module name using\n"
214 value = flagmap[i].value;
217 mod = flagmap[i].module;
223 "%s: unknown module or flag %s/%s\n",
224 cdename, *module, name);
227 "%s: unknown flag %s\n",
237 get_flags(char *module)
239 char buffer[256], filename[256];
242 snprintf(filename, 256, "/proc/sys/sunrpc/%s_debug", module);
244 if ((sysfd = open(filename, O_RDONLY)) < 0) {
248 if ((len = read(sysfd, buffer, sizeof(buffer))) < 0) {
253 buffer[len - 1] = '\0';
255 return strtoul(buffer, NULL, 0);
259 set_flags(char *module, unsigned int value)
261 char buffer[64], filename[256];
264 snprintf(filename, 256, "/proc/sys/sunrpc/%s_debug", module);
266 len = sprintf(buffer, "%d", value);
267 if ((sysfd = open(filename, O_WRONLY)) < 0) {
271 if ((ret = write(sysfd, buffer, len)) < 0) {
276 fprintf(stderr, "error: short write in set_flags!\n");
285 strtolower(char *str)
287 static char temp[64];
291 for (sp = temp; *sp; sp++)
297 print_flags(FILE *ofp, char *module, unsigned int flags, int show_all)
299 char *lastmod = NULL;
300 unsigned int shown = 0;
304 fprintf(ofp, "%-10s", strtolower(module));
306 fprintf(ofp, "<no flags set>\n");
311 for (i = 0, shown = 0; flagmap[i].module; i++) {
313 if (strcasecmp(flagmap[i].module, module))
315 } else if (!lastmod || strcmp(lastmod, flagmap[i].module)) {
320 fprintf(ofp, "%-10s", strtolower(flagmap[i].module));
321 lastmod = flagmap[i].module;
323 if (!(flags & flagmap[i].value)
324 || (!show_all && (shown & flagmap[i].value))
325 || (module && !strcasecmp(flagmap[i].name, "all")))
327 fprintf(ofp, " %s", strtolower(flagmap[i].name));
328 shown |= flagmap[i].value;
334 usage(int excode, char *module)
337 fprintf(stderr, "usage: %s [-v] [-h] [-s flags...|-c flags...]\n", cdename);
339 fprintf(stderr, "usage: %s [-v] [-h] [-m module] [-s flags...|-c flags...]\n", cdename);
340 fprintf(stderr, " set or cancel debug flags.\n");
342 fprintf(stderr, "\nModule Valid flags\n");
343 print_flags(stderr, module, ~(unsigned int) 0, 1);
346 fprintf(stderr, " (use %s -vh to get a list of valid flags)\n", cdename);
348 fprintf(stderr, " (use %s -vh to get a list of modules and valid flags)\n", cdename);