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, Olaf Kirch <okir@monad.swb.de>
25
#include <nfs/debug.h>
28
static int verbose = 0;
32
static void find_offset(char *module);
33
static unsigned int find_flag(char **module, char *name);
34
static unsigned int get_flags(void);
35
static void set_flags(unsigned int value);
36
static void print_flags(char *module, unsigned int flags);
37
static void usage(int excode);
40
main(int argc, char **argv)
44
unsigned int flags = 0, oflags;
48
while ((c = getopt(argc, argv, "chm:sv")) != EOF) {
65
fprintf(stderr, "rpcdebug: unknown option -%c\n",
71
if (opt_c + opt_s > 1) {
72
fprintf(stderr, "You can use at most one of -c and -s\n");
77
flags = ~(unsigned int) 0;
79
for (; optind < argc; optind++) {
82
if (!(temp = find_flag(&module, argv[optind]))) {
83
fprintf(stderr, "rpcdebug: unknown flag %s\n",
92
fprintf(stderr, "rpcdebug: no module name specified, and "
93
"could not be inferred.\n");
97
if ((memfd = open("/dev/kmem", O_RDWR)) < 0) {
98
perror("can't open /dev/mem");
104
oflags = get_flags();
107
set_flags(oflags & ~flags);
109
set_flags(oflags | flags);
111
print_flags(module, oflags);
118
#define FLAG(mname, fname) \
119
{ #mname, #fname, mname##DBG_##fname }
121
static struct flagmap {
140
/* currently handled by RPCDBG_NFS */
150
FLAG(NFSD, REPCACHE),
169
find_flag(char **module, char *name)
172
unsigned int value = 0;
175
for (i = 0; flagmap[i].module; i++) {
176
if ((mod && strcasecmp(mod, flagmap[i].module))
177
|| strcasecmp(name, flagmap[i].name))
181
"rpcdebug: ambiguous symbol name %s.\n"
182
"This name is used by more than one module, "
183
"please specify the module name using\n"
188
value = flagmap[i].value;
191
mod = flagmap[i].module;
204
if (lseek(memfd, flagpos, SEEK_SET) < 0) {
208
if ((count = read(memfd, &value, sizeof(value))) < 0) {
212
if (count != sizeof(value)) {
213
fprintf(stderr, "read failed (only %d bytes read)\n",
218
printf("getting flags 0x%x\n", value);
223
set_flags(unsigned int value)
228
printf("setting flags 0x%x\n", value);
229
if (lseek(memfd, flagpos, SEEK_SET) < 0) {
233
if ((count = write(memfd, &value, sizeof(value))) < 0) {
237
if (count != sizeof(value)) {
238
fprintf(stderr, "write failed (only %d bytes written)\n",
245
find_offset(char *module)
247
char buffer[512], *sp;
252
len = sprintf(symbol, "%s_debug", module);
254
if ((fp = fopen("/proc/ksyms", "r")) < 0) {
255
perror("rpcdebug: can't open /proc/ksyms");
259
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
260
if (!(sp = strchr(buffer, ' ')))
262
if (strncmp(++sp, symbol, len))
264
if (sp[len] != '\n' && sp[len] != '\t'
265
&& strncmp(sp+len, "_R", 2))
267
flagpos = (unsigned long) strtol(buffer, &sp, 16);
268
/* printf("position is %lx\n", flagpos); */
269
if (sp && *sp == ' ')
271
fprintf(stderr, "rpcdebug: weird line in /proc/ksyms: %s\n",
276
fprintf(stderr, "rpcdebug: debug symbol for module %s not found.\n",
282
strtolower(char *str)
284
static char temp[64];
288
for (sp = temp; *sp; sp++)
294
print_flags(char *module, unsigned int flags)
296
char *lastmod = NULL;
300
printf("%-10s", strtolower(module));
302
printf("<no flags set>\n");
305
/* printf(" <%x>", flags); */
308
for (i = 0; flagmap[i].module; i++) {
310
if (strcasecmp(flagmap[i].module, module))
312
} else if (!lastmod || strcmp(lastmod, flagmap[i].module)) {
315
printf("%-10s", strtolower(flagmap[i].module));
316
lastmod = flagmap[i].module;
318
if (!(flags & flagmap[i].value)
319
|| (module && !strcasecmp(flagmap[i].name, "all")))
321
printf(" %s", strtolower(flagmap[i].name));
329
fprintf(stderr, "usage: rpcdebug [-m module] [-cs] flags ...\n");
331
printf("\nModule Valid flags\n");
332
print_flags(NULL, ~(unsigned int) 0);