3 # ModDepTab -- encapsulate modprobe(8)
4 # Copyright (C) 2005 Erik van Konijnenburg
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 # Most important routine is resolve(), which returns a list of
21 # modules with dependencies resolved.
23 # For every module, we have a list of prerequisite modules;
24 # these prerequisites are in no particular order: the prerequisites
25 # may have dependencies among themselves that are not satisfied
26 # by the order in the list.
28 # This emulates modprobe(8) by interpreting /lib/modules/2.6.x/modules.dep.
30 # - characters are bytes, no messing with utf-8.
31 # - backslash at end of line merges lines
32 # - other \x get replaced by x
33 # - ^\s*# lines are ignored
34 # - lines without : are ignored.
35 # This means "aap: noot.#7" is a valid dependency.
36 # The backslash interpretation is mostly for modprobe.conf;
37 # depmod does not generate it.
39 # Modprobe determines module name by dropping everything after dot:
40 # "/lib/noot.#7" is module "noot". We'll adopt the same policy.
42 # Note that depmod only grabs modules ending in .ko or .ko.gz;
43 # we'll issue a warning if a module has a different suffix.
45 # Note that modprobe does not discriminate against modules outside
46 # /lib/modules: if it's listed in modules.dep, it's a valid module.
48 # Note that redhat has a convention that modules in .../update take
49 # precedence over other modules with the same name. Depmod implements
50 # this by not putting modules that are overridden in modules.dep.
51 # Thus modprobe and yaird need no special action to support that convention.
53 # The logic modprobe uses to determine which modules to load:
54 # - replace hyphens with underscore
55 # - read config specified on command line,
56 # OR modprobe.conf OR modprobe.d, only first one found.
57 # Remember all "install" and "option" directives,
58 # rewrite module name if an alias matches
59 # - if no alias found and the name is of the form 'symbol:xxx':
60 # look in modules.symbols to resolve to a module name
62 # make a list of modules to load, based on modules.dep
64 # make a list of modules to load, based on modules.dep
65 # if that turned up no modules AND there was no install cmd:
66 # - look in modules.aliases to resolve to modulename
67 # - make a list of modules to load, based on modules.dep
68 # - if the list to load is empty AND there was no install command:
71 # - recurse over the module list, most basic stuff first, doing:
72 # - if there is a command for this module name:
77 # We probably should replace this perl module with parsing the
78 # output of modprobe --verbose --dry-run --show-depends --set-version,
79 # but that requires changes in the calling modules, and there's discussion
80 # of adding blacklist support to modprobe, so for now, let's not.
92 my $modDepTab = undef;
93 my $modDepList = undef;
96 if (defined ($modDepTab)) {
100 my $name = Conf::get('modDep');
101 if (! open (IN, "<", "$name")) {
102 Base::fatal ("can't open $name");
105 while (defined (my $line = <IN>)) {
109 # it would be nice to ignore leading and trailing
110 # space, and to allow # comment at end of line.
111 # however, that's not how modprobe does it,
112 # so we shouldn't either.
113 next if $line =~ /^\s*#/;
115 if ($line =~ /^(.*):\s*(.*)$/) {
120 if ($key !~ /\.ko$/ && $key !~ /\.ko\.gz/) {
121 Base::warning ("$name:$lineNo: odd module name: $key");
127 my @fields = split (/\s+/, $val);
128 for my $i (0 .. $#fields) {
129 # strip pathname and extension from
130 # required modules, normalise underscore.
131 # dont complain about odd suffix.
132 $fields[$i] =~ s!.*/!!;
133 $fields[$i] =~ s!\..*$!!;
134 $fields[$i] =~ s!_!-!g;
137 my $conflict = $modDepTab->{$key};
138 if (defined ($conflict)) {
139 my $origin = $conflict->origin();
140 Base::warning ("$name:$lineNo: $key overrules earlier definition at $origin");
143 $modDepTab->{$key} = ModDep->new (
146 origin => "$name:$lineNo",
151 Base::warning ("$name:$lineNo: malformed line ignored");
156 Base::fatal ("could not read $name");
158 $modDepList = [ sort keys %{$modDepTab} ];
166 sub findByModnam ($) {
170 my $result = $modDepTab->{$module};
171 if (! defined ($result)) {
172 Base::fatal ("can't find dependencies for $module");
178 # return a copy of the list with prerequisite modules inserted
181 Base::debug ("resolving: " . join (',', @{$modList}) . '.');
183 resolve2 ($modList, $result);
184 Base::debug ("resolved to: " . join (',', @{$result}) . '.');
189 # resolve2 -- given a list of modules, that may have dependencies
190 # (even among themselves) and a list of modules that is in proper order
191 # to be loaded without unresolved dependencies,
192 # add everything from the first list (plus their dependencies)
193 # to the second list, without introducing duplicates.
197 my ($modList, $done) = @_;
198 OUTER: for my $module (@{$modList}) {
200 # Stuff that is compiled into the kernel cannot
201 # add or resolve dependencies, and obviously don't
202 # need to be loaded. Drop them from the list.
204 if (KConfig::isBuiltIn ($module)) {
208 # if the module is already there, don't add again
210 for my $d (@{$done}) {
216 # recursively add prerequisites
218 my $deps = ModDepTab::findByModnam($module);
219 if (! defined ($deps)) {
220 Base::fatal ("can't find dependencies for $module");
222 resolve2 ($deps->deps, $done);
226 push @{$done}, $module;