~smoser/ubuntu/quantal/module-init-tools/lp-1115710

« back to all changes in this revision

Viewing changes to .pc/ubuntu-maps_by_default/depmod.c

  • Committer: Bazaar Package Importer
  • Author(s): Andy Whitcroft
  • Date: 2011-06-08 11:53:21 UTC
  • mfrom: (0.1.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110608115321-2zwtf5l3mbbz1sck
Tags: 3.13-1ubuntu1
* Manual Resync with Debian version 3.13-1.
  - Remaining changes:
    + Ubuntu specific control scripts carrying upgrade quirks
    + Ubuntu specific modprobe.d/depmod.d contents
    + debian/patches/ubuntu-maps_by_default -- Reenable map files
    + debian/patches/ubuntu-modinfo-wantparm-uninitialised -- fix
      performance issue due to unitialised variable in modinfo
    + switch source to 'unapply-patches' to simplify merging with
      debian upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * New simplified depmod without backwards compat stuff and not
 
3
 * requiring ksyms.
 
4
 *
 
5
 * (C) 2010 Jon Masters <jcm@jonmasters.org>, and others.
 
6
 * (C) 2002 Rusty Russell IBM Corporation
 
7
 */
 
8
#define _GNU_SOURCE /* asprintf */
 
9
 
 
10
#include <stdio.h>
 
11
#include <stdlib.h>
 
12
#include <getopt.h>
 
13
#include <string.h>
 
14
#include <errno.h>
 
15
#include <unistd.h>
 
16
#include <elf.h>
 
17
#include <sys/types.h>
 
18
#include <sys/stat.h>
 
19
#include <fcntl.h>
 
20
#include <dirent.h>
 
21
#include <sys/utsname.h>
 
22
#include <sys/mman.h>
 
23
 
 
24
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
25
 
 
26
#include "util.h"
 
27
#include "zlibsupport.h"
 
28
#include "depmod.h"
 
29
#include "logging.h"
 
30
#include "index.h"
 
31
#include "elfops.h"
 
32
#include "tables.h"
 
33
#include "config_filter.h"
 
34
 
 
35
#include "testing.h"
 
36
 
 
37
#ifndef MODULE_DIR
 
38
#define MODULE_DIR "/lib/modules/"
 
39
#endif
 
40
 
 
41
#ifndef MODULE_BUILTIN_KEY
 
42
#define MODULE_BUILTIN_KEY "built-in"
 
43
#endif
 
44
 
 
45
struct module_overrides
 
46
{
 
47
        /* Next override */
 
48
        struct module_overrides *next;
 
49
 
 
50
        /* overridden module */
 
51
        char *modfile;
 
52
};
 
53
 
 
54
struct module_search
 
55
{
 
56
        /* Next search */
 
57
        struct module_search *next;
 
58
 
 
59
        /* search path */
 
60
        char *search_path;
 
61
        size_t len;
 
62
};
 
63
 
 
64
static char sym_prefix;
 
65
static unsigned int skipchars;
 
66
static unsigned int make_map_files = 0; /* default to off */
 
67
static unsigned int force_map_files = 0; /* default to on */
 
68
 
 
69
#define SYMBOL_HASH_SIZE 1024
 
70
struct symbol
 
71
{
 
72
        struct symbol *next;
 
73
        struct module *owner;
 
74
        uint64_t ver;
 
75
        char name[0];
 
76
};
 
77
 
 
78
static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
 
79
 
 
80
/* This is based on the hash agorithm from gdbm, via tdb */
 
81
static inline unsigned int tdb_hash(const char *name)
 
82
{
 
83
        unsigned value; /* Used to compute the hash value.  */
 
84
        unsigned   i;   /* Used to cycle through random values. */
 
85
 
 
86
        /* Set the initial value from the key size. */
 
87
        for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
 
88
                value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
 
89
 
 
90
        return (1103515243 * value + 12345);
 
91
}
 
92
 
 
93
static const char *skip_symprefix(const char *symname)
 
94
{
 
95
        return symname + (symname[0] == sym_prefix ? 1 : 0);
 
96
}
 
97
 
 
98
static void add_symbol(const char *name, uint64_t ver, struct module *owner)
 
99
{
 
100
        unsigned int hash;
 
101
        struct symbol *new = NOFAIL(malloc(sizeof *new + strlen(name) + 1));
 
102
 
 
103
        new->owner = owner;
 
104
        new->ver = ver;
 
105
        strcpy(new->name, name);
 
106
 
 
107
        hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
 
108
        new->next = symbolhash[hash];
 
109
        symbolhash[hash] = new;
 
110
}
 
111
 
 
112
static int print_unknown, check_symvers;
 
113
 
 
114
static struct module *find_symbol(const char *name, uint64_t ver,
 
115
                const char *modname, int weak)
 
116
{
 
117
        struct symbol *s;
 
118
 
 
119
        /* For our purposes, .foo matches foo.  PPC64 needs this. */
 
120
        if (name[0] == '.')
 
121
                name++;
 
122
        name = skip_symprefix(name);
 
123
 
 
124
        for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
 
125
                if (streq(s->name, name))
 
126
                        break;
 
127
        }
 
128
        if (s) {
 
129
                if (ver && s->ver && s->ver != ver && print_unknown && !weak)
 
130
                        warn("%s disagrees about version of symbol %s\n",
 
131
                                        modname, name);
 
132
                return s->owner;
 
133
        }
 
134
 
 
135
        if (print_unknown && !weak)
 
136
                warn("%s needs unknown symbol %s\n", modname, name);
 
137
 
 
138
        return NULL;
 
139
}
 
140
 
 
141
static void add_dep(struct module *mod, struct module *depends_on)
 
142
{
 
143
        unsigned int i;
 
144
 
 
145
        for (i = 0; i < mod->num_deps; i++)
 
146
                if (mod->deps[i] == depends_on)
 
147
                        return;
 
148
 
 
149
        mod->deps = NOFAIL(realloc(mod->deps, sizeof(mod->deps[0])*(mod->num_deps+1)));
 
150
        mod->deps[mod->num_deps++] = depends_on;
 
151
}
 
152
 
 
153
static void add_fake_syms(void)
 
154
{
 
155
        /* __this_module is magic inserted by kernel loader. */
 
156
        add_symbol("__this_module", 0, NULL);
 
157
        /* On S390, this is faked up too */
 
158
        add_symbol("_GLOBAL_OFFSET_TABLE_", 0, NULL);
 
159
}
 
160
 
 
161
static void load_system_map(const char *filename)
 
162
{
 
163
        FILE *system_map;
 
164
        char line[10240];
 
165
        const char ksymstr[] = "__ksymtab_";
 
166
        const int ksymstr_len = strlen(ksymstr);
 
167
 
 
168
        system_map = fopen(filename, "r");
 
169
        if (!system_map)
 
170
                fatal("Could not open '%s': %s\n", filename, strerror(errno));
 
171
 
 
172
        /* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
 
173
        while (fgets(line, sizeof(line)-1, system_map)) {
 
174
                char *ptr;
 
175
                const char *cptr;
 
176
 
 
177
                /* Snip \n */
 
178
                ptr = strchr(line, '\n');
 
179
                if (ptr)
 
180
                        *ptr = '\0';
 
181
 
 
182
                ptr = strchr(line, ' ');
 
183
                if (!ptr || !(ptr = strchr(ptr + 1, ' ')))
 
184
                        continue;
 
185
 
 
186
                /* Skip the space before symbol name */
 
187
                cptr = skip_symprefix(ptr + 1);
 
188
 
 
189
                /* Covers gpl-only and normal symbols. */
 
190
                if (strstarts(cptr, ksymstr))
 
191
                        add_symbol(cptr + ksymstr_len, 0, NULL);
 
192
        }
 
193
 
 
194
        fclose(system_map);
 
195
        add_fake_syms();
 
196
}
 
197
 
 
198
static void load_module_symvers(const char *filename)
 
199
{
 
200
        FILE *module_symvers;
 
201
        char line[10240];
 
202
 
 
203
        module_symvers = fopen(filename, "r");
 
204
        if (!module_symvers)
 
205
                fatal("Could not open '%s': %s\n", filename, strerror(errno));
 
206
 
 
207
        /* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */
 
208
        while (fgets(line, sizeof(line)-1, module_symvers)) {
 
209
                const char *ver, *sym, *where;
 
210
 
 
211
                ver = strtok(line, " \t");
 
212
                sym = strtok(NULL, " \t");
 
213
                where = strtok(NULL, " \t");
 
214
                if (!ver || !sym || !where)
 
215
                        continue;
 
216
 
 
217
                if (streq(where, "vmlinux"))
 
218
                        add_symbol(skip_symprefix(sym), strtoull(ver, NULL, 16), NULL);
 
219
        }
 
220
 
 
221
        fclose(module_symvers);
 
222
        add_fake_syms();
 
223
}
 
224
 
 
225
static const struct option options[] = { { "all", 0, NULL, 'a' },
 
226
                                   { "quick", 0, NULL, 'A' },
 
227
                                   { "basedir", 1, NULL, 'b' },
 
228
                                   { "config", 1, NULL, 'C' },
 
229
                                   { "symvers", 1, NULL, 'E' },
 
230
                                   { "filesyms", 1, NULL, 'F' },
 
231
                                   { "errsyms", 0, NULL, 'e' },
 
232
                                   { "unresolved-error", 0, NULL, 'u' },
 
233
                                   { "quiet", 0, NULL, 'q' },
 
234
                                   { "root", 0, NULL, 'r' },
 
235
                                   { "verbose", 0, NULL, 'v' },
 
236
                                   { "show", 0, NULL, 'n' },
 
237
                                   { "dry-run", 0, NULL, 'n' },
 
238
                                   { "symbol-prefix", 0, NULL, 'P' },
 
239
                                   { "help", 0, NULL, 'h' },
 
240
                                   { "version", 0, NULL, 'V' },
 
241
                                   { "warn", 0, NULL, 'w' },
 
242
                                   { "map", 0, NULL, 'm' },
 
243
                                   { NULL, 0, NULL, 0 } };
 
244
 
 
245
/* Version number or module name?  Don't assume extension. */
 
246
static int is_version_number(const char *version)
 
247
{
 
248
        unsigned int dummy;
 
249
 
 
250
        return (sscanf(version, "%u.%u", &dummy, &dummy) == 2);
 
251
}
 
252
 
 
253
static int old_module_version(const char *version)
 
254
{
 
255
        /* Expect three part version. */
 
256
        unsigned int major, sub, minor;
 
257
 
 
258
        sscanf(version, "%u.%u.%u", &major, &sub, &minor);
 
259
 
 
260
        if (major > 2) return 0;
 
261
        if (major < 2) return 1;
 
262
 
 
263
        /* 2.x */
 
264
        if (sub > 5) return 0;
 
265
        if (sub < 5) return 1;
 
266
 
 
267
        /* 2.5.x */
 
268
        if (minor >= 48) return 0;
 
269
        return 1;
 
270
}
 
271
 
 
272
static void print_usage(const char *name)
 
273
{
 
274
        fprintf(stderr,
 
275
        "%s " VERSION " -- part of " PACKAGE "\n"
 
276
        "%s -[aA] [-n -e -v -q -V -r -u -w -m]\n"
 
277
        "      [-b basedirectory] [forced_version]\n"
 
278
        "depmod [-n -e -v -q -r -u -w] [-F kernelsyms] module1.ko module2.ko ...\n"
 
279
        "If no arguments (except options) are given, \"depmod -a\" is assumed\n"
 
280
        "\n"
 
281
        "depmod will output a dependancy list suitable for the modprobe utility.\n"
 
282
        "\n"
 
283
        "\n"
 
284
        "Options:\n"
 
285
        "\t-a, --all            Probe all modules\n"
 
286
        "\t-A, --quick          Only does the work if there's a new module\n"
 
287
        "\t-e, --errsyms        Report not supplied symbols\n"
 
288
        "\t-m, --map            Create the legacy map files\n"
 
289
        "\t-n, --show           Write the dependency file on stdout only\n"
 
290
        "\t-P, --symbol-prefix  Architecture symbol prefix\n"
 
291
        "\t-V, --version        Print the release version\n"
 
292
        "\t-v, --verbose        Enable verbose mode\n"
 
293
        "\t-w, --warn           Warn on duplicates\n"
 
294
        "\t-h, --help           Print this usage message\n"
 
295
        "\n"
 
296
        "The following options are useful for people managing distributions:\n"
 
297
        "\t-b basedirectory\n"
 
298
        "\t    --basedir basedirectory    Use an image of a module tree.\n"
 
299
        "\t-F kernelsyms\n"
 
300
        "\t    --filesyms kernelsyms      Use the file instead of the\n"
 
301
        "\t                               current kernel symbols.\n"
 
302
        "\t-E Module.symvers\n"
 
303
        "\t    --symvers Module.symvers   Use Module.symvers file to check\n"
 
304
        "\t                               symbol versions.\n",
 
305
        "depmod", "depmod");
 
306
}
 
307
 
 
308
static int ends_in(const char *name, const char *ext)
 
309
{
 
310
        unsigned int namelen, extlen;
 
311
 
 
312
        /* Grab lengths */
 
313
        namelen = strlen(name);
 
314
        extlen = strlen(ext);
 
315
 
 
316
        if (namelen < extlen) return 0;
 
317
 
 
318
        if (streq(name + namelen - extlen, ext))
 
319
                return 1;
 
320
        return 0;
 
321
}
 
322
 
 
323
static struct module *grab_module(const char *dirname, const char *filename)
 
324
{
 
325
        struct module *new;
 
326
 
 
327
        new = NOFAIL(malloc(sizeof(*new)
 
328
                            + strlen(dirname?:"") + 1 + strlen(filename) + 1));
 
329
        if (dirname)
 
330
                sprintf(new->pathname, "%s/%s", dirname, filename);
 
331
        else
 
332
                strcpy(new->pathname, filename);
 
333
        new->basename = my_basename(new->pathname);
 
334
 
 
335
        INIT_LIST_HEAD(&new->dep_list);
 
336
        new->order = INDEX_PRIORITY_MIN;
 
337
 
 
338
        new->file = grab_elf_file(new->pathname);
 
339
        if (!new->file) {
 
340
                warn("Can't read module %s: %s\n",
 
341
                     new->pathname, strerror(errno));
 
342
                free(new);
 
343
                return NULL;
 
344
        }
 
345
        return new;
 
346
}
 
347
 
 
348
struct module_traverse
 
349
{
 
350
        struct module_traverse *prev;
 
351
        struct module *mod;
 
352
};
 
353
 
 
354
static int in_loop(struct module *mod, const struct module_traverse *traverse)
 
355
{
 
356
        const struct module_traverse *i;
 
357
 
 
358
        for (i = traverse; i; i = i->prev) {
 
359
                if (i->mod == mod)
 
360
                        return 1;
 
361
        }
 
362
        return 0;
 
363
}
 
364
 
 
365
/* Assume we are doing all the modules, so only report each loop once. */
 
366
static void report_loop(const struct module *mod,
 
367
                        const struct module_traverse *traverse)
 
368
{
 
369
        const struct module_traverse *i;
 
370
 
 
371
        /* Check that start is least alphabetically.  eg.  a depends
 
372
           on b depends on a will get reported for a, not b.  */
 
373
        for (i = traverse->prev; i->prev; i = i->prev) {
 
374
                if (strcmp(mod->pathname, i->mod->pathname) > 0)
 
375
                        return;
 
376
        }
 
377
 
 
378
        /* Is start in the loop?  If not, don't report now. eg. a
 
379
           depends on b which depends on c which depends on b.  Don't
 
380
           report when generating depends for a. */
 
381
        if (mod != i->mod)
 
382
                return;
 
383
 
 
384
        warn("Loop detected: %s ", mod->pathname);
 
385
        for (i = traverse->prev; i->prev; i = i->prev)
 
386
                fprintf(stderr, "needs %s ", i->mod->basename);
 
387
        fprintf(stderr, "which needs %s again!\n", i->mod->basename);
 
388
}
 
389
 
 
390
/* This is damn slow, but loops actually happen, and we don't want to
 
391
   just exit() and leave the user without any modules. */
 
392
static int has_dep_loop(struct module *module, struct module_traverse *prev)
 
393
{
 
394
        unsigned int i;
 
395
        struct module_traverse traverse = { .prev = prev, .mod = module };
 
396
 
 
397
        if (in_loop(module, prev)) {
 
398
                report_loop(module, &traverse);
 
399
                return 1;
 
400
        }
 
401
 
 
402
        for (i = 0; i < module->num_deps; i++)
 
403
                if (has_dep_loop(module->deps[i], &traverse))
 
404
                        return 1;
 
405
        return 0;
 
406
}
 
407
 
 
408
/* Uniquifies and orders a dependency list. */
 
409
static void order_dep_list(struct module *start, struct module *mod)
 
410
{
 
411
        unsigned int i;
 
412
 
 
413
        for (i = 0; i < mod->num_deps; i++) {
 
414
                /* If it was previously depended on, move it to the
 
415
                   tail.  ie. if a needs b and c, and c needs b, we
 
416
                   must order b after c. */
 
417
                list_del(&mod->deps[i]->dep_list);
 
418
                list_add_tail(&mod->deps[i]->dep_list, &start->dep_list);
 
419
                order_dep_list(start, mod->deps[i]);
 
420
        }
 
421
}
 
422
 
 
423
static struct module *deleted = NULL;
 
424
 
 
425
static void del_module(struct module **modules, struct module *delme)
 
426
{
 
427
        struct module **i;
 
428
 
 
429
        /* Find pointer to it. */ 
 
430
        if (modules) {
 
431
                for (i = modules; *i != delme; i = &(*i)->next);
 
432
                
 
433
                *i = delme->next;
 
434
        }
 
435
        
 
436
        /* Save on a list to quiet valgrind.
 
437
           Can't free - other modules may depend on them */
 
438
        delme->next = deleted;
 
439
        deleted = delme;
 
440
}
 
441
 
 
442
/* convert to relative path if possible */
 
443
static const char *compress_path(const char *path, const char *basedir)
 
444
{
 
445
        int len = strlen(basedir);
 
446
 
 
447
        if (strncmp(path, basedir, len) == 0)
 
448
                path += len + 1;
 
449
        return path;
 
450
}
 
451
 
 
452
static int output_deps(struct module *modules,
 
453
                        FILE *out, char *dirname)
 
454
{
 
455
        struct module *i;
 
456
 
 
457
        for (i = modules; i; i = i->next) {
 
458
                struct list_head *j, *tmp;
 
459
                order_dep_list(i, i);
 
460
 
 
461
                fprintf(out, "%s:", compress_path(i->pathname, dirname));
 
462
                list_for_each_safe(j, tmp, &i->dep_list) {
 
463
                        struct module *dep
 
464
                                = list_entry(j, struct module, dep_list);
 
465
                        fprintf(out, " %s",
 
466
                                compress_path(dep->pathname, dirname));
 
467
                        list_del_init(j);
 
468
                }
 
469
                fprintf(out, "\n");
 
470
        }
 
471
        return 1;
 
472
}
 
473
 
 
474
/* warn whenever duplicate module aliases, deps, or symbols are found. */
 
475
static int warn_dups = 0;
 
476
 
 
477
static int output_deps_bin(struct module *modules,
 
478
                        FILE *out, char *dirname)
 
479
{
 
480
        struct module *i;
 
481
        struct index_node *index;
 
482
        char *line;
 
483
        char *p;
 
484
 
 
485
        index = index_create();
 
486
 
 
487
        for (i = modules; i; i = i->next) {
 
488
                struct list_head *j, *tmp;
 
489
                char modname[strlen(i->pathname)+1];
 
490
                
 
491
                order_dep_list(i, i);
 
492
                
 
493
                filename2modname(modname, i->pathname);
 
494
                nofail_asprintf(&line, "%s:",
 
495
                                compress_path(i->pathname, dirname));
 
496
                p = line;
 
497
                list_for_each_safe(j, tmp, &i->dep_list) {
 
498
                        struct module *dep
 
499
                                = list_entry(j, struct module, dep_list);
 
500
                        nofail_asprintf(&line, "%s %s",
 
501
                                        p,
 
502
                                        compress_path(dep->pathname, dirname));
 
503
                        free(p);
 
504
                        p = line;
 
505
                        list_del_init(j);
 
506
                }
 
507
                if (index_insert(index, modname, line, i->order) && warn_dups)
 
508
                        warn("duplicate module deps:\n%s\n",line);
 
509
                free(line);
 
510
        }
 
511
        
 
512
        index_write(index, out);
 
513
        index_destroy(index);
 
514
 
 
515
        return 1;
 
516
}
 
517
 
 
518
 
 
519
static int smells_like_module(const char *name)
 
520
{
 
521
        return ends_in(name,".ko") || ends_in(name, ".ko.gz");
 
522
}
 
523
 
 
524
typedef struct module *(*do_module_t)(const char *dirname,
 
525
                                      const char *filename,
 
526
                                      struct module *next,
 
527
                                      struct module_search *search,
 
528
                                      struct module_overrides *overrides);
 
529
 
 
530
static int is_higher_priority(const char *newpath, const char *oldpath,
 
531
                              struct module_search *search,
 
532
                              struct module_overrides *overrides)
 
533
{
 
534
        struct module_search *tmp;
 
535
        struct module_overrides *ovtmp;
 
536
        int i = 0;
 
537
        int prio_builtin = -1;
 
538
        int prio_new = -1;
 
539
        int prio_old = -1;
 
540
 
 
541
/* The names already match, now we check for overrides and directory search
 
542
 * order
 
543
 */
 
544
        for (ovtmp = overrides; ovtmp != NULL; ovtmp = ovtmp->next) {
 
545
                if (streq(ovtmp->modfile, newpath))
 
546
                        return 1;
 
547
                if (streq(ovtmp->modfile, oldpath))
 
548
                        return 0;
 
549
        }
 
550
        for (i = 0, tmp = search; tmp != NULL; tmp = tmp->next, i++) {
 
551
                if (streq(tmp->search_path, MODULE_BUILTIN_KEY))
 
552
                        prio_builtin = i;
 
553
                else if (strncmp(tmp->search_path, newpath, tmp->len) == 0)
 
554
                        prio_new = i;
 
555
                else if (strncmp(tmp->search_path, oldpath, tmp->len) == 0)
 
556
                        prio_old = i;
 
557
        }
 
558
        if (prio_new < 0)
 
559
                prio_new = prio_builtin;
 
560
        if (prio_old < 0)
 
561
                prio_old = prio_builtin;
 
562
 
 
563
        return prio_new > prio_old;
 
564
}
 
565
 
 
566
 
 
567
static struct module *do_module(const char *dirname,
 
568
                                       const char *filename,
 
569
                                       struct module *list,
 
570
                                       struct module_search *search,
 
571
                                       struct module_overrides *overrides)
 
572
{
 
573
        struct module *new, **i;
 
574
 
 
575
        new = grab_module(dirname, filename);
 
576
        if (!new)
 
577
                return list;
 
578
 
 
579
        /* Check if module is already in the list. */
 
580
        for (i = &list; *i; i = &(*i)->next) {
 
581
 
 
582
                if (streq((*i)->basename, filename)) {
 
583
                        char newpath[strlen(dirname) + strlen("/")
 
584
                                      + strlen(filename) + 1];
 
585
 
 
586
                        sprintf(newpath, "%s/%s", dirname, filename);
 
587
 
 
588
                        if (is_higher_priority(newpath, (*i)->pathname,search,
 
589
                                               overrides)) {
 
590
                                del_module(i, *i);
 
591
                                
 
592
                                new->next = *i;
 
593
                                *i = new;
 
594
                        } else
 
595
                                del_module(NULL, new);
 
596
 
 
597
                        return list;
 
598
                }
 
599
        }
 
600
 
 
601
        /* Not in the list already. Just prepend. */
 
602
        new->next = list;
 
603
        return new;
 
604
}
 
605
 
 
606
static struct module *grab_dir(const char *dirname,
 
607
                               DIR *dir,
 
608
                               struct module *next,
 
609
                               do_module_t do_mod,
 
610
                               struct module_search *search,
 
611
                               struct module_overrides *overrides)
 
612
{
 
613
        struct dirent *dirent;
 
614
 
 
615
        while ((dirent = readdir(dir)) != NULL) {
 
616
                if (smells_like_module(dirent->d_name))
 
617
                        next = do_mod(dirname, dirent->d_name, next,
 
618
                                      search, overrides);
 
619
                else if (!streq(dirent->d_name, ".")
 
620
                         && !streq(dirent->d_name, "..")
 
621
                         && !streq(dirent->d_name, "source")
 
622
                         && !streq(dirent->d_name, "build")) {
 
623
 
 
624
                        DIR *sub;
 
625
                        char subdir[strlen(dirname) + 1
 
626
                                   + strlen(dirent->d_name) + 1];
 
627
                        sprintf(subdir, "%s/%s", dirname, dirent->d_name);
 
628
                        sub = opendir(subdir);
 
629
                        if (sub) {
 
630
                                next = grab_dir(subdir, sub, next, do_mod,
 
631
                                                search, overrides);
 
632
                                closedir(sub);
 
633
                        }
 
634
                }
 
635
        }
 
636
        return next;
 
637
}
 
638
 
 
639
static struct module *grab_basedir(const char *dirname,
 
640
                                   struct module_search *search,
 
641
                                   struct module_overrides *overrides)
 
642
{
 
643
        DIR *dir;
 
644
        struct module *list;
 
645
 
 
646
        dir = opendir(dirname);
 
647
        if (!dir) {
 
648
                warn("Couldn't open directory %s: %s\n",
 
649
                     dirname, strerror(errno));
 
650
                return NULL;
 
651
        }
 
652
        list = grab_dir(dirname, dir, NULL, do_module, search, overrides);
 
653
        closedir(dir);
 
654
 
 
655
        return list;
 
656
}
 
657
 
 
658
static struct module *sort_modules(const char *dirname, struct module *list)
 
659
{
 
660
        struct module *tlist = NULL, **tpos = &tlist;
 
661
        FILE *modorder;
 
662
        int dir_len = strlen(dirname) + 1;
 
663
        char file_name[dir_len + strlen("modules.order") + 1];
 
664
        char line[10240];
 
665
        unsigned int linenum = 0;
 
666
 
 
667
        sprintf(file_name, "%s/%s", dirname, "modules.order");
 
668
 
 
669
        modorder = fopen(file_name, "r");
 
670
        if (!modorder) {
 
671
                /* Older kernels don't generate modules.order.  Just
 
672
                   return if the file doesn't exist. */
 
673
                if (errno == ENOENT)
 
674
                        return list;
 
675
                fatal("Could not open '%s': %s\n", file_name, strerror(errno));
 
676
        }
 
677
 
 
678
        sprintf(line, "%s/", dirname);
 
679
 
 
680
        /* move modules listed in modorder file to tlist in order */
 
681
        while (fgets(line, sizeof(line), modorder)) {
 
682
                struct module **pos, *mod;
 
683
                int len = strlen(line);
 
684
 
 
685
                linenum++;
 
686
                if (line[len - 1] == '\n')
 
687
                        line[len - 1] = '\0';
 
688
 
 
689
                for (pos = &list; (mod = *pos); pos = &(*pos)->next) {
 
690
                        if (streq(line, mod->pathname + dir_len)) {
 
691
                                mod->order = linenum;
 
692
                                *pos = mod->next;
 
693
                                mod->next = NULL;
 
694
                                *tpos = mod;
 
695
                                tpos = &mod->next;
 
696
                                break;
 
697
                        }
 
698
                }
 
699
        }
 
700
 
 
701
        /* append the rest */
 
702
        *tpos = list;
 
703
 
 
704
        fclose(modorder);
 
705
 
 
706
        return tlist;
 
707
}
 
708
 
 
709
/* Calculate the dependencies for this module */
 
710
static void calculate_deps(struct module *module)
 
711
{
 
712
        unsigned int i;
 
713
        struct string_table *symnames;
 
714
        struct string_table *symtypes;
 
715
        uint64_t *symvers = NULL;
 
716
        struct elf_file *file;
 
717
 
 
718
        module->num_deps = 0;
 
719
        module->deps = NULL;
 
720
        file = module->file;
 
721
 
 
722
        symnames = file->ops->load_dep_syms(file, &symtypes,
 
723
                        check_symvers ? &symvers : NULL);
 
724
        if (!symnames || !symtypes)
 
725
                return;
 
726
 
 
727
        for (i = 0; i < symnames->cnt; i++) {
 
728
                const char *name;
 
729
                uint64_t ver;
 
730
                struct module *owner;
 
731
                int weak;
 
732
 
 
733
                name = symnames->str[i];
 
734
                ver = symvers ? symvers[i] : 0;
 
735
                weak = (*(symtypes->str[i]) == 'W');
 
736
                owner = find_symbol(name, ver, module->pathname, weak);
 
737
                if (owner) {
 
738
                        info("%s needs \"%s\": %s\n",
 
739
                               module->pathname, name,
 
740
                               owner->pathname);
 
741
                        add_dep(module, owner);
 
742
                }
 
743
        }
 
744
 
 
745
        free(symnames);
 
746
        free(symtypes);
 
747
        free(symvers);
 
748
}
 
749
 
 
750
static struct module *parse_modules(struct module *list)
 
751
{
 
752
        struct module *i;
 
753
        struct elf_file *file;
 
754
        struct string_table *syms;
 
755
        int j;
 
756
 
 
757
        for (i = list; i; i = i->next) {
 
758
                uint64_t *symvers = NULL;
 
759
                file = i->file;
 
760
                syms = file->ops->load_symbols(file,
 
761
                                check_symvers ? &symvers : NULL);
 
762
                if (syms) {
 
763
                        for (j = 0; j < syms->cnt; j++)
 
764
                                add_symbol(skip_symprefix(syms->str[j]),
 
765
                                        symvers ? symvers[j] : 0, i);
 
766
                        strtbl_free(syms);
 
767
                }
 
768
                free(symvers);
 
769
                file->ops->fetch_tables(file, &i->tables);
 
770
        }
 
771
        
 
772
        for (i = list; i; i = i->next)
 
773
                calculate_deps(i);
 
774
        
 
775
        /* Strip out modules with dependency loops. */
 
776
 again:
 
777
        for (i = list; i; i = i->next) {
 
778
                if (has_dep_loop(i, NULL)) {
 
779
                        warn("Module %s ignored, due to loop\n",
 
780
                             i->pathname + skipchars);
 
781
                        del_module(&list, i);
 
782
                        goto again;
 
783
                }
 
784
        }
 
785
        
 
786
        return list;
 
787
}
 
788
 
 
789
/* Simply dump hash table. */
 
790
static int output_symbols(struct module *unused, FILE *out, char *dirname)
 
791
{
 
792
        unsigned int i;
 
793
 
 
794
        fprintf(out, "# Aliases for symbols, used by symbol_request().\n");
 
795
        for (i = 0; i < SYMBOL_HASH_SIZE; i++) {
 
796
                struct symbol *s;
 
797
 
 
798
                for (s = symbolhash[i]; s; s = s->next) {
 
799
                        if (s->owner) {
 
800
                                char modname[strlen(s->owner->pathname)+1];
 
801
                                filename2modname(modname, s->owner->pathname);
 
802
                                fprintf(out, "alias symbol:%s %s\n",
 
803
                                        s->name, modname);
 
804
                        }
 
805
                }
 
806
        }
 
807
        return 1;
 
808
}
 
809
 
 
810
static int output_symbols_bin(struct module *unused, FILE *out, char *dirname)
 
811
{
 
812
        struct index_node *index;
 
813
        unsigned int i;
 
814
        char *alias;
 
815
        int duplicate;
 
816
 
 
817
        index = index_create();
 
818
        
 
819
        for (i = 0; i < SYMBOL_HASH_SIZE; i++) {
 
820
                struct symbol *s;
 
821
 
 
822
                for (s = symbolhash[i]; s; s = s->next) {
 
823
                        if (s->owner) {
 
824
                                char modname[strlen(s->owner->pathname)+1];
 
825
                                filename2modname(modname, s->owner->pathname);
 
826
                                nofail_asprintf(&alias, "symbol:%s", s->name);
 
827
                                duplicate = index_insert(index, alias, modname,
 
828
                                                         s->owner->order);
 
829
                                if (duplicate && warn_dups)
 
830
                                        warn("duplicate module syms:\n%s %s\n",
 
831
                                                alias, modname);
 
832
                                free(alias);
 
833
                        }
 
834
                }
 
835
        }
 
836
        
 
837
        index_write(index, out);
 
838
        index_destroy(index);
 
839
 
 
840
        return 1;
 
841
}
 
842
 
 
843
static int output_builtin_bin(struct module *unused, FILE *out, char *dirname)
 
844
{
 
845
        struct index_node *index;
 
846
        char *textfile, *line;
 
847
        unsigned int linenum;
 
848
        FILE *f;
 
849
 
 
850
        nofail_asprintf(&textfile, "%s/modules.builtin", dirname);
 
851
        if (!(f = fopen(textfile, "r"))) {
 
852
                if (errno != ENOENT)
 
853
                        fatal("Could not open '%s': %s\n",
 
854
                                        textfile, strerror(errno));
 
855
                free(textfile);
 
856
                return 0;
 
857
        }
 
858
        free(textfile);
 
859
        index = index_create();
 
860
 
 
861
        while ((line = getline_wrapped(f, &linenum)) != NULL) {
 
862
                char *module = line;
 
863
 
 
864
                if (!*line || *line == '#') {
 
865
                        free(line);
 
866
                        continue;
 
867
                }
 
868
                filename2modname(module, module);
 
869
                index_insert(index, module, "", 0);
 
870
                free(line);
 
871
        }
 
872
        fclose(f);
 
873
        index_write(index, out);
 
874
        index_destroy(index);
 
875
 
 
876
        return 1;
 
877
}
 
878
 
 
879
static int output_aliases(struct module *modules, FILE *out, char *dirname)
 
880
{
 
881
        struct module *i;
 
882
        struct elf_file *file;
 
883
        struct string_table *tbl;
 
884
        int j;
 
885
 
 
886
        fprintf(out, "# Aliases extracted from modules themselves.\n");
 
887
        for (i = modules; i; i = i->next) {
 
888
                char modname[strlen(i->pathname)+1];
 
889
 
 
890
                file = i->file;
 
891
                filename2modname(modname, i->pathname);
 
892
 
 
893
                /* Grab from old-style .modalias section. */
 
894
                tbl = file->ops->load_strings(file, ".modalias", NULL);
 
895
                for (j = 0; tbl && j < tbl->cnt; j++)
 
896
                        fprintf(out, "alias %s %s\n", tbl->str[j], modname);
 
897
                strtbl_free(tbl);
 
898
 
 
899
                /* Grab from new-style .modinfo section. */
 
900
                tbl = file->ops->load_strings(file, ".modinfo", NULL);
 
901
                for (j = 0; tbl && j < tbl->cnt; j++) {
 
902
                        const char *p = tbl->str[j];
 
903
                        if (strstarts(p, "alias="))
 
904
                                fprintf(out, "alias %s %s\n",
 
905
                                        p + strlen("alias="), modname);
 
906
                }
 
907
                strtbl_free(tbl);
 
908
        }
 
909
        return 1;
 
910
}
 
911
 
 
912
static int output_aliases_bin(struct module *modules, FILE *out, char *dirname)
 
913
{
 
914
        struct module *i;
 
915
        struct elf_file *file;
 
916
        struct string_table *tbl;
 
917
        int j;
 
918
        char *alias;
 
919
        struct index_node *index;
 
920
        int duplicate;
 
921
 
 
922
        index = index_create();
 
923
        
 
924
        for (i = modules; i; i = i->next) {
 
925
                char modname[strlen(i->pathname)+1];
 
926
 
 
927
                file = i->file;
 
928
                filename2modname(modname, i->pathname);
 
929
 
 
930
                /* Grab from old-style .modalias section. */
 
931
                tbl = file->ops->load_strings(file, ".modalias", NULL);
 
932
                for (j = 0; tbl && j < tbl->cnt; j++) {
 
933
                        alias = NOFAIL(strdup(tbl->str[j]));
 
934
                        underscores(alias);
 
935
                        duplicate = index_insert(index, alias, modname, i->order);
 
936
                        if (duplicate && warn_dups)
 
937
                                warn("duplicate module alias:\n%s %s\n",
 
938
                                        alias, modname);
 
939
                        free(alias);
 
940
                }
 
941
                strtbl_free(tbl);
 
942
 
 
943
                /* Grab from new-style .modinfo section. */
 
944
                tbl = file->ops->load_strings(file, ".modinfo", NULL);
 
945
                for (j = 0; tbl && j < tbl->cnt; j++) {
 
946
                        const char *p = tbl->str[j];
 
947
                        if (strstarts(p, "alias=")) {
 
948
                                alias = NOFAIL(strdup(p + strlen("alias=")));
 
949
                                underscores(alias);
 
950
                                duplicate = index_insert(index, alias, modname, i->order);
 
951
                                if (duplicate && warn_dups)
 
952
                                        warn("duplicate module alias:\n%s %s\n",
 
953
                                                alias, modname);
 
954
                                free(alias);
 
955
                        }
 
956
                }
 
957
                strtbl_free(tbl);
 
958
        }
 
959
        
 
960
        index_write(index, out);
 
961
        index_destroy(index);
 
962
 
 
963
        return 1;
 
964
}
 
965
 
 
966
static int output_softdeps(struct module *modules, FILE *out, char *dirname)
 
967
{
 
968
        struct module *i;
 
969
        struct elf_file *file;
 
970
        struct string_table *tbl;
 
971
        int j;
 
972
 
 
973
        fprintf(out, "# Soft dependencies extracted from modules themselves.\n");
 
974
        fprintf(out, "# Copy, with a .conf extension, to /etc/modprobe.d to use "
 
975
                "it with modprobe.\n");
 
976
        for (i = modules; i; i = i->next) {
 
977
                char modname[strlen(i->pathname)+1];
 
978
 
 
979
                file = i->file;
 
980
                filename2modname(modname, i->pathname);
 
981
 
 
982
                /* Grab from new-style .modinfo section. */
 
983
                tbl = file->ops->load_strings(file, ".modinfo", NULL);
 
984
                for (j = 0; tbl && j < tbl->cnt; j++) {
 
985
                        const char *p = tbl->str[j];
 
986
                        if (strstarts(p, "softdep="))
 
987
                                fprintf(out, "softdep %s %s\n",
 
988
                                        modname, p + strlen("softdep="));
 
989
                }
 
990
                strtbl_free(tbl);
 
991
        }
 
992
        return 1;
 
993
}
 
994
 
 
995
static int output_devname(struct module *modules, FILE *out, char *dirname)
 
996
{
 
997
        struct module *m;
 
998
 
 
999
        fprintf(out, "# Device nodes to trigger on-demand module loading.\n");
 
1000
        for (m = modules; m != NULL; m = m->next) {
 
1001
                struct string_table *tbl;
 
1002
                int i;
 
1003
                char type = '\0';
 
1004
                const char *devname = NULL;
 
1005
 
 
1006
                tbl = m->file->ops->load_strings(m->file, ".modinfo", NULL);
 
1007
                for (i = 0; tbl && i < tbl->cnt; i++) {
 
1008
                        const char *p = tbl->str[i];
 
1009
                        unsigned int maj, min;
 
1010
 
 
1011
                        if (sscanf(p, "alias=char-major-%u-%u", &maj, &min) == 2)
 
1012
                                type = 'c';
 
1013
                        else if (sscanf(p, "alias=block-major-%u-%u", &maj, &min) == 2)
 
1014
                                type = 'b';
 
1015
                        else if (strstarts(p, "alias=devname:"))
 
1016
                                devname = &p[strlen("alias=devname:")];
 
1017
 
 
1018
                        if (type && devname) {
 
1019
                                char modname[strlen(m->pathname)+1];
 
1020
 
 
1021
                                filename2modname(modname, m->pathname);
 
1022
                                fprintf(out, "%s %s %c%u:%u\n",
 
1023
                                        modname, devname, type, maj, min);
 
1024
                                break;
 
1025
                        }
 
1026
                }
 
1027
                strtbl_free(tbl);
 
1028
        }
 
1029
        return 1;
 
1030
}
 
1031
 
 
1032
struct depfile {
 
1033
        const char *name;
 
1034
        int (*func)(struct module *, FILE *, char *dirname);
 
1035
        int map_file;
 
1036
};
 
1037
 
 
1038
static const struct depfile depfiles[] = {
 
1039
        { "modules.dep", output_deps, 0 }, /* This is what we check for '-A'. */
 
1040
        { "modules.dep.bin", output_deps_bin, 0 },
 
1041
        { "modules.pcimap", output_pci_table, 1 },
 
1042
        { "modules.usbmap", output_usb_table, 1 },
 
1043
        { "modules.ccwmap", output_ccw_table, 1 },
 
1044
        { "modules.ieee1394map", output_ieee1394_table, 1 },
 
1045
        { "modules.isapnpmap", output_isapnp_table, 1 },
 
1046
        { "modules.inputmap", output_input_table, 1 },
 
1047
        { "modules.ofmap", output_of_table, 1 },
 
1048
        { "modules.seriomap", output_serio_table, 1 },
 
1049
        { "modules.alias", output_aliases, 0 },
 
1050
        { "modules.alias.bin", output_aliases_bin, 0 },
 
1051
        { "modules.softdep", output_softdeps, 0 },
 
1052
        { "modules.symbols", output_symbols, 0 },
 
1053
        { "modules.symbols.bin", output_symbols_bin, 0 },
 
1054
        { "modules.builtin.bin", output_builtin_bin, 0 },
 
1055
        { "modules.devname", output_devname, 0 },
 
1056
};
 
1057
 
 
1058
/* If we can't figure it out, it's safe to say "true". */
 
1059
static int any_modules_newer(const char *dirname, time_t mtime)
 
1060
{
 
1061
        DIR *dir;
 
1062
        struct dirent *dirent;
 
1063
 
 
1064
        dir = opendir(dirname);
 
1065
        if (!dir)
 
1066
                return 1;
 
1067
 
 
1068
        while ((dirent = readdir(dir)) != NULL) {
 
1069
                struct stat st;
 
1070
                char file[strlen(dirname) + 1 + strlen(dirent->d_name) + 1];
 
1071
 
 
1072
                if (streq(dirent->d_name, ".") || streq(dirent->d_name, ".."))
 
1073
                        continue;
 
1074
 
 
1075
                sprintf(file, "%s/%s", dirname, dirent->d_name);
 
1076
                if (lstat(file, &st) != 0)
 
1077
                        goto ret_true;
 
1078
 
 
1079
                if (smells_like_module(dirent->d_name)) {
 
1080
                        if (st.st_mtime > mtime)
 
1081
                                goto ret_true;
 
1082
                } else if (S_ISDIR(st.st_mode)) {
 
1083
                        if (any_modules_newer(file, mtime))
 
1084
                                goto ret_true;
 
1085
                }
 
1086
        }
 
1087
        closedir(dir);
 
1088
        return 0;
 
1089
 
 
1090
ret_true:
 
1091
        closedir(dir);
 
1092
        return 1;
 
1093
}
 
1094
 
 
1095
static int depfile_out_of_date(const char *dirname)
 
1096
{
 
1097
        struct stat st;
 
1098
        char depfile[strlen(dirname) + 1 + strlen(depfiles[0].name) + 1];
 
1099
 
 
1100
        sprintf(depfile, "%s/%s", dirname, depfiles[0].name);
 
1101
 
 
1102
        if (stat(depfile, &st) != 0)
 
1103
                return 1;
 
1104
 
 
1105
        return any_modules_newer(dirname, st.st_mtime);
 
1106
}
 
1107
 
 
1108
static char *strsep_skipspace(char **string, char *delim)
 
1109
{
 
1110
        if (!*string)
 
1111
                return NULL;
 
1112
        *string += strspn(*string, delim);
 
1113
        return strsep(string, delim);
 
1114
}
 
1115
 
 
1116
static struct module_search *add_search(const char *search_path,
 
1117
                                        size_t len,
 
1118
                                        struct module_search *search)
 
1119
{
 
1120
 
 
1121
        struct module_search *new;
 
1122
        
 
1123
        new = NOFAIL(malloc(sizeof(*new)));
 
1124
        new->search_path = NOFAIL(strdup(search_path));
 
1125
        new->len = len;
 
1126
        new->next = search;
 
1127
 
 
1128
        return new;
 
1129
        
 
1130
}
 
1131
 
 
1132
static struct module_overrides *add_override(const char *modfile,
 
1133
                                             struct module_overrides *overrides)
 
1134
{
 
1135
 
 
1136
        struct module_overrides *new;
 
1137
        
 
1138
        new = NOFAIL(malloc(sizeof(*new)));
 
1139
        new->modfile = NOFAIL(strdup(modfile));
 
1140
        new->next = overrides;
 
1141
 
 
1142
        return new;
 
1143
        
 
1144
}
 
1145
 
 
1146
static int parse_config_scan(const char *filename,
 
1147
                             const char *basedir,
 
1148
                             const char *kernelversion,
 
1149
                             struct module_search **search,
 
1150
                             struct module_overrides **overrides);
 
1151
 
 
1152
static int parse_config_file(const char *filename,
 
1153
                             const char *basedir,
 
1154
                             const char *kernelversion,
 
1155
                             struct module_search **search,
 
1156
                             struct module_overrides **overrides)
 
1157
{
 
1158
        char *line;
 
1159
        unsigned int linenum = 0;
 
1160
        FILE *cfile;
 
1161
 
 
1162
        cfile = fopen(filename, "r");
 
1163
        if (!cfile) {
 
1164
                if (errno != ENOENT)
 
1165
                        fatal("could not open '%s', reason: %s\n", filename,
 
1166
                              strerror(errno));
 
1167
                return 0;
 
1168
        }
 
1169
 
 
1170
        while ((line = getline_wrapped(cfile, &linenum)) != NULL) {
 
1171
                char *ptr = line;
 
1172
                char *cmd, *modname;
 
1173
 
 
1174
                cmd = strsep_skipspace(&ptr, "\t ");
 
1175
 
 
1176
                if (cmd == NULL || cmd[0] == '#' || cmd[0] == '\0') {
 
1177
                        free(line);
 
1178
                        continue;
 
1179
                }
 
1180
 
 
1181
                if (streq(cmd, "search")) {
 
1182
                        char *search_path;
 
1183
                        
 
1184
                        while ((search_path = strsep_skipspace(&ptr, "\t "))) {
 
1185
                                char *dirname;
 
1186
                                size_t len;
 
1187
 
 
1188
                                if (strcmp(search_path,
 
1189
                                                MODULE_BUILTIN_KEY) == 0) {
 
1190
                                        *search = add_search(MODULE_BUILTIN_KEY,
 
1191
                                                             0, *search);
 
1192
                                        continue;
 
1193
                                }
 
1194
                                nofail_asprintf(&dirname, "%s%s%s/%s", basedir,
 
1195
                                        MODULE_DIR, kernelversion, search_path);
 
1196
                                len = strlen(dirname);
 
1197
                                *search = add_search(dirname, len, *search);
 
1198
                                free(dirname);
 
1199
                        }
 
1200
                } else if (streq(cmd, "override")) {
 
1201
                        char *pathname = NULL, *version, *subdir;
 
1202
                        modname = strsep_skipspace(&ptr, "\t ");
 
1203
                        version = strsep_skipspace(&ptr, "\t ");
 
1204
                        subdir = strsep_skipspace(&ptr, "\t ");
 
1205
 
 
1206
                        if (!regex_match(kernelversion, (const char *)version))
 
1207
                                continue;
 
1208
 
 
1209
                        nofail_asprintf(&pathname, "%s%s%s/%s/%s.ko", basedir,
 
1210
                                MODULE_DIR, kernelversion, subdir, modname);
 
1211
 
 
1212
                        *overrides = add_override(pathname, *overrides);
 
1213
                        free(pathname);
 
1214
                } else if (streq(cmd, "include")) {
 
1215
                        char *newfilename;
 
1216
 
 
1217
                        newfilename = strsep_skipspace(&ptr, "\t ");
 
1218
                        if (!newfilename) {
 
1219
                                grammar(cmd, filename, linenum);
 
1220
                        } else {
 
1221
                                warn("\"include %s\" is deprecated, "
 
1222
                                     "please use /etc/depmod.d\n", newfilename);
 
1223
                                if (strstarts(newfilename, "/etc/depmod.d")) {
 
1224
                                        warn("\"include /etc/depmod.d\" is "
 
1225
                                             "the default, ignored\n");
 
1226
                                } else {
 
1227
                                        if (!parse_config_scan(newfilename, basedir,
 
1228
                                                               kernelversion,
 
1229
                                                               search, overrides))
 
1230
                                        warn("Failed to open included"
 
1231
                                             " config file %s: %s\n",
 
1232
                                             newfilename, strerror(errno));
 
1233
                                }
 
1234
                        }
 
1235
                } else if (streq(cmd, "make_map_files")) {
 
1236
                        char *option;
 
1237
 
 
1238
                        option = strsep_skipspace(&ptr, "\t ");
 
1239
                        if (!option)
 
1240
                                grammar(cmd, filename, linenum);
 
1241
                        else {
 
1242
                                if (streq(option, "yes"))
 
1243
                                        make_map_files = 1;
 
1244
                                else if (streq(option, "no"))
 
1245
                                        make_map_files = 0;
 
1246
                                else
 
1247
                                        grammar(cmd, filename, linenum);
 
1248
                        }
 
1249
                } else
 
1250
                        grammar(cmd, filename, linenum);
 
1251
 
 
1252
                free(line);
 
1253
        }
 
1254
        fclose(cfile);
 
1255
        return 1;
 
1256
}
 
1257
 
 
1258
static int parse_config_scan(const char *filename,
 
1259
                             const char *basedir,
 
1260
                             const char *kernelversion,
 
1261
                             struct module_search **search,
 
1262
                             struct module_overrides **overrides)
 
1263
{
 
1264
        DIR *dir;
 
1265
        int ret = 0;
 
1266
 
 
1267
        dir = opendir(filename);
 
1268
        if (dir) {
 
1269
                struct file_entry {
 
1270
                        struct list_head node;
 
1271
                        char name[];
 
1272
                };
 
1273
                LIST_HEAD(files_list);
 
1274
                struct file_entry *fe, *fe_tmp;
 
1275
                struct dirent *i;
 
1276
 
 
1277
                /* sort files from directory into list */
 
1278
                while ((i = readdir(dir)) != NULL) {
 
1279
                        size_t len;
 
1280
 
 
1281
                        if (i->d_name[0] == '.')
 
1282
                                continue;
 
1283
                        if (!config_filter(i->d_name))
 
1284
                                continue;
 
1285
 
 
1286
                        len = strlen(i->d_name);
 
1287
                        if (len < 6 || strcmp(&i->d_name[len-5], ".conf") != 0)
 
1288
                                warn("All config files need .conf: %s/%s, "
 
1289
                                     "it will be ignored in a future release.\n",
 
1290
                                     filename, i->d_name);
 
1291
                        fe = malloc(sizeof(struct file_entry) + len + 1);
 
1292
                        if (fe == NULL)
 
1293
                                continue;
 
1294
                        strcpy(fe->name, i->d_name);
 
1295
                        list_for_each_entry(fe_tmp, &files_list, node)
 
1296
                                if (strcmp(fe_tmp->name, fe->name) >= 0)
 
1297
                                        break;
 
1298
                        list_add_tail(&fe->node, &fe_tmp->node);
 
1299
                }
 
1300
                closedir(dir);
 
1301
 
 
1302
                /* parse list of files */
 
1303
                list_for_each_entry_safe(fe, fe_tmp, &files_list, node) {
 
1304
                        char *cfgfile;
 
1305
 
 
1306
                        nofail_asprintf(&cfgfile, "%s/%s", filename, fe->name);
 
1307
                        if (!parse_config_file(cfgfile, basedir, kernelversion,
 
1308
                                               search, overrides))
 
1309
                                warn("Failed to open config file "
 
1310
                                     "%s: %s\n", fe->name, strerror(errno));
 
1311
                        free(cfgfile);
 
1312
                        list_del(&fe->node);
 
1313
                        free(fe);
 
1314
                }
 
1315
 
 
1316
                ret = 1;
 
1317
        } else {
 
1318
                if (parse_config_file(filename, basedir, kernelversion, search,
 
1319
                                      overrides))
 
1320
                        ret = 1;
 
1321
        }
 
1322
 
 
1323
        return ret;
 
1324
}
 
1325
 
 
1326
static void parse_toplevel_config(const char *filename,
 
1327
                                  const char *basedir,
 
1328
                                  const char *kernelversion,
 
1329
                                  struct module_search **search,
 
1330
                                  struct module_overrides **overrides)
 
1331
{
 
1332
        if (filename) {
 
1333
                if (!parse_config_scan(filename, basedir, kernelversion, search,
 
1334
                                 overrides))
 
1335
                        fatal("Failed to open config file %s: %s\n",
 
1336
                              filename, strerror(errno));
 
1337
                return;
 
1338
        }
 
1339
 
 
1340
        /* deprecated config file */
 
1341
        if (parse_config_file("/etc/depmod.conf", basedir, kernelversion,
 
1342
                              search, overrides) > 0)
 
1343
                warn("Deprecated config file /etc/depmod.conf, "
 
1344
                      "all config files belong into /etc/depmod.d/.\n");
 
1345
 
 
1346
        /* default config */
 
1347
        parse_config_scan("/etc/depmod.d", basedir, kernelversion,
 
1348
                          search, overrides);
 
1349
}
 
1350
 
 
1351
/* Local to main, but not freed on exit.  Keep valgrind quiet. */
 
1352
static struct module *list = NULL;
 
1353
static struct module_search *search = NULL;
 
1354
static struct module_overrides *overrides = NULL;
 
1355
 
 
1356
int main(int argc, char *argv[])
 
1357
{
 
1358
        int opt, all = 0, maybe_all = 0, doing_stdout = 0;
 
1359
        char *basedir = "", *dirname, *version;
 
1360
        char *system_map = NULL, *module_symvers = NULL;
 
1361
        int i;
 
1362
        const char *config = NULL;
 
1363
 
 
1364
        if (native_endianness() == 0)
 
1365
                abort();
 
1366
 
 
1367
        while ((opt = getopt_long(argc, argv, "aAb:C:E:F:euqrvnP:hVwm", options, NULL))
 
1368
               != -1) {
 
1369
                switch (opt) {
 
1370
                case 'a':
 
1371
                        all = 1;
 
1372
                        break;
 
1373
                case 'A':
 
1374
                        maybe_all = 1;
 
1375
                        break;
 
1376
                case 'b':
 
1377
                        basedir = optarg;
 
1378
                        skipchars = strlen(basedir);
 
1379
                        break;
 
1380
                case 'C':
 
1381
                        config = optarg;
 
1382
                        break;
 
1383
                case 'E':
 
1384
                        module_symvers = optarg;
 
1385
                        check_symvers = 1;
 
1386
                        break;
 
1387
                case 'F':
 
1388
                        system_map = optarg;
 
1389
                        break;
 
1390
                case 'e':
 
1391
                        print_unknown = 1;
 
1392
                        break;
 
1393
                case 'u':
 
1394
                case 'q':
 
1395
                case 'r':
 
1396
                        break;
 
1397
                case 'v':
 
1398
                        verbose = 1;
 
1399
                        break;
 
1400
                case 'n':
 
1401
                        doing_stdout = 1;
 
1402
                        break;
 
1403
                case 'P':
 
1404
                        if (optarg[1] != '\0')
 
1405
                                fatal("-P only takes a single char\n");
 
1406
                        sym_prefix = optarg[0];
 
1407
                        break;
 
1408
                case 'h':
 
1409
                        print_usage(argv[0]);
 
1410
                        exit(0);
 
1411
                        break;
 
1412
                case 'V':
 
1413
                        printf("%s %s\n", PACKAGE, VERSION);
 
1414
                        exit(0);
 
1415
                case 'w':
 
1416
                        warn_dups = 1;
 
1417
                        break;
 
1418
                case 'm':
 
1419
                        force_map_files = 1;
 
1420
                        break;
 
1421
                default:
 
1422
                        print_usage(argv[0]);
 
1423
                        exit(1);
 
1424
                }
 
1425
        }
 
1426
 
 
1427
        if (module_symvers)
 
1428
                load_module_symvers(module_symvers);
 
1429
        else if (system_map)
 
1430
                load_system_map(system_map);
 
1431
        else if (print_unknown) {
 
1432
                warn("-e needs -E or -F\n");
 
1433
                print_unknown = 0;
 
1434
        }
 
1435
 
 
1436
        /* They can specify the version naked on the command line */
 
1437
        if (optind < argc && is_version_number(argv[optind])) {
 
1438
                version = NOFAIL(strdup(argv[optind]));
 
1439
                optind++;
 
1440
        } else {
 
1441
                struct utsname buf;
 
1442
                uname(&buf);
 
1443
                version = NOFAIL(strdup(buf.release));
 
1444
        }
 
1445
 
 
1446
        /* Check for old version. */
 
1447
        if (old_module_version(version)) {
 
1448
                fprintf(stderr, "Kernel version %s requires old depmod\n",
 
1449
                        version);
 
1450
                exit(2);
 
1451
        }
 
1452
 
 
1453
        /* Depmod -a by default if no names. */
 
1454
        if (optind == argc)
 
1455
                all = 1;
 
1456
 
 
1457
        nofail_asprintf(&dirname, "%s%s%s", basedir, MODULE_DIR, version);
 
1458
 
 
1459
        if (maybe_all) {
 
1460
                if (!doing_stdout && !depfile_out_of_date(dirname))
 
1461
                        exit(0);
 
1462
                all = 1;
 
1463
        }
 
1464
 
 
1465
        parse_toplevel_config(config, basedir, version, &search, &overrides);
 
1466
 
 
1467
        /* For backward compatibility add "updates" to the head of the search
 
1468
         * list here. But only if there was no "search" option specified.
 
1469
         */
 
1470
        if (!search) {
 
1471
                char *dirname;
 
1472
                size_t len;
 
1473
 
 
1474
                nofail_asprintf(&dirname, "%s%s%s/updates", basedir,
 
1475
                                MODULE_DIR, version);
 
1476
                len = strlen(dirname);
 
1477
                search = add_search(dirname, len, search);
 
1478
        }
 
1479
        if (!all) {
 
1480
                /* Do command line args. */
 
1481
                for (opt = optind; opt < argc; opt++) {
 
1482
                        struct module *new;
 
1483
 
 
1484
                        if (argv[opt][0] != '/')
 
1485
                                fatal("modules must be specified using absolute paths.\n"
 
1486
                                        "\"%s\" is a relative path\n", argv[opt]);
 
1487
 
 
1488
                        new = grab_module(NULL, argv[opt]);
 
1489
                        if (!new) {
 
1490
                                /* cmd-line specified modules must exist */
 
1491
                                fatal("grab_module() failed for module %s\n", argv[opt]);
 
1492
                        }
 
1493
                        new->next = list;
 
1494
                        list = new;
 
1495
                }
 
1496
        } else {
 
1497
                list = grab_basedir(dirname,search,overrides);
 
1498
        }
 
1499
        list = sort_modules(dirname,list);
 
1500
        list = parse_modules(list);
 
1501
 
 
1502
        for (i = 0; i < ARRAY_SIZE(depfiles); i++) {
 
1503
                FILE *out;
 
1504
                int res;
 
1505
                const struct depfile *d = &depfiles[i];
 
1506
                char depname[strlen(dirname) + 1 + strlen(d->name) + 1];
 
1507
                char tmpname[strlen(dirname) + 1 + strlen(d->name) +
 
1508
                                                strlen(".temp") + 1];
 
1509
 
 
1510
                if (d->map_file && !make_map_files && !force_map_files)
 
1511
                        continue;
 
1512
 
 
1513
                sprintf(depname, "%s/%s", dirname, d->name);
 
1514
                sprintf(tmpname, "%s/%s.temp", dirname, d->name);
 
1515
                if (!doing_stdout) {
 
1516
                        out = fopen(tmpname, "w");
 
1517
                        if (!out)
 
1518
                                fatal("Could not open %s for writing: %s\n",
 
1519
                                        tmpname, strerror(errno));
 
1520
                } else {
 
1521
                        out = stdout;
 
1522
                        if (ends_in(depname, ".bin"))
 
1523
                                continue;
 
1524
                }
 
1525
                res = d->func(list, out, dirname);
 
1526
                if (doing_stdout)
 
1527
                        continue;
 
1528
                fclose(out);
 
1529
                if (res) {
 
1530
                        if (rename(tmpname, depname) < 0)
 
1531
                                fatal("Could not rename %s into %s: %s\n",
 
1532
                                        tmpname, depname, strerror(errno));
 
1533
                } else {
 
1534
                        if (unlink(tmpname) < 0)
 
1535
                                warn("Could not delete %s: %s\n",
 
1536
                                        tmpname, strerror(errno));
 
1537
                }
 
1538
        }
 
1539
 
 
1540
        free(dirname);
 
1541
        free(version);
 
1542
        
 
1543
        return 0;
 
1544
}