~ubuntu-branches/debian/experimental/nfs-utils/experimental

« back to all changes in this revision

Viewing changes to tools/rpcdebug/neat_idea.c

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2006-07-08 14:26:40 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060708142640-r171kjj2a13gy2kz
Tags: 1:1.0.9-1
* Updated co-mantainer mail address.
* New upstream release.
  - Added 'mount.nfs' utility which can be used as a mount helper
    to mount nfs filesystems. It does not yet support 'user' mounts.
  - Makefile/autoconf tidyups
  - No compiles with no warnings
  - deleted debian/* at request of debian maintainer
  - deleted assorted other unused files
  - mountd can be run multi-threaded for configurations with many hundreds
    of clients (mountd -t 20).  Default is single-threaded
  - Support for selection NFS version to be exported, and protocol to
    use.  This requires kernel patches that should be in linux 2.6.19.
  - Use 65534 rather than -2 for default anon.  This makes no difference in many
    cases, but is important in some.
  - New utility 'rpcdebug' for controlled kernel 'debug' options for nfs and nfsd.
  - nfsstat reports NFSv4 operation statistics that should be available in
    linux 2.6.18.
  - assorted other fixes

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