* Re: Patch?: module-init-tools/modprobe.c - use modules.dep
[not found] <200211252254.OAA04288@freya.yggdrasil.com>
@ 2002-11-26 0:45 ` Rusty Russell
2002-11-26 7:40 ` [PATCH] Symbol name prefixes (e.g., `_') with the new module loader Miles Bader
0 siblings, 1 reply; 9+ messages in thread
From: Rusty Russell @ 2002-11-26 0:45 UTC (permalink / raw)
To: Adam J. Richter; +Cc: dwmw2, linux-kernel
In message <200211252254.OAA04288@freya.yggdrasil.com> you write:
> Rusty Russell wrote:
> >(you took out module alias support in your patch, though) 8(.
>
> Did not. See the routine get_alias() in my version.
No, you took out the part that reads the aliases from the module
itself (.modalias section).
> However, my version does not support:
>
> wildcard aliases,
> an alias that expands to multiple targets, or
> an alias that expands to an alias.
>
> It should only take a few lines to fix the first two.
See my wishlist for the second one (or/and support): this is a request
I got from someone.
> As for last, I'm not sure how useful aliasing to an alias really is.
Don't know. Combinations of and/or aliases would be easiest with
this, though.
> It wouldn't be the Manhattan Project to add it, but I'd rather not
> add a feature if it has no real use.
Good man!
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] Symbol name prefixes (e.g., `_') with the new module loader
2002-11-26 0:45 ` Patch?: module-init-tools/modprobe.c - use modules.dep Rusty Russell
@ 2002-11-26 7:40 ` Miles Bader
0 siblings, 0 replies; 9+ messages in thread
From: Miles Bader @ 2002-11-26 7:40 UTC (permalink / raw)
To: Rusty Russell; +Cc: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 436 bytes --]
Hi,
On the v850, the elf toolchain uses a `_' prefix for all user symbols
(I'm not sure why, since most toolchains seem to have dropped this sort
of thing).
The attached patch adds the ability to deal with this, if the macro
MODULE_SYMBOL_PREFIX is defined by <asm/module.h>. This only affects
places where symbol names come from the user, e.g., EXPORT_SYMBOL, or
the explicit symbol-names used in kernel/module.c itself.
Patch:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: module-sympfx-20021126.patch --]
[-- Type: text/x-patch, Size: 3161 bytes --]
diff -ruN -X../cludes ../orig/linux-2.5.49-uc0/include/linux/module.h include/linux/module.h
--- ../orig/linux-2.5.49-uc0/include/linux/module.h 2002-11-25 10:30:09.000000000 +0900
+++ include/linux/module.h 2002-11-25 18:55:11.000000000 +0900
@@ -88,11 +88,18 @@
void *__symbol_get_gpl(const char *symbol);
#define symbol_get(x) ((typeof(&x))(__symbol_get(#x)))
+#ifdef MODULE_SYMBOL_PREFIX
/* For every exported symbol, place a struct in the __ksymtab section */
#define EXPORT_SYMBOL(sym) \
const struct kernel_symbol __ksymtab_##sym \
__attribute__((section("__ksymtab"))) \
+ = { (unsigned long)&sym, MODULE_SYMBOL_PREFIX #sym }
+#else
+#define EXPORT_SYMBOL(sym) \
+ const struct kernel_symbol __ksymtab_##sym \
+ __attribute__((section("__ksymtab"))) \
= { (unsigned long)&sym, #sym }
+#endif
#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
#define EXPORT_SYMBOL_GPL(sym) EXPORT_SYMBOL(sym)
diff -ruN -X../cludes ../orig/linux-2.5.49-uc0/kernel/module.c kernel/module.c
--- ../orig/linux-2.5.49-uc0/kernel/module.c 2002-11-25 10:30:10.000000000 +0900
+++ kernel/module.c 2002-11-25 18:38:58.000000000 +0900
@@ -37,6 +37,17 @@
#define DEBUGP(fmt , a...)
#endif
+/* Define a handy short alias for MODULE_SYMBOL_PREFIX, defaulting
+ to "" if it isn't defined (it's also useful to avoid just
+ defining MODULE_SYMBOL_PREFIX here so that #ifdefs can still be
+ done against it). */
+#ifdef MODULE_SYMBOL_PREFIX
+#define SYMPFX MODULE_SYMBOL_PREFIX
+#else
+#define SYMPFX ""
+#endif
+
+
/* List of modules, protected by module_mutex */
static DECLARE_MUTEX(module_mutex);
LIST_HEAD(modules); /* FIXME: Accessed w/o lock on oops by some archs */
@@ -630,10 +641,10 @@
unsigned int i;
for (i = 1; i < sechdrs[symbolsec].sh_size/sizeof(*sym); i++) {
- if (strcmp("__initfn", strtab + sym[i].st_name) == 0)
+ if (strcmp(SYMPFX "__initfn", strtab + sym[i].st_name) == 0)
mod->init = (void *)sym[i].st_value;
#ifdef CONFIG_MODULE_UNLOAD
- if (strcmp("__exitfn", strtab + sym[i].st_name) == 0)
+ if (strcmp(SYMPFX "__exitfn", strtab + sym[i].st_name) == 0)
mod->exit = (void *)sym[i].st_value;
#endif
}
@@ -770,7 +781,8 @@
mod,
&ksg);
/* We fake up "__this_module" */
- if (strcmp(strtab+sym[i].st_name, "__this_module")==0)
+ if (strcmp(strtab+sym[i].st_name,
+ SYMPFX "__this_module")==0)
sym[i].st_value = (unsigned long)mod;
}
}
@@ -869,7 +881,8 @@
/* This module's name */
DEBUGP("Module name in section %u\n", i);
modnameindex = i;
- } else if (strcmp(secstrings+sechdrs[i].sh_name, "__ksymtab")
+ } else if (strcmp(secstrings+sechdrs[i].sh_name,
+ SYMPFX "__ksymtab")
== 0) {
/* Exported symbols. */
DEBUGP("EXPORT table in section %u\n", i);
@@ -884,7 +897,8 @@
/* Setup parameter info */
DEBUGP("Setup table found in section %u\n", i);
setupindex = i;
- } else if (strcmp(secstrings+sechdrs[i].sh_name, "__ex_table")
+ } else if (strcmp(secstrings+sechdrs[i].sh_name,
+ SYMPFX "__ex_table")
== 0) {
/* Exception table */
DEBUGP("Exception table found in section %u\n", i);
[-- Attachment #3: Type: text/plain, Size: 63 bytes --]
Thanks,
-Miles
--
"1971 pickup truck; will trade for guns"
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Patch?: module-init-tools/modprobe.c - use modules.dep
2002-11-27 5:02 ` Rusty Russell
@ 2002-11-27 23:17 ` Keith Owens
0 siblings, 0 replies; 9+ messages in thread
From: Keith Owens @ 2002-11-27 23:17 UTC (permalink / raw)
To: linux-kernel
On Wed, 27 Nov 2002 16:02:08 +1100,
Rusty Russell <rusty@rustcorp.com.au> wrote:
>In message <200211261902.LAA04005@baldur.yggdrasil.com> you write:
>> >I'd prefer a static parser which turns modules.conf into modprobe.conf
>> >rather than reimplementing modules.conf (config files which are so
>> >complex they need a "hobbled mode" in case they are called from
>> >untrusted context are in trouble already).
>>
>> Could we just use modules.conf and not support certain
>> commands?
>
>Hmm, I'd prefer to convert.
I hope you are going to check with everybody using complex modules.conf
files before you remove all the facilities. I know that there are
people who rely on being able to run commands in modules.conf to suit
their system.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Patch?: module-init-tools/modprobe.c - use modules.dep
2002-11-26 19:02 Patch?: module-init-tools/modprobe.c - use modules.dep Adam J. Richter
@ 2002-11-27 5:02 ` Rusty Russell
2002-11-27 23:17 ` Keith Owens
0 siblings, 1 reply; 9+ messages in thread
From: Rusty Russell @ 2002-11-27 5:02 UTC (permalink / raw)
To: Adam J. Richter; +Cc: dwmw2, linux-kernel
In message <200211261902.LAA04005@baldur.yggdrasil.com> you write:
> On Tue, 26 Nov 2002 10:34:30 +1100, Rusty Russell wrote:
> >In message <200211251916.LAA01830@baldur.yggdrasil.com> you write:
> [...]
> >> >The ELF dependence will go back in eventually, but that's trivial.
> >>
> >> I'm guessing this is for symbols. If it's for something other
> >> reason, I'd be curious to know it.
> >
> >--name support. It's a hack, but it's 20 lines in total.
>
> Why not derive the default name from the file name?
Yes, it's a choice. But inside the kernel, modules know their own
name for module_parm() support. Changing it outside the kernel is
counterintuitive, and hence generally inadvisable.
> By the way, I have sometimes wanted to be able to load
> multiple copies of the same module with different names, usually
> little debugging helpers with different command line options.
Yes, this is exactly why this hack exists (dummy.o and ethertap.o kind
of rely on it).
> >Frankly, linking just *isn't* that hard, especially when you're doing
> >it on your own architecture (vs. 32-bit userspace handling both 32-bit
> >and 64-bit kernelspaces).
>
> I think that Roman's approach of having a module-init.o
> to initialize the struct module would reduce or eliminate this.
Yes, and, we could ship libc with the kernel and avoid having to keep
stable system call interfaces too. But there's benifit in not doing
it: we keep the kernel fairly standalone and it is good discipline for
us.
> >With RTH's "make it a shared object" patch,
> >it becomes even more trivial.
>
> rth's patch prevents allocating sections separately, so you
> won't be able to kmalloc them as much, using TLB entries unnecessarily,
> and using memory less efficiently in the case where the non-init
> sections would fit in a single area small enough to be kmalloc'ed.
> It's a modest cost, but it's something for the score card.
Even in total, most modules are fairly small, so I don't think it's a
big issue really. Maybe.
> >But let's ignore my ideas, and look at three things which have been
> >suggested to me by other people since this patch went in. Ted Ts'o's
> >digital signatures on modules. Obviously much simpler in kernelspace.
>
> No. You're much more likely to have random crypto software in
> user land.
Yes, but I believe the problem is that the kernel has to authenticate
it somehow.
> There are also a variety of changes which are easier with the
> module loader in user land (saving ~100kB of unswappable space by
> kicking the symbols out of the kernel, being able to load modules with
> dependency loops).
The first one is definitely a valid point, which I hadn't considered
before. Of course, compression takes it down to 14k, which implies we
should at least be doing something with it 8(
> >I'd prefer a static parser which turns modules.conf into modprobe.conf
> >rather than reimplementing modules.conf (config files which are so
> >complex they need a "hobbled mode" in case they are called from
> >untrusted context are in trouble already).
>
> Could we just use modules.conf and not support certain
> commands?
Hmm, I'd prefer to convert.
>
> >My plans were:
> >
> >1) Extend alias to be:
> >
> > alias foo bar [and|or baz]...
> >
> > Aliases would continue to insist that they resolve where defined (to
> > avoid loops).
>
> As we discussed, I suspect that we can insist that the names on
> the right hand size must be actual module names, not aliases, at least
> until someone complains and identifies a real use for aliases to
> aliases.
Sure.
> >2) Implement "options" of course, which would stack (in case you
> > attach modules to an alias), and
>
> There are usually a small number of "options" lines that
> people want to add, and I think that external packages that install
> kernel module might want to install and remove those lines, so it
> might be better to use the filesystem as the database for this, by
> having small files like /etc/modules/args/ipsec_tunnel.
Hmm, Debian actually compiles up modules.conf at the moment as it is:
it's probably better to leave this to the distros anyway.
> >3) Implement "install" (to allow arbitrary stuff like pre and post,
> > weirdass conditional stuff, etc).
>
> Then why not just run the existing modutils version of
> modprobe?
Because three commands should do everything we need? Because it's
infinitely simpler? But mainly because I *want* people to customize
modprobe for their own uses (that's why /proc/sys/kernel/modprobe
exists), and simplicity is good.
> I've been thinking that perhaps we should eliminate
> request_module() from the kernel and instead generate a "want"
Hmm, I'll have to take time to think about it. One kernel change at a
time, I think 8)
Cheers,
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Patch?: module-init-tools/modprobe.c - use modules.dep
@ 2002-11-26 19:02 Adam J. Richter
2002-11-27 5:02 ` Rusty Russell
0 siblings, 1 reply; 9+ messages in thread
From: Adam J. Richter @ 2002-11-26 19:02 UTC (permalink / raw)
To: rusty; +Cc: dwmw2, linux-kernel
On Tue, 26 Nov 2002 10:34:30 +1100, Rusty Russell wrote:
>In message <200211251916.LAA01830@baldur.yggdrasil.com> you write:
[...]
>> >The ELF dependence will go back in eventually, but that's trivial.
>>
>> I'm guessing this is for symbols. If it's for something other
>> reason, I'd be curious to know it.
>
>--name support. It's a hack, but it's 20 lines in total.
Why not derive the default name from the file name?
By the way, I have sometimes wanted to be able to load
multiple copies of the same module with different names, usually
little debugging helpers with different command line options.
>> [...] I have not seen any convincing
>> accounting of real benefits and costs that shows that it is a win to
>> have the module loader in kernel memory.
>
>Well, the linecount comes out as a wash (it's slightly bigger because
>of the hoops I jump through to avoid a spinlock on module refcount
>acquisition, but that's orthogonal). Some archs lose 100 lines, some
>gain 400 lines. The win comes from the cleanliness of two syscalls:
>one to add, one to remove. For userspace loading you have one to
>allocate, one to insert, one to query so you know how to link. Turns
>out to be more complicated than just doing the damn linking yourself.
Sometimes a larger total code size to achieve smaller kernel
code size is a worthwhile trade-off because the userland code is not
always present, is swappable, is more customizable without rebooting
the system, etc. Whether that is the case with the module loader
is the question that I'm trying to analyze.
>Frankly, linking just *isn't* that hard, especially when you're doing
>it on your own architecture (vs. 32-bit userspace handling both 32-bit
>and 64-bit kernelspaces).
I think that Roman's approach of having a module-init.o
to initialize the struct module would reduce or eliminate this.
>With RTH's "make it a shared object" patch,
>it becomes even more trivial.
rth's patch prevents allocating sections separately, so you
won't be able to kmalloc them as much, using TLB entries unnecessarily,
and using memory less efficiently in the case where the non-init
sections would fit in a single area small enough to be kmalloc'ed.
It's a modest cost, but it's something for the score card.
>But the flexibility! By having a real interface, insmod doesn't need
>to know anything about the module (modprobe still does, but even that
>is very limited).
Roman's module-init.o reduces or eliminates this difference.
>Shrinking insmod to 20 lines and putting it in
>busybox is nice, but being able to change the way parameters are
>parsed,
I think the module parameters should be passed as an
argument to the init_module/insmod system call in either case.
>being able to switch reference count schemes, alter
>initialization or shutdown methods, rewrite module versioning to be
>sane, and otherwise tweak the kernel internals without breaking
>userspace is a huge win.
For some changes, yes, but for some many other changes, a
scheme that uses Roman's module-init.o might not need any insmod
changes. And, for an insmod as simple as Roman's mini-loader,
we could ship it with the kernel tree and install it in
/lib/modules/<version>/bin/.
>But let's ignore my ideas, and look at three things which have been
>suggested to me by other people since this patch went in. Ted Ts'o's
>digital signatures on modules. Obviously much simpler in kernelspace.
No. You're much more likely to have random crypto software in
user land. User level authentication code can allocate memory more
freely, lookup up supporting certificates in external files, do
more elaborate more elaborate error handling like popping up a
dialog to say "The certificate for this module has expired.
Install it anyway?", or attempt to log the problem in
detail to a security server.
>The second is Keith Owens' NUMA text replication. Now such a change
>is entirely up to the architecture (no modutils upgrade, sure, it will
>almost certainly break oprofile on them though for kernel hackers).
Yes. By the way, I assume that we're talking about the
read-only sections of a module being mapped to different physical
pages but having the same virtual addresses across all processors, by
the way. User level insmod would need to be changed to load the
read-only sections separately.
>The third is David Woodhouse's "multiple init for modules". There are
>some fundamental questions (each initfn must have a matching exitfn in
>case a later one fails), but this change wouldn't break userspace
>either.
With something like module-{init,end}.o, this should not
require a further change to insmod.
There are also a variety of changes which are easier with the
module loader in user land (saving ~100kB of unswappable space by
kicking the symbols out of the kernel, being able to load modules with
dependency loops). Also, it's a small incremental difference, but
lowering the minimum resource costs of CONFIG_MODULES means that a
standard binary Linux kernel link kit may be a slightly more appealing
option to gadget makers in comparison to Vxworks, Windows NTE, CE, in
terms of engineering risk (e.g., what if the one kernel person who is
working on someone's digital music player quits).
Anyhow, thank you very much for taking the time to explain
your case for kernel module loading. I'm still thinking about it.
Regarding module loading tools that could support both user level
and kernel module loading:
>Sure: it'd definitely be worth distributing them together rather than
>the horrible install hack at the moment (there's a RPM which already
>does this).
Good.
>I'd prefer a static parser which turns modules.conf into modprobe.conf
>rather than reimplementing modules.conf (config files which are so
>complex they need a "hobbled mode" in case they are called from
>untrusted context are in trouble already).
Could we just use modules.conf and not support certain
commands?
>My plans were:
>
>1) Extend alias to be:
>
> alias foo bar [and|or baz]...
>
> Aliases would continue to insist that they resolve where defined (to
> avoid loops).
As we discussed, I suspect that we can insist that the names on
the right hand size must be actual module names, not aliases, at least
until someone complains and identifies a real use for aliases to
aliases.
>2) Implement "options" of course, which would stack (in case you
> attach modules to an alias), and
There are usually a small number of "options" lines that
people want to add, and I think that external packages that install
kernel module might want to install and remove those lines, so it
might be better to use the filesystem as the database for this, by
having small files like /etc/modules/args/ipsec_tunnel.
>3) Implement "install" (to allow arbitrary stuff like pre and post,
> weirdass conditional stuff, etc).
Then why not just run the existing modutils version of
modprobe?
I've been thinking that perhaps we should eliminate
request_module() from the kernel and instead generate a "want"
hotplug event ("hotplug filesystem want ext3",
"hotplug devfs want /dev/discs/disc0/part3", "hotplug soundcore want oss")
and move some of this complexity from modprobe to hotplug. My
reason are:
1. While we usually want to load a module in response to
these events, we might not always want to, and but we still
might want the "pre and post, weirdass conditional stuff, etc."
For example "hotplug devfs want /dev/discs/disc0/part3" may
just invoke "partx -a /dev/discs/disc0/disc".
2. Walking a tree and loading a kernel module are probably best
done in C, while most of this other customization is
probably best done from shell scripts.
3. There is a known security issue that users might
be able to cause a "dangerous" module to be loaded by
doing things like "ifconfig name-of-a-dangerous-module".
4. Conceivably, we may want software packages that load a
set of hotplug functionality based on bus type, so it
would be helpful to use an interface that has the extra
argument for bus type as hotplug does.
Maybe enough as been broken already, and this idea could be
pursued incrementally later if it's worth it. Any comments would
be welcome.
Also, thanks again for explaining your case for kernel module
loading.
Adam J. Richter __ ______________ 575 Oroville Road
adam@yggdrasil.com \ / Milpitas, California 95035
+1 408 309-6081 | g g d r a s i l United States of America
"Free Software For The Rest Of Us."
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Patch?: module-init-tools/modprobe.c - use modules.dep
2002-11-25 19:16 Adam J. Richter
@ 2002-11-25 23:34 ` Rusty Russell
0 siblings, 0 replies; 9+ messages in thread
From: Rusty Russell @ 2002-11-25 23:34 UTC (permalink / raw)
To: Adam J. Richter; +Cc: dwmw2, linux-kernel
In message <200211251916.LAA01830@baldur.yggdrasil.com> you write:
> Rusty Russell wrote:
> >Hmm, I like it. But I prefer to pull the depmod code into the source
> >too, to keep it all under one roof.
>
> I have been thinking about splitting depmod into two programs:
> the program as originally designed that generates modules.dep and one
> that generates hardware support files. The latter could be
> distributed in the Linux kernel tree and perhaps installed in
> /lib/modules/<version>/bin/ to make it easy to change support table
> formats as needed.
Makes sense, but the plan was to migrate to using module aliases
anyway (you took out module alias support in your patch, though) 8(.
The modules are postprocessed on built to convert the device tables
into a series of aliases, eg. "usb:v0506p4601dl*dh*dc*dsc*dp*ic*isc*ip*"
for drivers/usb/net/pegasus.o. Then /sbin/hotplug just goes "modprobe
usb:v0506p4601dl01dh01dc01dsc01dp01ic01isc01ip01" or whatever, and voila.
The alias system also allows a driver to alias to an older driver, eg:
/* We can be used in place of the older driver if it isn't present */
MODULE_ALIAS("foo2000");
I've put a FIXME:, under your scheme the alias information from the
modules themselves needs to be extracted by depmod.
> >The ELF dependence will go back in eventually, but that's trivial.
>
> I'm guessing this is for symbols. If it's for something other
> reason, I'd be curious to know it.
--name support. It's a hack, but it's 20 lines in total.
> >Hmm, Adam, do you want to reverse positions and become
> >module-init-tools maintainer? I'll send patches to you, instead of
> >vice versa. I'll release a 0.8 with the patches I have so far, then
> >hand it over if you want.
>
> >Thoughts?
> >Rusty.
>
> I'm honored by the offer, but I have not seen any convincing
> accounting of real benefits and costs that shows that it is a win to
> have the module loader in kernel memory.
Well, the linecount comes out as a wash (it's slightly bigger because
of the hoops I jump through to avoid a spinlock on module refcount
acquisition, but that's orthogonal). Some archs lose 100 lines, some
gain 400 lines. The win comes from the cleanliness of two syscalls:
one to add, one to remove. For userspace loading you have one to
allocate, one to insert, one to query so you know how to link. Turns
out to be more complicated than just doing the damn linking yourself.
Frankly, linking just *isn't* that hard, especially when you're doing
it on your own architecture (vs. 32-bit userspace handling both 32-bit
and 64-bit kernelspaces). With RTH's "make it a shared object" patch,
it becomes even more trivial.
But the flexibility! By having a real interface, insmod doesn't need
to know anything about the module (modprobe still does, but even that
is very limited). Shrinking insmod to 20 lines and putting it in
busybox is nice, but being able to change the way parameters are
parsed, being able to switch reference count schemes, alter
initialization or shutdown methods, rewrite module versioning to be
sane, and otherwise tweak the kernel internals without breaking
userspace is a huge win.
But let's ignore my ideas, and look at three things which have been
suggested to me by other people since this patch went in. Ted Ts'o's
digital signatures on modules. Obviously much simpler in kernelspace.
The second is Keith Owens' NUMA text replication. Now such a change
is entirely up to the architecture (no modutils upgrade, sure, it will
almost certainly break oprofile on them though for kernel hackers).
The third is David Woodhouse's "multiple init for modules". There are
some fundamental questions (each initfn must have a matching exitfn in
case a later one fails), but this change wouldn't break userspace
either.
Even if the code had added 500 lines to the kernel, I'd say it was a
win.
> I might be interested in
> maintaining a small modutils that could be compiled to support either
> the in-kernel module load or a user level method (or both) so as to
> avoid unnecessary differences between the user level and in-kernel
> methods, given that the code that is specific to the kernel module
> loader would be small.
Sure: it'd definitely be worth distributing them together rather than
the horrible install hack at the moment (there's a RPM which already
does this).
I'd prefer a static parser which turns modules.conf into modprobe.conf
rather than reimplementing modules.conf (config files which are so
complex they need a "hobbled mode" in case they are called from
untrusted context are in trouble already). My plans were:
1) Extend alias to be:
alias foo bar [and|or baz]...
Aliases would continue to insist that they resolve where defined (to
avoid loops).
2) Implement "options" of course, which would stack (in case you
attach modules to an alias), and
3) Implement "install" (to allow arbitrary stuff like pre and post,
weirdass conditional stuff, etc).
Thoughts?
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Patch?: module-init-tools/modprobe.c - use modules.dep
@ 2002-11-25 19:16 Adam J. Richter
2002-11-25 23:34 ` Rusty Russell
0 siblings, 1 reply; 9+ messages in thread
From: Adam J. Richter @ 2002-11-25 19:16 UTC (permalink / raw)
To: rusty; +Cc: dwmw2, linux-kernel
Rusty Russell wrote:
>In message <20021121073912.A15349@adam.yggdrasil.com> you [Adam Richter] write:
>>
>> --xHFwDpU9dbj6ez1V
>> Content-Type: text/plain; charset=us-ascii
>> Content-Disposition: inline
>>
>> The following patch changes modprobe in module-init-tools-0.8
>> to use modules.dep.
>>
>> Benefits:
>>
>> - deletes a net of 594 lines of source code
>>
>> - shrinks modprobe from 14kB to 10kB (stripped, dynamically linked),
>> which is useful for boot images
>>
>> - should make modprobe as fast on systems with a lot of modules as
>> it was with the user level module loader,
>>
>> - Restores the "include" command to the aliases file, which makes
>> it simpler to have separate files for automatically generated
>> aliases and user customizations.
>>
>> - minor: eliminates ELF dependence from modprobe user level code
>Hmm, I like it. But I prefer to pull the depmod code into the source
>too, to keep it all under one roof.
I have been thinking about splitting depmod into two programs:
the program as originally designed that generates modules.dep and one
that generates hardware support files. The latter could be
distributed in the Linux kernel tree and perhaps installed in
/lib/modules/<version>/bin/ to make it easy to change support table
formats as needed.
>The ELF dependence will go back in eventually, but that's trivial.
I'm guessing this is for symbols. If it's for something other
reason, I'd be curious to know it.
>Hmm, Adam, do you want to reverse positions and become
>module-init-tools maintainer? I'll send patches to you, instead of
>vice versa. I'll release a 0.8 with the patches I have so far, then
>hand it over if you want.
>Thoughts?
>Rusty.
I'm honored by the offer, but I have not seen any convincing
accounting of real benefits and costs that shows that it is a win to
have the module loader in kernel memory. I might be interested in
maintaining a small modutils that could be compiled to support either
the in-kernel module load or a user level method (or both) so as to
avoid unnecessary differences between the user level and in-kernel
methods, given that the code that is specific to the kernel module
loader would be small.
Adam J. Richter __ ______________ 575 Oroville Road
adam@yggdrasil.com \ / Milpitas, California 95035
+1 408 309-6081 | g g d r a s i l United States of America
"Free Software For The Rest Of Us."
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Patch?: module-init-tools/modprobe.c - use modules.dep
2002-11-21 15:39 Adam J. Richter
@ 2002-11-25 5:47 ` Rusty Russell
0 siblings, 0 replies; 9+ messages in thread
From: Rusty Russell @ 2002-11-25 5:47 UTC (permalink / raw)
To: Adam J. Richter; +Cc: dwmw2, linux-kernel
In message <20021121073912.A15349@adam.yggdrasil.com> you write:
>
> --xHFwDpU9dbj6ez1V
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: inline
>
> The following patch changes modprobe in module-init-tools-0.8
> to use modules.dep.
>
> Benefits:
>
> - deletes a net of 594 lines of source code
>
> - shrinks modprobe from 14kB to 10kB (stripped, dynamically linked),
> which is useful for boot images
>
> - should make modprobe as fast on systems with a lot of modules as
> it was with the user level module loader,
>
> - Restores the "include" command to the aliases file, which makes
> it simpler to have separate files for automatically generated
> aliases and user customizations.
>
> - minor: eliminates ELF dependence from modprobe user level code
Hmm, I like it. But I prefer to pull the depmod code into the source
too, to keep it all under one roof.
The ELF dependence will go back in eventually, but that's trivial.
Hmm, Adam, do you want to reverse positions and become
module-init-tools maintainer? I'll send patches to you, instead of
vice versa. I'll release a 0.8 with the patches I have so far, then
hand it over if you want.
Thoughts?
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Patch?: module-init-tools/modprobe.c - use modules.dep
@ 2002-11-21 15:39 Adam J. Richter
2002-11-25 5:47 ` Rusty Russell
0 siblings, 1 reply; 9+ messages in thread
From: Adam J. Richter @ 2002-11-21 15:39 UTC (permalink / raw)
To: rusty; +Cc: dwmw2, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2514 bytes --]
The following patch changes modprobe in module-init-tools-0.8
to use modules.dep.
Benefits:
- deletes a net of 594 lines of source code
- shrinks modprobe from 14kB to 10kB (stripped, dynamically linked),
which is useful for boot images
- should make modprobe as fast on systems with a lot of modules as
it was with the user level module loader,
- Restores the "include" command to the aliases file, which makes
it simpler to have separate files for automatically generated
aliases and user customizations.
- minor: eliminates ELF dependence from modprobe user level code
Drawbacks:
- It makes modprobe require that depmod had been run at some
point (although it isn't necessary to put depmod on a boot
image to use modprobe; you just need it when you want to add
a module that you want modprobe to know about). The current
depmod implementation is bigger than 594 lines of code, but
also generates hardware device tables, so systems that do
hardware autoconfiguration this way currently need depmod anyhow.
- I have not tested these changes much, because the in-kernel
module loader reports "memory allocation failure" for many
modules that I try to load. This does not appear to be
related to my changes.
- I do not currently see a positive balance of real benefits
to putting the module linker in unswappable kernel memory.
If you're running a system with a user level module loader,
you are probably better off staying with that.
Note to lmkl readers: this patch is again
module-init-tools-0.8.dwmw2, which is a modification done by David
Woodhouse of module-init-tools-0.7. It is not an official release,
and it requires a kernel patch which changes the system call interface
for loading modules (to pass the module name). I am posting a patch
against it instead of 0.7 because I don't want people applying this
patch and then breaking their systems due to the interface change. I
am also attaching David's patches to this message (after checking with
him by email), but please do not refer to David's changes or mine as
releases of module-init-tools, as they both depend on David's kernel
changes, which may or may not be integrated into Linus's future
releases.
--
Adam J. Richter __ ______________ 575 Oroville Road
adam@yggdrasil.com \ / Milpitas, California 95035
+1 408 309-6081 | g g d r a s i l United States of America
"Free Software For The Rest Of Us."
[-- Attachment #2: mod-init-tools.diff --]
[-- Type: text/plain, Size: 31288 bytes --]
diff -u -r --new-file module-init-tools-0.8/Makefile.in module-init-tools-0.9.ajr/Makefile.in
--- module-init-tools-0.8/Makefile.in 2002-11-13 18:09:56.000000000 -0800
+++ module-init-tools-0.9.ajr/Makefile.in 2002-11-21 05:55:06.000000000 -0800
@@ -5,8 +5,8 @@
default: insmod rmmod lsmod modprobe
-insmod.o rmmod.o lsmod.o: backwards_compat.c
-modprobe.o: backwards_compat.c mod32.c mod64.c mod_types.h
+insmod.o rmmod.o lsmod.o: backwards_compat.c mod_types.h
+modprobe.o: backwards_compat.c mod_types.h
# Moving a link lsmod -> insmod requires two moves.
%.old:
diff -u -r --new-file module-init-tools-0.8/mod32.c module-init-tools-0.9.ajr/mod32.c
--- module-init-tools-0.8/mod32.c 2002-11-13 18:15:24.000000000 -0800
+++ module-init-tools-0.9.ajr/mod32.c 1969-12-31 16:00:00.000000000 -0800
@@ -1,158 +0,0 @@
-static void *load_section32(int fd, unsigned long shdroff,
- unsigned int num_secs,
- unsigned int secnamesec,
- const char *secname,
- unsigned long *size)
-{
- Elf32_Shdr sechdrs[num_secs];
- unsigned int i;
- char *secnames;
-
- /* Grab headers. */
- lseek(fd, shdroff, SEEK_SET);
- if (read(fd, sechdrs, sizeof(sechdrs)) != sizeof(sechdrs))
- return (void*)-1;
-
- /* Grab strings so we can tell who is who */
- secnames = malloc(sechdrs[secnamesec].sh_size);
- lseek(fd, sechdrs[secnamesec].sh_offset, SEEK_SET);
- if (read(fd, secnames, sechdrs[secnamesec].sh_size)
- != sechdrs[secnamesec].sh_size) {
- free(secnames);
- return (void*)-1;
- }
-
-
- /* Find the section they want */
- for (i = 1; i < num_secs; i++) {
- if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) {
- void *buf;
-
- free(secnames);
- *size = sechdrs[i].sh_size;
- buf = malloc(*size);
- if (lseek(fd, sechdrs[i].sh_offset, SEEK_SET) == -1
- || read(fd, buf, *size) != *size) {
- free(buf);
- return (void *)-1;
- }
- return buf;
- }
- }
- free(secnames);
- return NULL;
-}
-
-static void *map_exports32(int fd,
- unsigned long shdroff,
- unsigned int num_secs,
- unsigned int secnamesec,
- const char *name,
- unsigned int *num_exports)
-{
- struct kernel_symbol32 *syms;
- unsigned long size;
-
- syms = load_section32(fd, shdroff, num_secs, secnamesec, "__ksymtab",
- &size);
- *num_exports = 0;
- if (syms == (void*)-1) {
- warn("Error finding exports for module %s\n", name);
- syms = NULL;
- } else if (syms)
- *num_exports = size / sizeof(struct kernel_symbol32);
- return syms;
-}
-
-static int export_name_cmp32(struct module *m, int index, const char *name)
-{
- return strcmp(m->u.exports32[index].name, name);
-}
-
-static struct module *add_module32(int fd, struct module *new,
- struct module *last,
- struct alias **aliases)
-{
- Elf32_Ehdr hdr;
-
- if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
- warn("Error reading module %s\n", new->name);
- free(new);
- close(fd);
- return last;
- }
-
- /* Map the section table */
- new->u.ptr = mops->map_exports(fd, hdr.e_shoff, hdr.e_shnum,
- hdr.e_shstrndx, new->name,
- &new->num_exports);
-
- /* Add in any aliases */
- *aliases = add_aliases(fd, hdr.e_shoff, hdr.e_shnum,
- hdr.e_shstrndx, new, *aliases);
-
- close(fd);
- return new;
-}
-
-/* Analyse this module to see if it needs others. */
-static int get_deps32(unsigned int order,
- const char *dirname,
- const char *modname,
- struct module *modules,
- int verbose)
-{
- unsigned int i;
- unsigned long size;
- Elf32_Ehdr hdr;
- int fd;
- char *strings;
- Elf32_Sym *syms;
- int needed = 0;
- char modpath[strlen(dirname) + strlen(modname)
- + sizeof(MODULE_EXTENSION)];
-
- sprintf(modpath, "%s%s%s", dirname, modname, MODULE_EXTENSION);
- fd = open(modpath, O_RDONLY);
- if (fd < 0)
- fatal("Can't open module %s: %s\n", modpath, strerror(errno));
-
- if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
- fatal("Error reading module %s\n", modpath);
-
- strings = mops->load_section(fd, hdr.e_shoff, hdr.e_shnum,
- hdr.e_shstrndx, ".strtab", &size);
- syms = mops->load_section(fd, hdr.e_shoff, hdr.e_shnum,
- hdr.e_shstrndx, ".symtab", &size);
- if (!strings || strings == (void *)-1
- || !syms || syms == (void *)-1) {
- fatal("Could not load strings and symbol table from %s\n",
- modpath);
- }
-
- /* Now establish which modules we need */
- for (i = 0; i < size / sizeof(syms[0]); i++) {
- if (syms[i].st_shndx == SHN_UNDEF) {
- /* Look for symbol */
- const char *name = strings + syms[i].st_name;
-
- if (strcmp(name, "") == 0)
- continue;
-
- /* Did this pull in a new module? */
- if (need_symbol(order, name, modules,
- verbose ? modpath : NULL))
- needed = 1;
- }
- }
- close(fd);
- return needed;
-}
-
-static struct mod_ops mod32_ops = {
- .load_section = load_section32,
- .map_exports = map_exports32,
- .export_name_cmp = export_name_cmp32,
- .add_module = add_module32,
- .get_deps = get_deps32,
-};
diff -u -r --new-file module-init-tools-0.8/mod64.c module-init-tools-0.9.ajr/mod64.c
--- module-init-tools-0.8/mod64.c 2002-11-13 18:15:57.000000000 -0800
+++ module-init-tools-0.9.ajr/mod64.c 1969-12-31 16:00:00.000000000 -0800
@@ -1,158 +0,0 @@
-static void *load_section64(int fd, unsigned long shdroff,
- unsigned int num_secs,
- unsigned int secnamesec,
- const char *secname,
- unsigned long *size)
-{
- Elf64_Shdr sechdrs[num_secs];
- unsigned int i;
- char *secnames;
-
- /* Grab headers. */
- lseek(fd, shdroff, SEEK_SET);
- if (read(fd, sechdrs, sizeof(sechdrs)) != sizeof(sechdrs))
- return (void*)-1;
-
- /* Grab strings so we can tell who is who */
- secnames = malloc(sechdrs[secnamesec].sh_size);
- lseek(fd, sechdrs[secnamesec].sh_offset, SEEK_SET);
- if (read(fd, secnames, sechdrs[secnamesec].sh_size)
- != sechdrs[secnamesec].sh_size) {
- free(secnames);
- return (void*)-1;
- }
-
-
- /* Find the section they want */
- for (i = 1; i < num_secs; i++) {
- if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) {
- void *buf;
-
- free(secnames);
- *size = sechdrs[i].sh_size;
- buf = malloc(*size);
- if (lseek(fd, sechdrs[i].sh_offset, SEEK_SET) == -1
- || read(fd, buf, *size) != *size) {
- free(buf);
- return (void *)-1;
- }
- return buf;
- }
- }
- free(secnames);
- return NULL;
-}
-
-static void *map_exports64(int fd,
- unsigned long shdroff,
- unsigned int num_secs,
- unsigned int secnamesec,
- const char *name,
- unsigned int *num_exports)
-{
- struct kernel_symbol64 *syms;
- unsigned long size;
-
- syms = load_section64(fd, shdroff, num_secs, secnamesec, "__ksymtab",
- &size);
- *num_exports = 0;
- if (syms == (void*)-1) {
- warn("Error finding exports for module %s\n", name);
- syms = NULL;
- } else if (syms)
- *num_exports = size / sizeof(struct kernel_symbol64);
- return syms;
-}
-
-static int export_name_cmp64(struct module *m, int index, const char *name)
-{
- return strcmp(m->u.exports64[index].name, name);
-}
-
-static struct module *add_module64(int fd, struct module *new,
- struct module *last,
- struct alias **aliases)
-{
- Elf64_Ehdr hdr;
-
- if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
- warn("Error reading module %s\n", new->name);
- free(new);
- close(fd);
- return last;
- }
-
- /* Map the section table */
- new->u.ptr = mops->map_exports(fd, hdr.e_shoff, hdr.e_shnum,
- hdr.e_shstrndx, new->name,
- &new->num_exports);
- /* Add in any aliases */
- *aliases = add_aliases(fd, hdr.e_shoff, hdr.e_shnum,
- hdr.e_shstrndx, new, *aliases);
-
- close(fd);
- return new;
-}
-
-/* Analyse this module to see if it needs others. */
-static int get_deps64(unsigned int order,
- const char *dirname,
- const char *modname,
- struct module *modules,
- int verbose)
-{
- unsigned int i;
- unsigned long size;
- Elf64_Ehdr hdr;
- int fd;
- char *strings;
- Elf64_Sym *syms;
- int needed = 0;
- char modpath[strlen(dirname) + strlen(modname)
- + sizeof(MODULE_EXTENSION)];
-
- sprintf(modpath, "%s%s%s", dirname, modname, MODULE_EXTENSION);
-
- fd = open(modpath, O_RDONLY);
- if (fd < 0)
- fatal("Can't open module %s: %s\n", modpath, strerror(errno));
-
- if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
- fatal("Error reading module %s\n", modpath);
-
- strings = mops->load_section(fd, hdr.e_shoff, hdr.e_shnum,
- hdr.e_shstrndx, ".strtab", &size);
- syms = mops->load_section(fd, hdr.e_shoff, hdr.e_shnum,
- hdr.e_shstrndx, ".symtab", &size);
- if (!strings || strings == (void *)-1
- || !syms || syms == (void *)-1) {
- fatal("Could not load strings and symbol table from %s\n",
- modpath);
- }
-
- /* Now establish which modules we need */
- for (i = 0; i < size / sizeof(syms[0]); i++) {
- if (syms[i].st_shndx == SHN_UNDEF) {
- /* Look for symbol */
- const char *name = strings + syms[i].st_name;
-
- if (strcmp(name, "") == 0)
- continue;
-
- /* Did this pull in a new module? */
- if (need_symbol(order, name, modules,
- verbose ? modpath : NULL))
- needed = 1;
- }
- }
- close(fd);
- return needed;
-}
-
-static struct mod_ops mod64_ops = {
- .load_section = load_section64,
- .map_exports = map_exports64,
- .export_name_cmp = export_name_cmp64,
- .add_module = add_module64,
- .get_deps = get_deps64,
-};
diff -u -r --new-file module-init-tools-0.8/mod_types.h module-init-tools-0.9.ajr/mod_types.h
--- module-init-tools-0.8/mod_types.h 2002-11-13 18:14:41.000000000 -0800
+++ module-init-tools-0.9.ajr/mod_types.h 2002-11-21 05:13:16.000000000 -0800
@@ -1,65 +1 @@
-struct kernel_symbol32 {
- char value[4];
- char name[64 - 4];
-};
-
-struct kernel_symbol64 {
- char value[8];
- char name[64 - 8];
-};
-
-/* All the modules kept in this list */
-struct module
-{
- struct module *next;
-
- /* mmaped export symbols area */
- unsigned int num_exports;
- union {
- struct kernel_symbol32 *exports32;
- struct kernel_symbol64 *exports64;
- void *ptr;
- } u;
-
- /* What order it has to be loaded (0 = never). */
- unsigned int order;
-
- /* full path name */
- char name[0];
-};
-
-struct alias
-{
- struct alias *next;
- /* One of these two is set. */
- struct module *module;
- struct alias *alias;
- /* Line in config where this was defined */
- int config_line;
- char name[0];
-};
-
-struct mod_ops {
- struct module *(*add_module)(int fd, struct module *new,
- struct module *last,
- struct alias **aliases);
- void *(*load_section)(int fd, unsigned long shdroff,
- unsigned int num_secs,
- unsigned int secnamesec,
- const char *secname,
- unsigned long *size);
- void *(*map_exports)(int fd,
- unsigned long shdroff,
- unsigned int num_secs,
- unsigned int secnamesec,
- const char *name,
- unsigned int *num_exports);
- int (*export_name_cmp)(struct module *m, int index, const char *name);
- int (*get_deps)(unsigned int order,
- const char *dirname,
- const char *modname,
- struct module *modules,
- int verbose);
-};
-
#define MODULE_EXTENSION ".o"
diff -u -r --new-file module-init-tools-0.8/modprobe.c module-init-tools-0.9.ajr/modprobe.c
--- module-init-tools-0.8/modprobe.c 2002-11-20 14:30:32.000000000 -0800
+++ module-init-tools-0.9.ajr/modprobe.c 2002-11-21 05:37:16.000000000 -0800
@@ -39,11 +39,21 @@
#include "mod_types.h"
-#define MODULE_DIR "/lib/modules/%s/kernel/"
+struct module_list;
-/* We decide when we hit the first module whether we are 32 or 64-bit,
- and set this. */
-static struct mod_ops *mops;
+struct module {
+ struct module *next;
+ struct module_list *dependencies;
+ enum { NOT_LOADED = 0, BEING_LOADED, LOADED } state;
+ char filename[0];
+};
+
+struct module_list {
+ struct module *module;
+ struct module_list *next;
+};
+
+#define MODULE_DIR "/lib/modules"
static void fatal(const char *fmt, ...)
__attribute__ ((noreturn, format (printf, 1, 2)));
@@ -75,20 +85,16 @@
va_end(arglist);
}
-static struct alias *add_aliases(int fd,
- unsigned long shdroff,
- unsigned int num_secs,
- unsigned int secnamesec,
- struct module *mod,
- struct alias *last);
-
-static int need_symbol(unsigned int order,
- const char *name,
- struct module *modules,
- const char *modname);
+static void *do_nofail(void *ptr, const char *file, int line, const char *expr)
+{
+ if (!ptr) {
+ fatal("Memory allocation failure %s line %d: %s.\n",
+ file, line, expr);
+ }
+ return ptr;
+}
-#include "mod32.c"
-#include "mod64.c"
+#define NOFAIL(ptr) do_nofail((ptr), __FILE__, __LINE__, #ptr)
static void print_usage(const char *progname)
{
@@ -98,185 +104,122 @@
exit(1);
}
-static int ends_in(const char *name, const char *ext)
+static int fgetc_wrapped(FILE *file)
{
- unsigned int namelen, extlen, i;
-
- /* Grab lengths */
- namelen = strlen(name);
- extlen = strlen(ext);
-
- if (namelen < extlen) return 0;
-
- /* Look backwards */
- for (i = 0; i < extlen; i++)
- if (name[namelen - i] != ext[extlen - i]) return 0;
-
- return 1;
+ for (;;) {
+ int ch = fgetc(file);
+ if (ch != '\\')
+ return ch;
+ ch = fgetc(file);
+ if (ch != '\n')
+ return ch;
+ }
}
-/* FIXME: Loop detect. */
-static struct alias *find_alias(const char *name, struct alias *aliases)
-{
- struct alias *i;
-
- for (i = aliases; i; i = i->next)
- if (fnmatch(i->name, name, 0) == 0) {
- /* Chase down alias to aliases */
- while (i->alias)
- i = i->alias;
- return i;
+static char *getline_wrapped(FILE *file)
+{
+ int size = 1024;
+ int i = 0;
+ char *buf = NOFAIL(malloc(size));
+ for(;;) {
+ int ch = fgetc_wrapped(file);
+ if (i == size) {
+ size *= 2;
+ buf = NOFAIL(realloc(buf, size));
}
-
- return NULL;
+ if (ch < 0 || ch == '\n') {
+ if (ch < 0 && i == 0) {
+ free(buf);
+ return NULL;
+ }
+ buf[i] = '\0';
+ return NOFAIL(realloc(buf, i+1));
+ }
+ buf[i++] = ch;
+ }
}
-static struct alias *add_alias(struct alias *last,
- const char *aliasname,
- struct module *mod,
- struct alias *alias,
- int linenum)
-{
- struct alias *newalias;
-
- newalias = malloc(sizeof *newalias + strlen(aliasname) + 1);
- strcpy(newalias->name, aliasname);
- newalias->config_line = linenum;
- newalias->module = mod;
- newalias->alias = alias;
+struct module *modules; /* = NULL */
- newalias->next = last;
- return newalias;
-}
-
-static struct alias *add_aliases(int fd,
- unsigned long shdroff,
- unsigned int num_secs,
- unsigned int secnamesec,
- struct module *mod,
- struct alias *last)
+struct module *get_module(char *filename, int namelen)
{
- char *aliases;
- unsigned long size, i;
-
- aliases = mops->load_section(fd, shdroff, num_secs, secnamesec,
- ".modalias", &size);
- if (aliases == (void *)-1) {
- warn("Error loading aliases from module %s\n", mod->name);
- return last;
+ struct module *mod;
+ for (mod = modules; mod; mod = mod->next) {
+ if (strlen(mod->filename) == namelen &&
+ memcmp(mod->filename, filename, namelen) == 0)
+ return mod;
}
- if (aliases) {
- for (i = 0; i < size; i += strlen(aliases+i)+1)
- last = add_alias(last, aliases+i, mod, NULL, 0);
- free(aliases);
- }
- return last;
+ /* No match. Make a new module. */
+ mod = NOFAIL(malloc(sizeof(struct module) + namelen + 1));
+ memset(mod, 0, sizeof(struct module));
+ memcpy(mod->filename, filename, namelen);
+ mod->filename[namelen] = '\0';
+ mod->next = modules;
+ modules = mod;
+ return mod;
}
-static struct module *add_module(const char *dirname, const char *entry,
- struct module *last, struct alias **aliases)
+static void add_modules_dep_line(char *line, const char *start_name,
+ struct module **start)
{
- int fd;
- struct module *new;
- char pathname[strlen(dirname) + strlen(entry) + 1];
+ struct module_list *dep;
+ char *dep_start;
+ struct module *mod, *dep_mod;
+ char *ptr;
+ int len;
+ char *modname;
- new = malloc(sizeof(*new) + strlen(entry) + 1);
- strcpy(new->name, entry);
- /* Truncate extension */
- new->name[strlen(new->name) - strlen(MODULE_EXTENSION)] = '\0';
- new->order = 0;
- new->next = last;
+ ptr = index(line, ':');
+ if (ptr == NULL || line[0] == '#')
+ return;
- sprintf(pathname, "%s%s", dirname, entry);
- fd = open(pathname, O_RDONLY);
- if (fd < 0) {
- warn("Can't read module %s: %s\n", pathname, strerror(errno));
- free(new);
- return last;
- }
+ mod = get_module(line, ptr - line);
- /* First call initializes this. */
- if (!mops) {
- /* "\177ELF" <byte> where byte = 001 for 32-bit, 002 for 64 */
- char ident[EI_NIDENT];
+ modname = rindex(mod->filename, '/') + 1;
+ len = strlen(modname) - sizeof(MODULE_EXTENSION) + 1;
- if (read(fd, ident, EI_NIDENT) != EI_NIDENT) {
- warn("Can't read module %s elf identifier: %s\n",
- pathname, strerror(errno));
- free(new);
- return last;
- }
- switch (ident[EI_CLASS]) {
- case ELFCLASS32:
- mops = &mod32_ops;
- break;
- case ELFCLASS64:
- mops = &mod64_ops;
+ if (len == strlen(start_name) && !strncmp(modname, start_name, len))
+ *start = mod;
+
+ ptr++;
+ for(;;) {
+ ptr += strspn(ptr, " \t");
+ if (*ptr == '\0')
break;
- default:
- warn("Module %s has elf unknown identifier %i\n",
- pathname, ident[EI_CLASS]);
- free(new);
- return last;
- }
- lseek(fd, 0, SEEK_SET);
+ dep_start = ptr;
+ ptr += strcspn(ptr, " \t");
+ dep_mod = get_module(dep_start, ptr - dep_start);
+ fflush(stdout);
+ dep = NOFAIL(malloc(sizeof(*dep)));
+ dep->module = dep_mod;
+ dep->next = mod->dependencies;
+ mod->dependencies = dep;
}
-
- return mops->add_module(fd, new, last, aliases);
}
-static struct module *load_all_modules(const char *dirname,
- struct alias **aliases)
+static void load_all_modules(const char *dirname,
+ const char *start_name,
+ struct module **start)
{
- struct module *mods = NULL;
- struct dirent *dirent;
- DIR *dir;
+ char modules_dep_name[strlen(dirname) + sizeof("modules.dep") + 1];
+ char *line;
+ FILE *modules_dep;
- dir = opendir(dirname);
- if (dir) {
- while ((dirent = readdir(dir)) != NULL) {
- /* Is it a .o file? */
- if (ends_in(dirent->d_name, MODULE_EXTENSION))
- mods = add_module(dirname, dirent->d_name,
- mods, aliases);
- }
- closedir(dir);
+ *start = NULL;
+ sprintf(modules_dep_name, "%s/%s", dirname, "modules.dep");
+ modules_dep = fopen(modules_dep_name, "r");
+ if (!modules_dep) {
+ perror(modules_dep_name);
+ exit(1);
}
- return mods;
-}
-static int need_symbol(unsigned int order,
- const char *name,
- struct module *modules,
- const char *modname)
-{
- struct module *m;
- struct module *found = NULL;
-
- for (m = modules; m; m = m->next) {
- unsigned int i;
- for (i = 0; i < m->num_exports; i++) {
- if (mops->export_name_cmp(m, i, name) == 0) {
- if (found) {
- warn("%s supplied by %s and %s:"
- " picking neither\n",
- name, m->name, found->name);
- /* Noone chosen */
- return 0;
- }
- if (modname)
- printf("%s needs %s: found in %s\n",
- modname, name, m->name);
- found = m;
- /* If we didn't need to load it
- already, we do now. */
- found->order = order;
- }
- }
+ while((line = getline_wrapped(modules_dep)) != NULL) {
+ add_modules_dep_line(line, start_name, start);
+ free(line);
}
- if (found) return 1;
- else return 0;
+
+ fclose(modules_dep);
}
/* We use error numbers in a loose translation... */
@@ -292,308 +235,150 @@
}
}
+static int
+module_in_kernel(const char *modname)
+{
+ FILE *proc_modules;
+ char *line;
+ const int modname_len = strlen(modname);
+
+ proc_modules = fopen("/proc/modules", "r");
+ if (proc_modules == NULL)
+ fatal("Error reading /proc/modules: %s\n", strerror(errno));
+
+ while ((line = getline_wrapped(proc_modules)) != NULL) {
+ if (strncmp(line, modname, modname_len) == 0 &&
+ isspace(line[modname_len])) {
+ free(line);
+ fclose(proc_modules);
+ return 1;
+ }
+ free(line);
+ }
+ fclose(proc_modules);
+ return 0;
+}
+
/* Actually do the insert. */
-static void insmod(const char *dirname,
- const char *filename,
- const char *options,
- int dont_fail)
+static void insmod(struct module *mod, const char *options, int dont_fail,
+ struct module_list *caller)
{
int fd, ret;
struct stat st;
unsigned long len;
void *map;
- char modpath[strlen(dirname) + strlen(filename)
- + sizeof(MODULE_EXTENSION)];
+ struct module_list *dep;
+ unsigned int i;
+ char modname[strlen(strrchr(mod->filename, '/'))];
+ struct module_list call_history, *modlist;
+
+ if (mod->state == LOADED)
+ return;
+
+ call_history.next = caller;
+ call_history.module = mod;
+
+ if (mod->state == BEING_LOADED) {
+ fprintf (stderr, "FATAL: recursive dependency loop:\n");
+ modlist = &call_history;
+ do {
+ fprintf(stderr, "\t%s\n", modlist->module->filename);
+ modlist = modlist->next;
+ } while (modlist != NULL);
+ exit(1);
+ }
- /* FIXME: Look in module for name. --RR */
- sprintf(modpath, "%s%s%s", dirname, filename, MODULE_EXTENSION);
+ mod->state = BEING_LOADED;
+
+ for(dep = mod->dependencies; dep != NULL; dep = dep->next)
+ insmod(dep->module, options, 0, &call_history);
+
+ /* If we fail to load after this piont, we abort the whole program. */
+ mod->state = LOADED;
/* Now, it may already be loaded: check /proc/modules */
- fd = open("/proc/modules", O_RDONLY);
- if (fd < 0) {
- warn("Cannot open /proc/modules:"
- " assuming no modules loaded.\n");
- } else {
- char *buf;
- unsigned int fill, size = 1024;
-
- buf = malloc(size+1);
- buf[0] = '\n';
- fill = 1;
- while ((ret = read(fd, buf+fill, size - fill)) > 0) {
- size *= 2;
- buf = realloc(buf, size+1);
- fill += ret;
- }
- if (ret < 0)
- fatal("Error reading /proc/modules: %s\n",
- strerror(errno));
- else {
- char *ptr;
- unsigned int i;
- char name_with_ret[strlen(strrchr(modpath, '/')) + 2];
-
- buf[fill+1] = '\0';
- /* Must appear at start of line. */
- name_with_ret[0] = '\n';
- strcpy(name_with_ret + 1, strrchr(modpath, '/') + 1);
+ strcpy(modname, strrchr(mod->filename, '/') + 1);
- /* Convert to underscores */
- for (i = 0; name_with_ret[i]; i++)
- if (name_with_ret[i] == '-')
- name_with_ret[i] = '_';
-
- for (ptr = buf;
- (ptr = strstr(ptr, name_with_ret)) != NULL;
- ptr++) {
- if (!isspace(ptr[strlen(name_with_ret)]))
- continue;
- /* Found: don't try to load again */
- if (dont_fail)
- fatal("Module %s already loaded\n",
- name_with_ret+1);
- close(fd);
- free(buf);
- return;
- }
- }
- close(fd);
- free(buf);
- }
- close(fd);
+ /* Convert to underscores */
+ for (i = 0; modname[i]; i++)
+ if (modname[i] == '-')
+ modname[i] = '_';
+
+ modname[strlen(modname) - sizeof(MODULE_EXTENSION) + 1] = '\0';
+ if (module_in_kernel(modname))
+ return;
- fd = open(modpath, O_RDONLY);
+ fd = open(mod->filename, O_RDONLY);
if (fd < 0)
- fatal("Could not open `%s': %s\n", modpath, strerror(errno));
+ fatal("Could not open `%s': %s\n", mod->filename, strerror(errno));
fstat(fd, &st);
len = st.st_size;
map = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
if (map == MAP_FAILED)
- fatal("Can't map `%s': %s\n", modpath, strerror(errno));
+ fatal("Can't map `%s': %s\n", mod->filename, strerror(errno));
- ret = syscall(__NR_init_module, filename, map, len, options);
+ ret = syscall(__NR_init_module, modname, map, len, options);
if (ret != 0) {
if (dont_fail)
- fatal("Error inserting %s: %s\n",
- modpath, moderror(errno));
+ fatal("Error inserting %s (%s): %s\n",
+ modname, mod->filename, moderror(errno));
else
- warn("Error inserting %s: %s\n",
- modpath, moderror(errno));
+ warn("Error inserting %s (%s): %s\n",
+ modname, mod->filename, moderror(errno));
}
close(fd);
}
-/* Read one line into the buffer */
-static char *read_line(FILE *f)
-{
- int size = 80;
- char *result = malloc(size);
-
- result[0] = '\0';
- while (fgets(result + strlen(result), size - strlen(result), f)) {
- char *nl = strchr(result, '\n');
- if (nl) {
- *nl = '\0';
- return result;
- }
- size *= 2;
- result = realloc(result, size);
- }
- if (strlen(result)) {
- warn("Unexpected error reading config file: %s\n",
- strerror(errno));
- return result;
- }
- free(result);
- return NULL;
-}
-
-static struct module *find_module(const char *name, struct module *modules)
-{
- struct module *m;
-
- for (m = modules; m; m = m->next)
- if (strcmp(name, m->name) == 0)
- return m;
- return NULL;
-}
-
-static char *get_word(const char **line)
+static char *strsep_skipspace(char **string, char *delim)
{
- size_t len;
- char *word = NULL;
-
- *line += strspn(*line, "\t ");
- len = strcspn(*line, "\t ");
- if (**line) {
- word = strdup(*line);
- word[len] = '\0';
- }
- *line += len;
-
- return word;
-}
-
-/* alias newname oldname */
-static struct alias *parse_alias(struct alias *last, const char *line,
- int linenum,
- struct module *modules)
-{
- char *newname, *oldname;
- struct alias *aliasto;
- struct module *moduleto = NULL;
-
- newname = get_word(&line);
- if (!newname) {
- warn("Config line %i missing first arg\n", linenum);
- return last;
- }
- oldname = get_word(&line);
- if (!oldname) {
- warn("Config line %i missing second arg\n", linenum);
- free(newname);
- return last;
- }
-
- aliasto = find_alias(oldname, last);
- if (aliasto || (moduleto = find_module(oldname, modules)))
- last = add_alias(last, newname, moduleto, aliasto, linenum);
- else
- warn("Config line %i aliases to unknown module %s\n",
- linenum, oldname);
-
- free(oldname);
- free(newname);
- return last;
-}
-
-static int keyword(const char *line, const char *keyword)
-{
- size_t len = strcspn(line, "\t ");
-
- if (len == strlen(keyword)
- && memcmp(line, keyword, len) == 0)
- return 1;
- return 0;
+ *string += strspn(*string, delim);
+ return strsep(string, delim);
}
/* Simple format, ignore lines starting with #, one command per line */
-static void load_config_file(const char *filename, int mustload,
- struct module *modules,
- struct alias **aliases)
+static char *get_alias(const char *filename, int mustload, char *name)
{
FILE *cfile;
char *line;
- int linenum = 1;
+ char *result = NULL;
cfile = fopen(filename, "r");
if (!cfile) {
if (mustload)
fatal("Failed to open config file %s: %s\n",
filename, strerror(errno));
- return;
- }
-
- while ((line = read_line(cfile)) != NULL) {
- size_t len;
- len = strspn(line, "\t ");
- /* Comment or blank? */
- if (line[len] == '#' || line[len] == '\0')
- goto next;
- else if (keyword(line+len, "alias"))
- *aliases = parse_alias(*aliases, line+len+strlen("alias"),
- linenum, modules);
- else
- fatal("Unknown line %s in config file\n", line);
- next:
- free(line);
- linenum++;
+ return NOFAIL(strdup(name));
}
-}
-static char *resolve_alias(const char *name,
- struct module *modules,
- struct alias *aliases)
-{
- struct module *m;
- struct alias *a;
+ while ((line = getline_wrapped(cfile)) != NULL) {
+ char *ptr = line;
+ char *cmd = strsep_skipspace(&ptr, "\t ");
- a = find_alias(name, aliases);
- if (a)
- return a->module->name;
+ if (cmd == NULL)
+ continue;
- m = find_module(name, modules);
- if (m)
- return m->name;
+ if (strcmp(cmd, "alias") == 0) {
+ char *fakename = strsep_skipspace(&ptr, "\t ");
+ char *realname = strsep_skipspace(&ptr, "\t ");
- fatal("Could not find a module or alias named %s\n",
- name);
-}
-
-static void load_symbol(const char *dirname,
- const char *symname,
- struct module *modules,
- const char *options,
- int verbose)
-{
- struct module *i;
-
- if (!need_symbol(1, symname, modules, verbose?"symbol request":NULL))
- fatal("Could not find module with symbol %s\n", symname);
-
- for (i = modules; i; i = i->next) {
- if (i->order) {
- if (verbose) printf("Loading %s\n", i->name);
- insmod(dirname, i->name, options, 1);
- }
- }
-}
-
-static void load(const char *dirname, const char *modname,
- struct module *modules,
- struct alias *aliases,
- const char *options,
- int verbose)
-{
- unsigned int order;
- struct module *i;
- char *realname;
-
- realname = resolve_alias(modname, modules, aliases);
-
- order = 1;
- if (mops->get_deps(order, dirname, realname, modules, verbose)) {
- /* We need some other modules. */
- int more_needed;
-
- do {
- more_needed = 0;
- for (i = modules; i; i = i->next) {
- if (i->order == order) {
- if (mops->get_deps(order + 1, dirname,
- i->name,
- modules, verbose))
- more_needed = 1;
- }
- }
- order++;
- } while (more_needed);
- }
-
- /* Now, walk back through orders, loading */
- for (; order > 0; order--) {
- for (i = modules; i; i = i->next) {
- if (i->order == order) {
- if (verbose) printf("Loading %s\n", i->name);
- insmod(dirname, i->name, "", 0);
+ if (fakename && realname && !strcmp(fakename, name)) {
+ result = NOFAIL(strdup(realname));
+ free(line);
+ break;
}
}
+ else if (strcmp(cmd, "include") == 0) {
+ filename = strsep(&ptr, "\t ");
+ result = get_alias(filename, 0, name);
+ if (result)
+ break;
+ }
+ free(line);
}
- if (verbose)
- printf("Loading %s%s%s\n", dirname, realname,MODULE_EXTENSION);
- insmod(dirname, realname, options, 1);
+ fclose(cfile);
+ return result;
}
static struct option options[] = { { "verbose", 0, NULL, 'v' },
@@ -608,10 +393,10 @@
struct utsname buf;
int opt;
int verbose = 0;
- struct alias *aliases = NULL;
- struct module *modules;
const char *config = NULL;
- char *dirname, *optstring = strdup("");
+ char *dirname, *optstring = NOFAIL(strdup(""));
+ char *modname;
+ struct module *start;
try_old_version("modprobe", argv);
@@ -651,22 +436,23 @@
}
uname(&buf);
- dirname = malloc(strlen(buf.release) + sizeof(MODULE_DIR));
- sprintf(dirname, MODULE_DIR, buf.release);
+ dirname = malloc(strlen(buf.release) + sizeof(MODULE_DIR) + 1);
+ sprintf(dirname, "%s/%s", MODULE_DIR, buf.release);
- /* Suck up the modules */
- modules = load_all_modules(dirname, &aliases);
+ modname = get_alias(config ?: DEFAULT_CONFIG, config ? 1 : 0,
+ argv[optind]);
- /* No config file specified? Don't worry if it doesn't exist. */
- load_config_file(config ?: DEFAULT_CONFIG, config ? 1 : 0,
- modules, &aliases);
-
- /* Special case for "symbol:" */
- if (strncmp(argv[optind], "symbol:", strlen("symbol:")) == 0)
- load_symbol(dirname, argv[optind] + strlen("symbol:"),
- modules, optstring, verbose);
- else
- load(dirname, argv[optind], modules, aliases, optstring,
- verbose);
- exit(0);
+ if (modname == NULL)
+ modname = argv[optind];
+
+ load_all_modules(dirname, modname, &start);
+ if (start == NULL) {
+ fprintf (stderr, "Module %s not found.\n", modname);
+ exit(1);
+ }
+
+ insmod(start, optstring, 1, NULL);
+
+ /* free(modname); -- Comment out. We're just going to exit. */
+ return 0;
}
[-- Attachment #3: dwmw2-module-init-tools.patch --]
[-- Type: text/plain, Size: 2292 bytes --]
diff -ur module-init-tools-0.7/CHANGES module-init-tools-0.8/CHANGES
--- module-init-tools-0.7/CHANGES Thu Nov 14 02:09:28 2002
+++ module-init-tools-0.8/CHANGES Wed Nov 20 13:32:39 2002
@@ -1,3 +1,4 @@
+o Add module name argument to sys_init_module()
o 64/32 bit autodetection thanks to Dave Miller
o Preliminary alias support.
o Very primitive /etc/modprobe.conf support
diff -ur module-init-tools-0.7/insmod.c module-init-tools-0.8/insmod.c
--- module-init-tools-0.7/insmod.c Wed Nov 13 22:33:32 2002
+++ module-init-tools-0.8/insmod.c Wed Nov 20 13:32:05 2002
@@ -28,6 +28,7 @@
#include <errno.h>
#include <asm/unistd.h>
+#include "mod_types.h"
#include "backwards_compat.c"
static void print_usage(const char *progname)
@@ -62,15 +63,22 @@
unsigned long len;
void *map;
char *filename, *options = strdup("");
+ char *modname = NULL;
try_old_version("insmod", argv);
- filename = argv[1];
+ i = 1;
+ if (argc > 3 && !strcmp(argv[1], "-o")) {
+ modname = argv[2];
+ i = 3;
+ }
+
+ filename = argv[i++];
if (!filename)
print_usage(argv[0]);
/* Rest is options */
- for (i = 2; i < argc; i++) {
+ for ( ; i < argc; i++) {
options = realloc(options,
strlen(options) + 2 + strlen(argv[i]) + 2);
/* Spaces handled by "" pairs, but no way of escaping
@@ -99,7 +107,20 @@
exit(1);
}
- ret = syscall(__NR_init_module, map, len, options);
+ if (!modname) {
+ char *ext;
+ modname = strrchr(filename, '/');
+ if (modname)
+ modname++;
+ else
+ modname = filename;
+
+ ext = strrchr(modname, '.');
+ if (ext && !strcmp(ext, MODULE_EXTENSION))
+ *ext = 0;
+ }
+
+ ret = syscall(__NR_init_module, modname, map, len, options);
if (ret != 0) {
fprintf(stderr, "Error inserting `%s': %li %s\n",
filename, ret, moderror(errno));
diff -ur module-init-tools-0.7/modprobe.c module-init-tools-0.8/modprobe.c
--- module-init-tools-0.7/modprobe.c Thu Nov 14 02:29:24 2002
+++ module-init-tools-0.8/modprobe.c Wed Nov 20 13:32:00 2002
@@ -373,7 +373,7 @@
if (map == MAP_FAILED)
fatal("Can't map `%s': %s\n", modpath, strerror(errno));
- ret = syscall(__NR_init_module, map, len, options);
+ ret = syscall(__NR_init_module, filename, map, len, options);
if (ret != 0) {
if (dont_fail)
fatal("Error inserting %s: %s\n",
[-- Attachment #4: dwmw2-kernel.patch --]
[-- Type: text/plain, Size: 5448 bytes --]
--- 1.17/include/linux/init.h Sat Nov 9 04:08:33 2002
+++ edited/include/linux/init.h Wed Nov 20 10:48:28 2002
@@ -125,14 +125,6 @@
*/
#define module_exit(x) __exitcall(x);
-/**
- * no_module_init - code needs no initialization.
- *
- * The equivalent of declaring an empty init function which returns 0.
- * Every module must have exactly one module_init() or no_module_init
- * invocation. */
-#define no_module_init
-
#else /* MODULE */
/* Don't use these in modules, but some people do... */
@@ -144,10 +136,6 @@
#define device_initcall(fn) module_init(fn)
#define late_initcall(fn) module_init(fn)
-/* Each module knows its own name. */
-#define __DEFINE_MODULE_NAME \
- char __module_name[] __attribute__((section(".modulename"))) = \
- __stringify(KBUILD_MODNAME)
/* These macros create a dummy inline: gcc 2.9x does not count alias
as usage, hence the `unused function' warning when __init functions
@@ -155,14 +143,11 @@
both to kill the warning and check the type of the init/cleanup
function. */
-/* Each module must use one module_init(), or one no_module_init */
+/* Each module must use no more than one module_init() */
#define module_init(initfn) \
- __DEFINE_MODULE_NAME; \
static inline initcall_t __inittest(void) \
{ return initfn; } \
int __initfn(void) __attribute__((alias(#initfn)));
-
-#define no_module_init __DEFINE_MODULE_NAME
/* This is only required if you want to be unloadable. */
#define module_exit(exitfn) \
===== include/linux/module.h 1.25 vs edited =====
--- 1.25/include/linux/module.h Tue Nov 19 04:51:14 2002
+++ edited/include/linux/module.h Wed Nov 20 10:08:30 2002
@@ -297,8 +297,6 @@
/* Used as "int init_module(void) { ... }". Get funky to insert modname. */
#define init_module(voidarg) \
__initfn(void); \
- char __module_name[] __attribute__((section(".modulename"))) = \
- __stringify(KBUILD_MODNAME); \
int __initfn(void)
#define cleanup_module(voidarg) __exitfn(void)
#endif
===== kernel/module.c 1.25 vs edited =====
--- 1.25/kernel/module.c Tue Nov 19 04:51:14 2002
+++ edited/kernel/module.c Wed Nov 20 10:54:47 2002
@@ -800,15 +800,15 @@
}
/* Allocate and load the module */
-static struct module *load_module(void *umod,
+static struct module *load_module(const char *modname,
+ void *umod,
unsigned long len,
const char *uargs)
{
Elf_Ehdr *hdr;
Elf_Shdr *sechdrs;
char *secstrings;
- unsigned int i, symindex, exportindex, strindex, setupindex, exindex,
- modnameindex;
+ unsigned int i, symindex, exportindex, strindex, setupindex, exindex;
long arglen;
unsigned long common_length;
struct sizes sizes, used;
@@ -816,8 +816,8 @@
long err = 0;
void *ptr = NULL; /* Stops spurious gcc uninitialized warning */
- DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
- umod, len, uargs);
+ DEBUGP("load_module: modname=%p, umod=%p, len=%lu, uargs=%p\n",
+ modname, umod, len, uargs);
if (len < sizeof(*hdr))
return ERR_PTR(-ENOEXEC);
@@ -849,7 +849,7 @@
exportindex = setupindex = 0;
/* And these should exist, but gcc whinges if we don't init them */
- symindex = strindex = exindex = modnameindex = 0;
+ symindex = strindex = exindex = 0;
/* Find where important sections are */
for (i = 1; i < hdr->e_shnum; i++) {
@@ -857,11 +857,6 @@
/* Internal symbols */
DEBUGP("Symbol table in section %u\n", i);
symindex = i;
- } else if (strcmp(secstrings+sechdrs[i].sh_name, ".modulename")
- == 0) {
- /* This module's name */
- DEBUGP("Module name in section %u\n", i);
- modnameindex = i;
} else if (strcmp(secstrings+sechdrs[i].sh_name, "__ksymtab")
== 0) {
/* Exported symbols. */
@@ -895,12 +890,6 @@
#endif
}
- if (!modnameindex) {
- DEBUGP("Module has no name!\n");
- err = -ENOEXEC;
- goto free_hdr;
- }
-
/* Now allocate space for the module proper, and copy name and args. */
err = strlen_user(uargs);
if (err < 0)
@@ -917,8 +906,9 @@
err = -EFAULT;
goto free_mod;
}
- strncpy(mod->name, (char *)hdr + sechdrs[modnameindex].sh_offset,
- sizeof(mod->name)-1);
+ strncpy_from_user(mod->name, modname, sizeof(mod->name)-1);
+ /* strncpy doesn't NUL-terminate when it runs out of space */
+ mod->name[sizeof(mod->name)-1] = 0;
if (find_module(mod->name)) {
err = -EEXIST;
@@ -1058,7 +1048,8 @@
/* This is where the real work happens */
asmlinkage long
-sys_init_module(void *umod,
+sys_init_module(const char *modname,
+ void *umod,
unsigned long len,
const char *uargs)
{
@@ -1074,7 +1065,7 @@
return -EINTR;
/* Do all the hard work */
- mod = load_module(umod, len, uargs);
+ mod = load_module(modname, umod, len, uargs);
if (IS_ERR(mod)) {
up(&module_mutex);
return PTR_ERR(mod);
===== lib/zlib_deflate/deflate_syms.c 1.2 vs edited =====
--- 1.2/lib/zlib_deflate/deflate_syms.c Sat Nov 9 04:08:33 2002
+++ edited/lib/zlib_deflate/deflate_syms.c Wed Nov 20 10:45:43 2002
@@ -19,5 +19,3 @@
EXPORT_SYMBOL(zlib_deflateCopy);
EXPORT_SYMBOL(zlib_deflateParams);
MODULE_LICENSE("GPL");
-
-no_module_init;
===== lib/zlib_inflate/inflate_syms.c 1.3 vs edited =====
--- 1.3/lib/zlib_inflate/inflate_syms.c Sat Nov 9 04:08:33 2002
+++ edited/lib/zlib_inflate/inflate_syms.c Wed Nov 20 10:51:40 2002
@@ -20,5 +20,3 @@
EXPORT_SYMBOL(zlib_inflateSyncPoint);
EXPORT_SYMBOL(zlib_inflateIncomp);
MODULE_LICENSE("GPL");
-
-no_module_init;
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2002-11-27 23:09 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <200211252254.OAA04288@freya.yggdrasil.com>
2002-11-26 0:45 ` Patch?: module-init-tools/modprobe.c - use modules.dep Rusty Russell
2002-11-26 7:40 ` [PATCH] Symbol name prefixes (e.g., `_') with the new module loader Miles Bader
2002-11-26 19:02 Patch?: module-init-tools/modprobe.c - use modules.dep Adam J. Richter
2002-11-27 5:02 ` Rusty Russell
2002-11-27 23:17 ` Keith Owens
-- strict thread matches above, loose matches on Subject: below --
2002-11-25 19:16 Adam J. Richter
2002-11-25 23:34 ` Rusty Russell
2002-11-21 15:39 Adam J. Richter
2002-11-25 5:47 ` Rusty Russell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®