Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / modpost_external_module_updates_rhel4.patch
1 This patch updates the RHEL 4 module build system to properly support
2 dependencies between external modules, similarly to the way they are
3 supported in newer kernels.
4
5 Index: linux-2.6.9-55.EL/scripts/Makefile.modpost
6 ===================================================================
7 --- linux-2.6.9-55.EL.orig/scripts/Makefile.modpost
8 +++ linux-2.6.9-55.EL/scripts/Makefile.modpost
9 @@ -38,7 +38,8 @@ _modpost: __modpost
10  include .config
11  include scripts/Makefile.lib
12  
13 -symverfile := $(objtree)/Module.symvers
14 +kernelsymfile := $(objtree)/Module.symvers
15 +modulesymfile := $(KBUILD_EXTMOD)/Module.symvers
16  
17  # Step 1), find all modules listed in $(MODVERDIR)/
18  __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
19 @@ -52,7 +53,9 @@ _modpost: $(modules)
20  quiet_cmd_modpost = MODPOST
21        cmd_modpost = scripts/mod/modpost            \
22          $(if $(CONFIG_MODVERSIONS),-m)             \
23 -       $(if $(KBUILD_EXTMOD),-i,-o) $(symverfile) \
24 +       $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
25 +       $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
26 +       $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
27         $(filter-out FORCE,$^)
28  
29  .PHONY: __modpost
30 Index: linux-2.6.9-55.EL/scripts/mod/modpost.c
31 ===================================================================
32 --- linux-2.6.9-55.EL.orig/scripts/mod/modpost.c
33 +++ linux-2.6.9-55.EL/scripts/mod/modpost.c
34 @@ -1,7 +1,8 @@
35  /* Postprocess module symbol versions
36   *
37   * Copyright 2003       Kai Germaschewski
38 - *           2002-2003  Rusty Russell, IBM Corporation
39 + *           2002-2004  Rusty Russell, IBM Corporation
40 + * Copyright 2006       Sam Ravnborg
41   *
42   * Based in part on module-init-tools/depmod.c,file2alias
43   *
44 @@ -18,6 +19,8 @@
45  int modversions = 0;
46  /* Warn about undefined symbols? (do so if we have vmlinux) */
47  int have_vmlinux = 0;
48 +/* If we are modposting external module set to 1 */
49 +static int external_module = 0;
50  
51  void
52  fatal(const char *fmt, ...)
53 @@ -45,6 +48,19 @@ warn(const char *fmt, ...)
54         va_end(arglist);
55  }
56  
57 +int
58 +is_vmlinux(const char *modname)
59 +{
60 +       const char *myname;
61 +
62 +       if ((myname = strrchr(modname, '/')))
63 +               myname++;
64 +       else
65 +               myname = modname;
66 +
67 +       return strcmp(myname, "vmlinux") == 0;
68 +}
69 +
70  void *do_nofail(void *ptr, const char *file, int line, const char *expr)
71  {
72         if (!ptr) {
73 @@ -102,6 +118,10 @@ struct symbol {
74         struct module *module;
75         unsigned int crc;
76         int crc_valid;
77 +       unsigned int vmlinux:1;    /* 1 if symbol is defined in vmlinux */
78 +       unsigned int kernel:1;     /* 1 if symbol is from kernel
79 +                                   *  (only for external modules) **/
80 +       unsigned int preloaded:1;  /* 1 if symbol from Module.symvers */
81         char name[0];
82  };
83  
84 @@ -136,8 +156,8 @@ alloc_symbol(const char *name, struct sy
85  
86  /* For the hash of exported symbols */
87  
88 -void
89 -new_symbol(const char *name, struct module *module, unsigned int *crc)
90 +static struct symbol *
91 +new_symbol(const char *name, struct module *module)
92  {
93         unsigned int hash;
94         struct symbol *new;
95 @@ -145,10 +165,7 @@ new_symbol(const char *name, struct modu
96         hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
97         new = symbolhash[hash] = alloc_symbol(name, symbolhash[hash]);
98         new->module = module;
99 -       if (crc) {
100 -               new->crc = *crc;
101 -               new->crc_valid = 1;
102 -       }
103 +       return new;
104  }
105  
106  struct symbol *
107 @@ -169,19 +186,29 @@ find_symbol(const char *name)
108  
109  /* Add an exported symbol - it may have already been added without a
110   * CRC, in this case just update the CRC */
111 -void
112 -add_exported_symbol(const char *name, struct module *module, unsigned int *crc)
113 +static struct symbol *
114 +sym_add_exported(const char *name, struct module *mod)
115  {
116         struct symbol *s = find_symbol(name);
117  
118         if (!s) {
119 -               new_symbol(name, module, crc);
120 -               return;
121 -       }
122 -       if (crc) {
123 -               s->crc = *crc;
124 -               s->crc_valid = 1;
125 +               s = new_symbol(name, mod);
126         }
127 +       s->preloaded = 0;
128 +       s->vmlinux   = is_vmlinux(mod->name);
129 +       s->kernel    = 0;
130 +       return s;
131 +}
132 +
133 +static void
134 +sym_update_crc(const char *name, struct module *mod, unsigned int crc)
135 +{
136 +       struct symbol *s = find_symbol(name);
137 +
138 +       if (!s)
139 +               s = new_symbol(name, mod);
140 +       s->crc = crc;
141 +       s->crc_valid = 1;
142  }
143  
144  void *
145 @@ -341,13 +368,13 @@ handle_modversions(struct module *mod, s
146                 /* CRC'd symbol */
147                 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
148                         crc = (unsigned int) sym->st_value;
149 -                       add_exported_symbol(symname + strlen(CRC_PFX),
150 -                                           mod, &crc);
151 +                       sym_update_crc(symname + strlen(CRC_PFX), mod, crc);
152                 }
153                 break;
154         case SHN_UNDEF:
155                 /* undefined symbol */
156 -               if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL)
157 +               if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
158 +                   ELF_ST_BIND(sym->st_info) != STB_WEAK)
159                         break;
160                 /* ignore global offset table */
161                 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
162 @@ -373,8 +400,7 @@ handle_modversions(struct module *mod, s
163         default:
164                 /* All exported symbols */
165                 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
166 -                       add_exported_symbol(symname + strlen(KSYMTAB_PFX),
167 -                                           mod, NULL);
168 +                       sym_add_exported(symname + strlen(KSYMTAB_PFX), mod);
169                 }
170                 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
171                         mod->has_init = 1;
172 @@ -384,19 +410,6 @@ handle_modversions(struct module *mod, s
173         }
174  }
175  
176 -int
177 -is_vmlinux(const char *modname)
178 -{
179 -       const char *myname;
180 -
181 -       if ((myname = strrchr(modname, '/')))
182 -               myname++;
183 -       else
184 -               myname = modname;
185 -
186 -       return strcmp(myname, "vmlinux") == 0;
187 -}
188 -
189  void
190  read_symbols(char *modname)
191  {
192 @@ -412,9 +425,7 @@ read_symbols(char *modname)
193         /* When there's no vmlinux, don't print warnings about
194          * unresolved symbols (since there'll be too many ;) */
195         if (is_vmlinux(modname)) {
196 -               unsigned int fake_crc = 0;
197                 have_vmlinux = 1;
198 -               add_exported_symbol("struct_module", mod, &fake_crc);
199                 mod->skip = 1;
200         }
201  
202 @@ -426,6 +437,7 @@ read_symbols(char *modname)
203         }
204         maybe_frob_version(modname, info.modinfo, info.modinfo_len,
205                            (void *)info.modinfo - (void *)info.hdr);
206 +
207         parse_elf_finish(&info);
208  
209         /* Our trick to get versioning for struct_module - it's
210 @@ -451,12 +463,7 @@ buf_printf(struct buffer *buf, const cha
211         
212         va_start(ap, fmt);
213         len = vsnprintf(tmp, SZ, fmt, ap);
214 -       if (buf->size - buf->pos < len + 1) {
215 -               buf->size += 128;
216 -               buf->p = realloc(buf->p, buf->size);
217 -       }
218 -       strncpy(buf->p + buf->pos, tmp, len + 1);
219 -       buf->pos += len;
220 +       buf_write(buf, tmp, len);
221         va_end(ap);
222  }
223  
224 @@ -464,7 +471,7 @@ void
225  buf_write(struct buffer *buf, const char *s, int len)
226  {
227         if (buf->size - buf->pos < len) {
228 -               buf->size += len;
229 +               buf->size += len + SZ;
230                 buf->p = realloc(buf->p, buf->size);
231         }
232         strncpy(buf->p + buf->pos, s, len);
233 @@ -506,8 +513,8 @@ add_versions(struct buffer *b, struct mo
234                 exp = find_symbol(s->name);
235                 if (!exp || exp->module == mod) {
236                         if (have_vmlinux)
237 -                               fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "
238 -                               "undefined!\n", s->name, mod->name);
239 +                               warn("\"%s\" [%s.ko] undefined!\n",
240 +                                    s->name, mod->name);
241                         continue;
242                 }
243                 s->module = exp->module;
244 @@ -615,8 +622,11 @@ write_if_changed(struct buffer *b, const
245         fclose(file);
246  }
247  
248 +/* parse Module.symvers file. line format:
249 + * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something]
250 + **/
251  void
252 -read_dump(const char *fname)
253 +read_dump(const char *fname, unsigned int kernel)
254  {
255         unsigned long size, pos = 0;
256         void *file = grab_file(fname, &size);
257 @@ -630,6 +640,7 @@ read_dump(const char *fname)
258                 char *symname, *modname, *d;
259                 unsigned int crc;
260                 struct module *mod;
261 +                struct symbol *s;
262  
263                 if (!(symname = strchr(line, '\t')))
264                         goto fail;
265 @@ -650,13 +661,30 @@ read_dump(const char *fname)
266                         mod = new_module(NOFAIL(strdup(modname)));
267                         mod->skip = 1;
268                 }
269 -               add_exported_symbol(symname, mod, &crc);
270 +                s = sym_add_exported(symname, mod);
271 +               s->kernel    = kernel;
272 +               s->preloaded = 1;
273 +               sym_update_crc(symname, mod, crc);
274         }
275         return;
276  fail:
277         fatal("parse error in symbol dump file\n");
278  }
279  
280 +/* For normal builds always dump all symbols.
281 + * For external modules only dump symbols
282 + * that are not read from kernel Module.symvers.
283 + **/
284 +static int
285 +dump_sym(struct symbol *sym)
286 +{
287 +       if (!external_module)
288 +               return 1;
289 +       if (sym->vmlinux || sym->kernel)
290 +               return 0;
291 +       return 1;
292 +}
293 +
294  void
295  write_dump(const char *fname)
296  {
297 @@ -667,15 +695,10 @@ write_dump(const char *fname)
298         for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
299                 symbol = symbolhash[n];
300                 while (symbol) {
301 -                       symbol = symbol->next;
302 -               }
303 -       }
304 -
305 -       for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
306 -               symbol = symbolhash[n];
307 -               while (symbol) {
308 -                       buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc,
309 -                               symbol->name, symbol->module->name);
310 +                       if (dump_sym(symbol))
311 +                               buf_printf(&buf, "0x%08x\t%s\t%s\n",
312 +                                       symbol->crc, symbol->name,
313 +                                       symbol->module->name);
314                         symbol = symbol->next;
315                 }
316         }
317 @@ -688,13 +711,18 @@ main(int argc, char **argv)
318         struct module *mod;
319         struct buffer buf = { };
320         char fname[SZ];
321 -       char *dump_read = NULL, *dump_write = NULL;
322 +       char *kernel_read = NULL, *module_read = NULL;
323 +       char *dump_write = NULL;
324         int opt;
325  
326 -       while ((opt = getopt(argc, argv, "i:mo:")) != -1) {
327 +       while ((opt = getopt(argc, argv, "i:I:mo:")) != -1) {
328                 switch(opt) {
329                         case 'i':
330 -                               dump_read = optarg;
331 +                               kernel_read = optarg;
332 +                               break;
333 +                       case 'I':
334 +                               module_read = optarg;
335 +                               external_module = 1;
336                                 break;
337                         case 'm':
338                                 modversions = 1;
339 @@ -707,8 +735,10 @@ main(int argc, char **argv)
340                 }
341         }
342  
343 -       if (dump_read)
344 -               read_dump(dump_read);
345 +       if (kernel_read)
346 +               read_dump(kernel_read, 1);
347 +       if (module_read)
348 +               read_dump(module_read, 0);
349  
350         while (optind < argc) {
351                 read_symbols(argv[optind++]);