diff options
Diffstat (limited to 'perl-install/modules.pm')
| -rw-r--r-- | perl-install/modules.pm | 334 |
1 files changed, 84 insertions, 250 deletions
diff --git a/perl-install/modules.pm b/perl-install/modules.pm index 91b05fbbf..f9d382767 100644 --- a/perl-install/modules.pm +++ b/perl-install/modules.pm @@ -1,15 +1,13 @@ package modules; # $Id$ use strict; -use vars qw(%conf); use common; use detect_devices; use run_program; use log; use list_modules; - -%conf = (); +use modules::any_conf; sub modules_descriptions() { my $f = '/lib/modules/' . c::kernel_version() . '/modules.description'; @@ -40,66 +38,75 @@ $mappings_26_24{'uhci-hcd'} = 'usb-uhci'; sub mapping_24_26 { my ($modname) = @_; - c::kernel_version() =~ /^\Q2.6/ && $mappings_24_26{$modname} || $modname; + $mappings_24_26{$modname} || $modname; } sub mapping_26_24 { my ($modname) = @_; - c::kernel_version() =~ /^\Q2.6/ && $mappings_26_24{$modname} || $modname; + $mappings_26_24{$modname} || $modname; +} + +sub cond_mapping_24_26 { + my ($modname) = @_; + c::kernel_version() =~ /^\Q2.6/ && $mappings_24_26{$modname} || $modname; } #-############################################################################### #- module loading #-############################################################################### # handles dependencies -# eg: load('vfat', 'reiserfs', [ ne2k => 'io=0xXXX', 'dma=5' ]) -sub load { - #- keeping the order of modules - my %options; - my @l = map { - my ($name, @options) = ref($_) ? @$_ : $_; - $options{$name} = \@options; - dependencies_closure(mapping_24_26($name)); - } @_; - - @l = difference2([ uniq(@l) ], [ map { my $s = $_; $s =~ s/_/-/g; $s, $_ } loaded_modules() ]) or return; - - my $network_module = do { - my ($network_modules, $other) = partition { module2category($_) =~ m,network/(main|gigabit|usb|wireless), } @l; - if (@$network_modules > 1) { - # do it one by one - load($_) foreach @$network_modules; - load(@$other); - return; - } - $network_modules->[0]; - }; - my @network_devices = $network_module ? detect_devices::getNet() : (); - +sub load_raw { + my ($l, $h_options) = @_; if ($::testing) { - log::l("i would load module $_ (" . join(" ", @{$options{$_}}) . ")") foreach @l; - } elsif ($::isStandalone || $::move) { - run_program::run('/sbin/modprobe', $_, @{$options{$_}}) - or !run_program::run('/sbin/modprobe', '-n', $_) #- ignore missing modules - or die "insmod'ing module $_ failed" foreach @l; + log::l("i would load module $_ ($h_options->{$_})") foreach @$l; + } elsif ($::isInstall && !$::move) { + load_raw_install($l, $h_options); } else { - load_raw_install(\@l, \%options); + run_program::run('/sbin/modprobe', $_, split(' ', $h_options->{$_})) + or !run_program::run('/sbin/modprobe', '-n', $_) #- ignore missing modules + or die "insmod'ing module $_ failed" foreach @$l; } - sleep 2 if any { /^(usb-storage|mousedev|printer)$/ } @l; + sleep 2 if any { /^(usb-storage|mousedev|printer)$/ } @$l; +} +sub load_with_options { + my ($l, $h_options) = @_; + + my @l = map { + dependencies_closure(cond_mapping_24_26($_)); + } @$l; + + @l = remove_loaded_modules(@l) or return; + + load_raw(\@l, $h_options); +} +sub load { + my (@l) = @_; + load_with_options(\@l, {}); +} - if ($network_module) { - set_alias($_, $network_module) foreach difference2([ detect_devices::getNet() ], \@network_devices); +# eg: load_and_configure($modules_conf, 'vfat', 'reiserfs', [ ne2k => 'io=0xXXX', 'dma=5' ]) +sub load_and_configure { + my ($conf, $module, $o_options) = @_; + + my $category = module2category($module) || ''; + my $network_devices = $category =~ m!network/(main|gigabit|usb|wireless)! && [ detect_devices::getNet() ]; + + my @l = remove_loaded_modules(dependencies_closure(cond_mapping_24_26($module))) or return; + load_raw(\@l, { $module => $o_options }); + + if ($network_devices) { + $conf->set_alias($_, $module) foreach difference2([ detect_devices::getNet() ], $network_devices); } - @l = grep { - if (c::kernel_version() =~ /^\Q2.6/ && member($_, 'imm', 'ppa') - && ! -d "/proc/sys/dev/parport/parport0/devices/$_") { - log::l("$_ loaded but is not useful, removing"); - unload($_); - 0; - } else { 1 } - } @l; + if (c::kernel_version() =~ /^\Q2.6/ && member($module, 'imm', 'ppa') + && ! -d "/proc/sys/dev/parport/parport0/devices/$module") { + log::l("$module loaded but is not useful, removing"); + unload($module); + return; + } + + $conf->set_options($module, $o_options) if $o_options; - when_load($_, @{$options{$_}}) foreach @l; + when_load($conf, $module); } sub unload { @@ -111,11 +118,7 @@ sub unload { } sub load_category { - my ($category, $o_wait_message) = @_; - - #- probe_category returns the PCMCIA cards. It doesn't know they are already - #- loaded, so: - read_already_loaded(); + my ($conf, $category, $o_wait_message) = @_; my @try_modules = ( if_($category =~ /scsi/, @@ -130,7 +133,7 @@ sub load_category { ); grep { $o_wait_message->($_->{description}, $_->{driver}) if $o_wait_message; - eval { load([ $_->{driver}, if_($_->{options}, $_->{options}) ]) }; + eval { load_and_configure($conf, $_->{driver}, $_->{options}) }; $_->{error} = $@; $_->{try} = 1 if member($_->{driver}, 'hptraid', 'ohci1394'); #- don't warn when this fails @@ -166,184 +169,13 @@ sub probe_category { #-############################################################################### #- modules.conf functions #-############################################################################### -sub get_alias { - my ($alias) = @_; - $conf{$alias}{alias}; -} -sub get_probeall { - my ($alias) = @_; - $conf{$alias}{probeall}; -} -sub get_options { - my ($name) = @_; - $conf{$name}{options}; -} -sub set_options { - my ($name, $new_option) = @_; - log::l(qq(set option "$new_option" for module "$name")); - $conf{$name}{options} = $new_option; -} -sub get_parameters { - map { if_(/(.*)=(.*)/, $1 => $2) } split(' ', get_options($_[0])); -} -sub set_alias { - my ($alias, $module) = @_; - $module =~ /ignore/ and return; - /\Q$alias/ && $conf{$_}{alias} && $conf{$_}{alias} eq $module and return $_ foreach keys %conf; - log::l("adding alias $alias to $module"); - $conf{$alias}{alias} = $module; - $alias; -} -sub add_probeall { - my ($alias, $module) = @_; - - my $l = $conf{$alias}{probeall} ||= []; - @$l = uniq(@$l, $module); - log::l("setting probeall $alias to @$l"); -} -sub remove_probeall { - my ($alias, $module) = @_; - - my $l = $conf{$alias}{probeall} ||= []; - @$l = grep { $_ ne $module } @$l; - log::l("setting probeall $alias to @$l"); -} - -sub remove_alias { - my ($name) = @_; - log::l(qq(removing alias "$name")); - remove_alias_regexp("^$name\$"); -} - -sub remove_alias_regexp { - my ($aliased) = @_; - log::l(qq(removing all aliases that match "$aliased")); - foreach (keys %conf) { - delete $conf{$_}{alias} if /$aliased/; - } -} - -sub remove_alias_regexp_byname { - my ($name) = @_; - log::l(qq(removing all aliases which names match "$name")); - foreach (keys %conf) { - delete $conf{$_} if /$name/; - } -} - -sub remove_module { - my ($name) = @_; - remove_alias($name); - log::l("removing module $name"); - delete $conf{$name}; - 0; -} - -sub set_sound_slot { - my ($alias, $module) = @_; - if (my $old = $conf{$alias}{alias}) { - $conf{$old} and delete $conf{$old}{above}; - } - set_alias($alias, $module); - $conf{$module}{above} = 'snd-pcm-oss' if $module =~ /^snd-/; -} - -sub read_conf { - my ($file) = @_; - my %c; - - foreach (cat_($file)) { - next if /^\s*#/; - s/#.*$//; - - s/\b(snd-card-)/snd-/g; - s/\b(snd-via686|snd-via8233)\b/snd-via82xx/g; - - my ($type, $module, $val) = split(/\s+/, chomp_($_), 3) or next; - $val =~ s/\s+$//; - - $val = [ split ' ', $val ] if $type eq 'probeall'; - - $c{$module}{$type} = $val; - } - #- cheating here: not handling aliases of aliases - while (my ($_k, $v) = each %c) { - if (my $a = $v->{alias}) { - local $c{$a}{alias}; - delete $v->{probeall}; - add2hash($c{$a}, $v); - } - } - #- convert old aliases to new probeall - foreach my $name ('scsi_hostadapter', 'usb-interface') { - my @old_aliases = - map { $_->[0] } sort { $a->[1] <=> $b->[1] } - map { if_(/^$name(\d*)/ && $c{$_}{alias}, [ $_, $1 || 0 ]) } keys %c; - foreach my $alias (@old_aliases) { - push @{$c{$name}{probeall} ||= []}, delete $c{$alias}{alias}; - } - } - \%c; -} - -sub mergein_conf_raw { - my ($file) = @_; - my $modconfref = read_conf($file); - while (my ($key, $value) = each %$modconfref) { - $conf{$key}{alias} ||= $value->{alias}; - $conf{$key}{above} ||= $value->{above}; - $conf{$key}{options} = $value->{options} if $value->{options}; - push @{$conf{$key}{probeall} ||= []}, deref($value->{probeall}) if $value->{probeall}; - } -} -sub mergein_conf() { - my $file = "$::prefix/etc/modules.conf"; - mergein_conf_raw($file) if -r $file; -} - -sub write_conf() { - my $file = "$::prefix/etc/modules.conf"; - rename "$::prefix/etc/conf.modules", $file; #- make the switch to new name if needed - - #- Substitute new aliases in modules.conf (if config has changed) - substInFile { - my ($type, $module, $val) = split(/\s+/, chomp_($_), 3); - if ($type eq 'post-install' && $module eq 'supermount') { - #- remove the post-install supermount stuff. - $_ = ''; - } elsif ($type eq 'alias' && $module =~ /scsi_hostadapter|usb-interface/) { - #- remove old aliases which are replaced by probeall - $_ = ''; - } elsif ($type eq 'above' && !defined $conf{$module}{above}) { - $_ = ''; - } elsif ($type eq 'alias' && !defined $conf{$module}{alias}) { - $_ = ''; - } elsif ($conf{$module}{$type} && $conf{$module}{$type} ne $val) { - my $v = join(' ', uniq(deref($conf{$module}{$type}))); - $_ = "$type $module $v\n"; - } - } $file; - - my $written = read_conf($file); - - open(my $F, ">> $file") or die("cannot write module config file $file: $!\n"); - while (my ($mod, $h) = each %conf) { - while (my ($type, $v) = each %$h) { - my $v2 = join(' ', uniq(deref($v))); - print $F "$type $mod $v2\n" - if $v2 && !$written->{$mod}{$type}; - } - } - #- use module-init-tools script for the moment - run_program::rooted($::prefix, "/sbin/generate-modprobe.conf", ">", "/etc/modprobe.conf") if -e "$::prefix/etc/modprobe.conf"; - - write_preload_conf(); -} - -sub write_preload_conf() { +sub write_preload_conf { + my ($conf) = @_; my @l; - push @l, 'scsi_hostadapter' if !is_empty_array_ref($conf{scsi_hostadapter}{probeall}); - push @l, grep { detect_devices::matching_driver("^$_\$") } qw(bttv cx8800 saa7134); + push @l, 'scsi_hostadapter' if $conf->get_probeall('scsi_hostadapter'); + push @l, intersection([ qw(bttv cx8800 saa7134) ], + [ map { $_->{driver} } detect_devices::probeall() ]); + push @l, 'nvram' if cat_('/proc/bus/input/devices') =~ m!^N: Name="SynPS/2 Synaptics TouchPad"$!m; my @l_26 = @l; if (my ($agp) = probe_category('various/agpgart')) { push @l_26, $agp->{driver}; @@ -354,7 +186,7 @@ sub write_preload_conf() { sub append_to_modules_loaded_at_startup { my ($file, @l) = @_; - my $l = join '|', map { '^\s*'.$_.'\s*$' } @l; + my $l = join '|', map { '^\s*' . $_ . '\s*$' } @l; log::l("to put in $file ", join(", ", @l)); substInFile { @@ -370,8 +202,14 @@ sub append_to_modules_loaded_at_startup { sub loaded_modules() { map { /(\S+)/ } cat_("/proc/modules"); } -sub read_already_loaded() { - when_load($_) foreach reverse loaded_modules(); +sub remove_loaded_modules { + my (@l) = @_; + difference2([ uniq(@l) ], [ map { my $s = $_; $s =~ s/_/-/g; $s, $_ } loaded_modules() ]) +} + +sub read_already_loaded { + my ($conf) = @_; + when_load($conf, $_) foreach reverse loaded_modules(); } my $module_extension = c::kernel_version() =~ /^\Q2.4/ ? 'o' : 'ko'; @@ -382,41 +220,37 @@ sub name2file { } sub when_load { - my ($name, @options) = @_; - - $name = mapping_26_24($name); #- need to stay with 2.4 names, modutils will allow booting 2.4 and 2.6 - - $conf{$name}{options} = join " ", @options if @options; + my ($conf, $name) = @_; if (my $category = module2category($name)) { - when_load_category($name, $category); + when_load_category($conf, $name, $category); } - if (my $above = $conf{$name}{above}) { + if (my $above = $conf->get_above($name)) { load($above); #- eg: for snd-pcm-oss set by set_sound_slot() } } sub when_load_category { - my ($name, $category) = @_; + my ($conf, $name, $category) = @_; - if ($category =~ m,disk/(scsi|hardware_raid|usb|firewire),) { - add_probeall('scsi_hostadapter', $name); + if ($category =~ m,disk/(ide|scsi|hardware_raid|usb|firewire),) { + $conf->add_probeall('scsi_hostadapter', $name); eval { load('sd_mod') }; } elsif ($category eq 'bus/usb') { - add_probeall('usb-interface', $name); + $conf->add_probeall('usb-interface', $name); -f '/proc/bus/usb/devices' or eval { - require fs; fs::mount('/proc/bus/usb', '/proc/bus/usb', 'usbdevfs'); + require fs; fs::mount('none', '/proc/bus/usb', 'usbdevfs'); #- ensure keyboard is working, the kernel must do the job the BIOS was doing sleep 4; load("usbkbd", "keybdev") if detect_devices::usbKeyboards(); } } elsif ($category eq 'bus/firewire') { - set_alias('ieee1394-controller', $name); + $conf->set_alias('ieee1394-controller', $name); } elsif ($category =~ /sound/) { - my $sound_alias = find { /^sound-slot-[0-9]+$/ && $conf{$_}{alias} eq $name } keys %conf; + my $sound_alias = find { /^sound-slot-[0-9]+$/ && $conf->get_alias($_) eq $name } $conf->modules; $sound_alias ||= 'sound-slot-0'; - set_sound_slot($sound_alias, $name); + $conf->set_sound_slot($sound_alias, $name); } } @@ -433,7 +267,7 @@ sub extract_modules { if (!-e $cz) { unlink $_ foreach glob_("/lib/modules*.cz*"); require install_any; - install_any::getAndSaveFile("Mandrake/mdkinst$cz", $cz) or die "failed to get modules $cz: $!"; + install_any::getAndSaveFile("install/stage2/live$cz", $cz) or die "failed to get modules $cz: $!"; } eval { require packdrake; @@ -451,7 +285,7 @@ sub load_raw_install { my $m = '/tmp/' . name2file($_); if (-e $m) { my $stdout; - my $rc = run_program::run(["/usr/bin/insmod_", "insmod"], '2>', \$stdout, $m, @{$options->{$_}}); + my $rc = run_program::run(["/usr/bin/insmod_", "insmod"], '2>', \$stdout, $m, split(' ', $options->{$_})); log::l(chomp_($stdout)) if $stdout; if ($rc) { unlink $m; |
