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>
16 #include <sys/types.h>
24 #include <nfs/debug.h>
26 static int verbose = 0;
28 static int find_sysname(char *module);
29 static unsigned int find_flag(char **module, char *name);
30 static unsigned int get_flags(char *);
31 static unsigned int set_flags(char *, unsigned int value);
32 static void print_flags(FILE *, char *, unsigned int, int);
33 static char * strtolower(char *str);
34 static void usage(int excode);
37 main(int argc, char **argv)
41 unsigned int flags = 0, oflags;
45 while ((c = getopt(argc, argv, "chm:sv")) != EOF) {
62 fprintf(stderr, "rpcdebug: unknown option -%c\n",
68 if (opt_c + opt_s > 1) {
69 fprintf(stderr, "You can use at most one of -c and -s\n");
74 flags = ~(unsigned int) 0;
76 for (; optind < argc; optind++)
77 flags |= find_flag(&module, argv[optind]);
83 fprintf(stderr, "rpcdebug: no module name specified, and "
84 "could not be inferred.\n");
88 oflags = get_flags(module);
91 oflags = set_flags(module, oflags & ~flags);
93 oflags = set_flags(module, oflags | flags);
95 print_flags(stdout, module, oflags, 0);
100 #define FLAG(mname, fname) \
101 { #mname, #fname, mname##DBG_##fname }
102 #define SHORTFLAG(mname, fname, dbgname) \
103 { #mname, #fname, mname##DBG_##dbgname }
105 static struct flagmap {
126 FLAG(NFS, LOOKUPCACHE),
127 FLAG(NFS, PAGECACHE),
130 SHORTFLAG(NFS, dir, DIRCACHE),
131 SHORTFLAG(NFS, lookup, LOOKUPCACHE),
132 SHORTFLAG(NFS, page, PAGECACHE),
142 FLAG(NFSD, REPCACHE),
161 find_flag(char **module, char *name)
164 unsigned int value = 0;
167 for (i = 0; flagmap[i].module; i++) {
168 if ((mod && strcasecmp(mod, flagmap[i].module))
169 || strcasecmp(name, flagmap[i].name))
173 "rpcdebug: ambiguous symbol name %s.\n"
174 "This name is used by more than one module, "
175 "please specify the module name using\n"
180 value = flagmap[i].value;
183 mod = flagmap[i].module;
189 "rpcdebug: unknown module or flag %s/%s\n",
193 "rpcdebug: unknown flag %s\n",
203 get_flags(char *module)
205 char buffer[256], *sp;
206 int sysfd, len, namelen;
208 if ((sysfd = open("/proc/net/rpc/debug", O_RDONLY)) < 0) {
209 perror("/proc/net/rpc/debug");
212 if ((len = read(sysfd, buffer, sizeof(buffer))) < 0) {
217 buffer[len - 1] = '\0';
219 namelen = strlen(module);
220 for (sp = strtok(buffer, " \t"); sp; sp = strtok(NULL, " \t")) {
221 if (!strncmp(sp, module, namelen) && sp[namelen] == '=') {
223 return strtoul(sp + namelen + 1, NULL, 0);
227 fprintf(stderr, "Unknown module %s\n", module);
232 set_flags(char *module, unsigned int value)
237 len = sprintf(buffer, "%s=%u\n", module, value);
238 if ((sysfd = open("/proc/net/rpc/debug", O_WRONLY)) < 0) {
239 perror("/proc/net/rpc/debug");
242 if ((ret = write(sysfd, buffer, len)) < 0) {
247 fprintf(stderr, "error: short write in set_flags!\n");
255 find_sysname(char *module)
260 module = strtolower(module);
262 sprintf(procname, "/proc/sys/sunrpc/%s_debug", module);
263 if ((fd = open(procname, O_RDWR)) < 0) {
272 strtolower(char *str)
274 static char temp[64];
278 for (sp = temp; *sp; sp++)
284 print_flags(FILE *ofp, char *module, unsigned int flags, int show_all)
286 char *lastmod = NULL;
287 unsigned int shown = 0;
291 fprintf(ofp, "%-10s", strtolower(module));
293 fprintf(ofp, "<no flags set>\n");
296 /* printf(" <%x>", flags); */
299 for (i = 0, shown = 0; flagmap[i].module; i++) {
301 if (strcasecmp(flagmap[i].module, module))
303 } else if (!lastmod || strcmp(lastmod, flagmap[i].module)) {
308 fprintf(ofp, "%-10s", strtolower(flagmap[i].module));
309 lastmod = flagmap[i].module;
311 if (!(flags & flagmap[i].value)
312 || (!show_all && (shown & flagmap[i].value))
313 || (module && !strcasecmp(flagmap[i].name, "all")))
315 fprintf(ofp, " %s", strtolower(flagmap[i].name));
316 shown |= flagmap[i].value;
324 fprintf(stderr, "usage: rpcdebug [-m module] [-cs] flags ...\n");
326 fprintf(stderr, "\nModule Valid flags\n");
327 print_flags(stderr, NULL, ~(unsigned int) 0, 1);
330 " (use rpcdebug -vh to get a list of valid flags)\n");