source: MondoRescue/branches/3.3/mindi-busybox/modutils/depmod.c@ 3865

Last change on this file since 3865 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 6.6 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * depmod - generate modules.dep
4 * Copyright (c) 2008 Bernhard Reutner-Fischer
5 * Copyrihgt (c) 2008 Timo Teras <timo.teras@iki.fi>
6 * Copyright (c) 2008 Vladimir Dronnikov
7 *
8 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
9 */
10
11//applet:IF_DEPMOD(APPLET(depmod, BB_DIR_SBIN, BB_SUID_DROP))
12
13#include "libbb.h"
14#include "modutils.h"
15#include <sys/utsname.h> /* uname() */
16
17/*
18 * Theory of operation:
19 * - iterate over all modules and record their full path
20 * - iterate over all modules looking for "depends=" entries
21 * for each depends, look through our list of full paths and emit if found
22 */
23
24static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARAM,
25 void *data, int depth UNUSED_PARAM)
26{
27 module_db *modules = data;
28 char *image, *ptr;
29 module_entry *e;
30
31 /* Arbitrary. Was sb->st_size, but that breaks .gz etc */
32 size_t len = (64*1024*1024 - 4096);
33
34 if (strrstr(fname, ".ko") == NULL)
35 return TRUE;
36
37 image = xmalloc_open_zipped_read_close(fname, &len);
38
39 e = moddb_get_or_create(modules, bb_get_last_path_component_nostrip(fname));
40 e->name = xstrdup(fname + 2); /* skip "./" */
41
42 for (ptr = image; ptr < image + len - 10; ptr++) {
43 if (is_prefixed_with(ptr, "depends=")) {
44 char *u;
45
46 ptr += 8;
47 for (u = ptr; *u; u++)
48 if (*u == '-')
49 *u = '_';
50 ptr += string_to_llist(ptr, &e->deps, ",");
51 } else if (ENABLE_FEATURE_MODUTILS_ALIAS
52 && is_prefixed_with(ptr, "alias=")
53 ) {
54 llist_add_to(&e->aliases, xstrdup(ptr + 6));
55 ptr += strlen(ptr);
56 } else if (ENABLE_FEATURE_MODUTILS_SYMBOLS
57 && is_prefixed_with(ptr, "__ksymtab_")
58 ) {
59 ptr += 10;
60 if (is_prefixed_with(ptr, "gpl")
61 || strcmp(ptr, "strings") == 0
62 ) {
63 continue;
64 }
65 llist_add_to(&e->symbols, xstrdup(ptr));
66 ptr += strlen(ptr);
67 }
68 }
69 free(image);
70
71 return TRUE;
72}
73
74static void order_dep_list(module_db *modules, module_entry *start, llist_t *add)
75{
76 module_entry *m;
77 llist_t *n;
78
79 for (n = add; n != NULL; n = n->link) {
80 m = moddb_get(modules, n->data);
81 if (m == NULL)
82 continue;
83
84 /* unlink current entry */
85 m->dnext->dprev = m->dprev;
86 m->dprev->dnext = m->dnext;
87
88 /* and add it to tail */
89 m->dnext = start;
90 m->dprev = start->dprev;
91 start->dprev->dnext = m;
92 start->dprev = m;
93
94 /* recurse */
95 order_dep_list(modules, start, m->deps);
96 }
97}
98
99static void xfreopen_write(const char *file, FILE *f)
100{
101 if (freopen(file, "w", f) == NULL)
102 bb_perror_msg_and_die("can't open '%s'", file);
103}
104
105//usage:#if !ENABLE_MODPROBE_SMALL
106//usage:#define depmod_trivial_usage "[-n] [-b BASE] [VERSION] [MODFILES]..."
107//usage:#define depmod_full_usage "\n\n"
108//usage: "Generate modules.dep, alias, and symbols files"
109//usage: "\n"
110//usage: "\n -b BASE Use BASE/lib/modules/VERSION"
111//usage: "\n -n Dry run: print files to stdout"
112//usage:#endif
113
114/* Upstream usage:
115 * [-aAenv] [-C FILE or DIR] [-b BASE] [-F System.map] [VERSION] [MODFILES]...
116 * -a --all
117 * Probe all modules. Default if no MODFILES.
118 * -A --quick
119 * Check modules.dep's mtime against module files' mtimes.
120 * -b --basedir BASE
121 * Use $BASE/lib/modules/VERSION
122 * -C --config FILE or DIR
123 * Path to /etc/depmod.conf or /etc/depmod.d/
124 * -e --errsyms
125 * When combined with the -F option, this reports any symbols
126 * which are not supplied by other modules or kernel.
127 * -F --filesyms System.map
128 * -n --dry-run
129 * Print modules.dep etc to standard output
130 * -v --verbose
131 * Print to stdout all the symbols each module depends on
132 * and the module's file name which provides that symbol.
133 * -r No-op
134 * -u No-op
135 * -q No-op
136 *
137 * So far we only support: [-n] [-b BASE] [VERSION] [MODFILES]...
138 * Accepted but ignored:
139 * -aAe
140 * -F System.map
141 * -C FILE/DIR
142 *
143 * Not accepted: -v
144 */
145enum {
146 //OPT_a = (1 << 0), /* All modules, ignore mods in argv */
147 //OPT_A = (1 << 1), /* Only emit .ko that are newer than modules.dep file */
148 OPT_b = (1 << 2), /* base directory when modules are in staging area */
149 //OPT_e = (1 << 3), /* with -F, print unresolved symbols */
150 //OPT_F = (1 << 4), /* System.map that contains the symbols */
151 OPT_n = (1 << 5), /* dry-run, print to stdout only */
152 OPT_r = (1 << 6), /* Compat dummy. Linux Makefile uses it */
153 OPT_u = (1 << 7), /* -u,--unresolved-error: ignored */
154 OPT_q = (1 << 8), /* -q,--quiet: ignored */
155 OPT_C = (1 << 9), /* -C,--config etc_modules_conf: ignored */
156};
157
158int depmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
159int depmod_main(int argc UNUSED_PARAM, char **argv)
160{
161 module_db modules;
162 module_entry *m, *dep;
163 const char *moddir_base = "/";
164 char *moddir, *version;
165 struct utsname uts;
166 unsigned i;
167 int tmp;
168
169 getopt32(argv, "aAb:eF:nruqC:", &moddir_base, NULL, NULL);
170 argv += optind;
171
172 /* goto modules location */
173 xchdir(moddir_base);
174
175 /* If a version is provided, then that kernel version's module directory
176 * is used, rather than the current kernel version (as returned by
177 * "uname -r"). */
178 if (*argv && sscanf(*argv, "%u.%u.%u", &tmp, &tmp, &tmp) == 3) {
179 version = *argv++;
180 } else {
181 uname(&uts);
182 version = uts.release;
183 }
184 moddir = concat_path_file(&CONFIG_DEFAULT_MODULES_DIR[1], version);
185 xchdir(moddir);
186 if (ENABLE_FEATURE_CLEAN_UP)
187 free(moddir);
188
189 /* Scan modules */
190 memset(&modules, 0, sizeof(modules));
191 if (*argv) {
192 do {
193 parse_module(*argv, /*sb (unused):*/ NULL, &modules, 0);
194 } while (*++argv);
195 } else {
196 recursive_action(".", ACTION_RECURSE,
197 parse_module, NULL, &modules, 0);
198 }
199
200 /* Generate dependency and alias files */
201 if (!(option_mask32 & OPT_n))
202 xfreopen_write(CONFIG_DEFAULT_DEPMOD_FILE, stdout);
203
204 moddb_foreach_module(&modules, m, i) {
205 printf("%s:", m->name);
206
207 order_dep_list(&modules, m, m->deps);
208 while (m->dnext != m) {
209 dep = m->dnext;
210 printf(" %s", dep->name);
211
212 /* unlink current entry */
213 dep->dnext->dprev = dep->dprev;
214 dep->dprev->dnext = dep->dnext;
215 dep->dnext = dep->dprev = dep;
216 }
217 bb_putchar('\n');
218 }
219
220#if ENABLE_FEATURE_MODUTILS_ALIAS
221 if (!(option_mask32 & OPT_n))
222 xfreopen_write("modules.alias", stdout);
223 moddb_foreach_module(&modules, m, i) {
224 while (m->aliases) {
225 /*
226 * Last word used to be a basename
227 * (filename with path and .ko.* stripped)
228 * at the time of module-init-tools 3.4.
229 * kmod v.12 uses module name, i.e., s/-/_/g.
230 */
231 printf("alias %s %s\n",
232 (char*)llist_pop(&m->aliases),
233 m->modname);
234 }
235 }
236#endif
237#if ENABLE_FEATURE_MODUTILS_SYMBOLS
238 if (!(option_mask32 & OPT_n))
239 xfreopen_write("modules.symbols", stdout);
240 moddb_foreach_module(&modules, m, i) {
241 while (m->symbols) {
242 printf("alias symbol:%s %s\n",
243 (char*)llist_pop(&m->symbols),
244 m->modname);
245 }
246 }
247#endif
248
249 if (ENABLE_FEATURE_CLEAN_UP)
250 moddb_free(&modules);
251
252 return EXIT_SUCCESS;
253}
Note: See TracBrowser for help on using the repository browser.