~ubuntu-branches/ubuntu/precise/nfs-utils/precise-proposed

« back to all changes in this revision

Viewing changes to tools/rpcdebug/rpcdebug.c

  • Committer: Bazaar Package Importer
  • Author(s): Nathaniel McCallum
  • Date: 2004-09-10 13:10:39 UTC
  • Revision ID: james.westby@ubuntu.com-20040910131039-qxfjx4pwgoz6imbv
Tags: upstream-1.0.6
ImportĀ upstreamĀ versionĀ 1.0.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Get or set RPC debug flags.
 
3
 *
 
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.
 
10
 *
 
11
 * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
 
12
 */
 
13
 
 
14
#include "config.h"
 
15
 
 
16
#include <sys/types.h>
 
17
#include <stdio.h>
 
18
#include <stdlib.h>
 
19
#include <getopt.h>
 
20
#include <unistd.h>
 
21
#include <string.h>
 
22
#include <fcntl.h>
 
23
#include <ctype.h>
 
24
#include <nfs/debug.h>
 
25
 
 
26
static int              verbose = 0;
 
27
 
 
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);
 
35
 
 
36
int
 
37
main(int argc, char **argv)
 
38
{
 
39
        int             opt_s = 0,
 
40
                        opt_c = 0;
 
41
        unsigned int    flags = 0, oflags;
 
42
        char *          module = NULL;
 
43
        int             c;
 
44
 
 
45
        while ((c = getopt(argc, argv, "chm:sv")) != EOF) {
 
46
                switch (c) {
 
47
                case 'c':
 
48
                        opt_c = 1;
 
49
                        break;
 
50
                case 'h':
 
51
                        usage(0);
 
52
                case 'm':
 
53
                        module = optarg;
 
54
                        break;
 
55
                case 's':
 
56
                        opt_s = 1;
 
57
                        break;
 
58
                case 'v':
 
59
                        verbose++;
 
60
                        break;
 
61
                default:
 
62
                        fprintf(stderr, "rpcdebug: unknown option -%c\n",
 
63
                                                optopt);
 
64
                        usage(1);
 
65
                }
 
66
        }
 
67
 
 
68
        if (opt_c + opt_s > 1) {
 
69
                fprintf(stderr, "You can use at most one of -c and -s\n");
 
70
                usage(1);
 
71
        }
 
72
 
 
73
        if (argc == optind) {
 
74
                flags = ~(unsigned int) 0;
 
75
        } else {
 
76
                for (; optind < argc; optind++)
 
77
                        flags |= find_flag(&module, argv[optind]);
 
78
                if (flags && !opt_c)
 
79
                        opt_s = 1;
 
80
        }
 
81
 
 
82
        if (!module) {
 
83
                fprintf(stderr, "rpcdebug: no module name specified, and "
 
84
                                "could not be inferred.\n");
 
85
                usage(1);
 
86
        }
 
87
 
 
88
        oflags = get_flags(module);
 
89
 
 
90
        if (opt_c) {
 
91
                oflags = set_flags(module, oflags & ~flags);
 
92
        } else if (opt_s) {
 
93
                oflags = set_flags(module, oflags | flags);
 
94
        }
 
95
        print_flags(stdout, module, oflags, 0);
 
96
 
 
97
        return 0;
 
98
}
 
99
 
 
100
#define FLAG(mname, fname)      \
 
101
      { #mname, #fname, mname##DBG_##fname }
 
102
#define SHORTFLAG(mname, fname, dbgname)        \
 
103
      { #mname, #fname, mname##DBG_##dbgname }
 
104
 
 
105
static struct flagmap {
 
106
        char *          module;
 
107
        char *          name;
 
108
        unsigned int    value;
 
109
}                       flagmap[] = {
 
110
        /* rpc */
 
111
        FLAG(RPC,       XPRT),
 
112
        FLAG(RPC,       CALL),
 
113
        FLAG(RPC,       DEBUG),
 
114
        FLAG(RPC,       NFS),
 
115
        FLAG(RPC,       AUTH),
 
116
        FLAG(RPC,       PMAP),
 
117
        FLAG(RPC,       SCHED),
 
118
        FLAG(RPC,       SVCSOCK),
 
119
        FLAG(RPC,       SVCDSP),
 
120
        FLAG(RPC,       MISC),
 
121
        FLAG(RPC,       ALL),
 
122
 
 
123
        /* nfs */
 
124
        FLAG(NFS,       VFS),
 
125
        FLAG(NFS,       DIRCACHE),
 
126
        FLAG(NFS,       LOOKUPCACHE),
 
127
        FLAG(NFS,       PAGECACHE),
 
128
        FLAG(NFS,       PROC),
 
129
        FLAG(NFS,       ALL),
 
130
        SHORTFLAG(NFS,  dir,    DIRCACHE),
 
131
        SHORTFLAG(NFS,  lookup, LOOKUPCACHE),
 
132
        SHORTFLAG(NFS,  page,   PAGECACHE),
 
133
 
 
134
        /* nfsd */
 
135
        FLAG(NFSD,      SOCK),
 
136
        FLAG(NFSD,      FH),
 
137
        FLAG(NFSD,      EXPORT),
 
138
        FLAG(NFSD,      SVC),
 
139
        FLAG(NFSD,      PROC),
 
140
        FLAG(NFSD,      FILEOP),
 
141
        FLAG(NFSD,      AUTH),
 
142
        FLAG(NFSD,      REPCACHE),
 
143
        FLAG(NFSD,      XDR),
 
144
        FLAG(NFSD,      LOCKD),
 
145
        FLAG(NFSD,      ALL),
 
146
 
 
147
        /* lockd */
 
148
        FLAG(NLM,       SVC),
 
149
        FLAG(NLM,       CLIENT),
 
150
        FLAG(NLM,       CLNTLOCK),
 
151
        FLAG(NLM,       SVCLOCK),
 
152
        FLAG(NLM,       MONITOR),
 
153
        FLAG(NLM,       CLNTSUBS),
 
154
        FLAG(NLM,       SVCSUBS),
 
155
        FLAG(NLM,       ALL),
 
156
 
 
157
      { NULL,           NULL,           0 }
 
158
};
 
159
 
 
160
static unsigned int
 
161
find_flag(char **module, char *name)
 
162
{
 
163
        char            *mod = *module;
 
164
        unsigned int    value = 0;
 
165
        int             i;
 
166
 
 
167
        for (i = 0; flagmap[i].module; i++) {
 
168
                if ((mod && strcasecmp(mod, flagmap[i].module))
 
169
                 || strcasecmp(name, flagmap[i].name))
 
170
                        continue;
 
171
                if (value) {
 
172
                        fprintf(stderr,
 
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"
 
176
                                "the -m option.\n",
 
177
                                name);
 
178
                        usage(1);
 
179
                }
 
180
                value = flagmap[i].value;
 
181
                if (*module)
 
182
                        return value;
 
183
                mod = flagmap[i].module;
 
184
        }
 
185
 
 
186
        if (!value) {
 
187
                if (*module)
 
188
                        fprintf(stderr,
 
189
                                "rpcdebug: unknown module or flag %s/%s\n",
 
190
                                *module, name);
 
191
                else
 
192
                        fprintf(stderr,
 
193
                                "rpcdebug: unknown flag %s\n",
 
194
                                name);
 
195
                exit(1);
 
196
        }
 
197
 
 
198
        *module = mod;
 
199
        return value;
 
200
}
 
201
 
 
202
static unsigned int
 
203
get_flags(char *module)
 
204
{
 
205
        char    buffer[256], *sp;
 
206
        int     sysfd, len, namelen;
 
207
 
 
208
        if ((sysfd = open("/proc/net/rpc/debug", O_RDONLY)) < 0) {
 
209
                perror("/proc/net/rpc/debug");
 
210
                exit(1);
 
211
        }
 
212
        if ((len = read(sysfd, buffer, sizeof(buffer))) < 0) {
 
213
                perror("read");
 
214
                exit(1);
 
215
        }
 
216
        close(sysfd);
 
217
        buffer[len - 1] = '\0';
 
218
 
 
219
        namelen = strlen(module);
 
220
        for (sp = strtok(buffer, " \t"); sp; sp = strtok(NULL, " \t")) {
 
221
                if (!strncmp(sp, module, namelen) && sp[namelen] == '=') {
 
222
 
 
223
                        return strtoul(sp + namelen + 1, NULL, 0);
 
224
                }
 
225
        }
 
226
 
 
227
        fprintf(stderr, "Unknown module %s\n", module);
 
228
        exit(1);
 
229
}
 
230
 
 
231
static unsigned int
 
232
set_flags(char *module, unsigned int value)
 
233
{
 
234
        char    buffer[64];
 
235
        int     sysfd, len, ret;
 
236
 
 
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");
 
240
                exit(1);
 
241
        }
 
242
        if ((ret = write(sysfd, buffer, len)) < 0) {
 
243
                perror("write");
 
244
                exit(1);
 
245
        }
 
246
        if (ret < len) {
 
247
                fprintf(stderr, "error: short write in set_flags!\n");
 
248
                exit(1);
 
249
        }
 
250
        close(sysfd);
 
251
        return value;
 
252
}
 
253
 
 
254
static int
 
255
find_sysname(char *module)
 
256
{
 
257
        char    procname[1024];
 
258
        int     fd;
 
259
 
 
260
        module = strtolower(module);
 
261
 
 
262
        sprintf(procname, "/proc/sys/sunrpc/%s_debug", module);
 
263
        if ((fd = open(procname, O_RDWR)) < 0) {
 
264
                perror(procname);
 
265
                exit(1);
 
266
        }
 
267
 
 
268
        return fd;
 
269
}
 
270
 
 
271
static char *
 
272
strtolower(char *str)
 
273
{
 
274
        static char     temp[64];
 
275
        char            *sp;
 
276
 
 
277
        strcpy(temp, str);
 
278
        for (sp = temp; *sp; sp++)
 
279
                *sp = tolower(*sp);
 
280
        return temp;
 
281
}
 
282
 
 
283
static void
 
284
print_flags(FILE *ofp, char *module, unsigned int flags, int show_all)
 
285
{
 
286
        char            *lastmod = NULL;
 
287
        unsigned int    shown = 0;
 
288
        int             i;
 
289
 
 
290
        if (module) {
 
291
                fprintf(ofp, "%-10s", strtolower(module));
 
292
                if (!flags) {
 
293
                        fprintf(ofp, "<no flags set>\n");
 
294
                        return;
 
295
                }
 
296
                /* printf(" <%x>", flags); */
 
297
        }
 
298
 
 
299
        for (i = 0, shown = 0; flagmap[i].module; i++) {
 
300
                if (module) {
 
301
                        if (strcasecmp(flagmap[i].module, module))
 
302
                                continue;
 
303
                } else if (!lastmod || strcmp(lastmod, flagmap[i].module)) {
 
304
                        if (lastmod) {
 
305
                                fprintf(ofp, "\n");
 
306
                                shown = 0;
 
307
                        }
 
308
                        fprintf(ofp, "%-10s", strtolower(flagmap[i].module));
 
309
                        lastmod = flagmap[i].module;
 
310
                }
 
311
                if (!(flags & flagmap[i].value)
 
312
                 || (!show_all && (shown & flagmap[i].value))
 
313
                 || (module && !strcasecmp(flagmap[i].name, "all")))
 
314
                        continue;
 
315
                fprintf(ofp, " %s", strtolower(flagmap[i].name));
 
316
                shown |= flagmap[i].value;
 
317
        }
 
318
        fprintf(ofp, "\n");
 
319
}
 
320
 
 
321
static void
 
322
usage(int excode)
 
323
{
 
324
        fprintf(stderr, "usage: rpcdebug [-m module] [-cs] flags ...\n");
 
325
        if (verbose) {
 
326
                fprintf(stderr, "\nModule     Valid flags\n");
 
327
                print_flags(stderr, NULL, ~(unsigned int) 0, 1);
 
328
        } else {
 
329
                fprintf(stderr,
 
330
                    "       (use rpcdebug -vh to get a list of valid flags)\n");
 
331
        }
 
332
        exit (excode);
 
333
}
 
334