diff options
Diffstat (limited to 'perl-install/modules.pm')
| -rw-r--r-- | perl-install/modules.pm | 263 |
1 files changed, 123 insertions, 140 deletions
diff --git a/perl-install/modules.pm b/perl-install/modules.pm index 3a16b62e6..abeb0b366 100644 --- a/perl-install/modules.pm +++ b/perl-install/modules.pm @@ -1,4 +1,4 @@ -package modules; # $Id$ +package modules; use strict; @@ -11,8 +11,7 @@ use modules::any_conf; sub modules_descriptions() { my $f = '/lib/modules/' . c::kernel_version() . '/modules.description'; - -e $f or $f = '/lib/modules.description'; - map { /(\S+)\s+(.*)/ } cat_($f); + map { my ($m, $d) = /(\S+)\s+(.*)/; $m =~ s/-/_/g; ($m => $d) } cat_($f); } sub module2description { +{ modules_descriptions() }->{$_[0]} } @@ -24,9 +23,9 @@ sub category2modules_and_description { } my %mappings_24_26 = ( - "usb-ohci" => "ohci-hcd", - "usb-uhci" => "uhci-hcd", - "uhci" => "uhci-hcd", + "usb_ohci" => "ohci_hcd", + "usb_uhci" => "uhci_hcd", + "uhci" => "uhci_hcd", "printer" => "usblp", "bcm4400" => "b44", "3c559" => "3c359", @@ -34,7 +33,9 @@ my %mappings_24_26 = ( "dc395x_trm" => "dc395x", ); my %mappings_26_24 = reverse %mappings_24_26; -$mappings_26_24{'uhci-hcd'} = 'usb-uhci'; +$mappings_26_24{uhci_hcd} = 'usb_uhci'; + +my @parallel_zip_modules = qw(imm ppa); sub mapping_24_26 { my ($modname) = @_; @@ -47,57 +48,97 @@ sub mapping_26_24 { sub cond_mapping_24_26 { my ($modname) = @_; - c::kernel_version() =~ /^\Q2.6/ && $mappings_24_26{$modname} || $modname; + $mappings_24_26{$modname} || list_modules::filename2modname($modname); +} + +sub module_is_available { + my ($module) = @_; + defined list_modules::modname2filename($module); } #-############################################################################### #- module loading #-############################################################################### + +sub filter_loaded_modules { + my ($lm) = @_; + + my $l; + + # try to detect built-in modules by looking at /sys/module + # unfortunately it does not work for all modules eg : + # - networks protocols like af_packet + # - filesystems + foreach my $mod (@$lm) { + $mod =~ s/-/_/g; + if (-d "/sys/module/$mod") { + log::l("$mod already loaded"); + } elsif ($mod =~ /af_packet/) { + if (-f "/proc/net/packet") { + log::l("$mod already loaded"); + } else { + push @$l, $mod; + } + } elsif (cat_("/proc/filesystems") =~ /$mod/) { + log::l("$mod already loaded"); + } elsif ($mod =~ /serial/) { + # hack ... must find who tries to load the module serial + } else { + push @$l, $mod; + } + } + $l; +} + # handles dependencies sub load_raw { - my ($l, $h_options) = @_; - if ($::testing) { + my ($lm, $h_options) = @_; + + my $l = filter_loaded_modules($lm); + + if ($::testing || $::local_install) { log::l("i would load module $_ ($h_options->{$_})") foreach @$l; - } elsif ($::isInstall && !$::move) { - load_raw_install($l, $h_options); } else { 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; + if (any { /^(mousedev|printer)$/ } @$l) { + sleep 2; + } elsif (member('usb_storage', @$l)) { + #- usb_storage is only modprobed when we know there is some scsi devices + #- so trying hard to wait for devices to be detected + run_program::run('udevadm', 'settle'); + } } sub load_with_options { my ($l, $h_options) = @_; my @l = map { - dependencies_closure(cond_mapping_24_26($_)); + if_(member($_, 'plip', @parallel_zip_modules), 'parport_pc'), + if_($_ eq 'vfat', 'nls_cp437', 'nls_iso8859_1'), + if_(member($_, qw(btrfs xfs)), 'crc32c', 'crc32c-intel'), + cond_mapping_24_26($_); } @$l; - @l = remove_loaded_modules(@l) or return; + @l = filter_out_loaded_modules(@l) or return; - load_raw(\@l, $h_options); + my %options = map { cond_mapping_24_26($_) => $h_options->{$_} } keys %$h_options; + load_raw(\@l, \%options); } sub load { my (@l) = @_; load_with_options(\@l, {}); } -# eg: load_and_configure($modules_conf, 'vfat', 'reiserfs', [ ne2k => 'io=0xXXX', 'dma=5' ]) +# eg: load_and_configure($modules_conf, 'bt878', [ bttv => 'no_overlay=1' ]) 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))); - load_raw(\@l, { $module => $o_options }); + my @l = filter_out_loaded_modules(cond_mapping_24_26($module)); + load_raw(\@l, { cond_mapping_24_26($module) => $o_options }); - if ($network_devices) { - $conf->set_alias($_, $module) foreach difference2([ detect_devices::getNet() ], $network_devices); - } - - if (c::kernel_version() =~ /^\Q2.6/ && member($module, 'imm', 'ppa') + if (member($module, @parallel_zip_modules) && ! -d "/proc/sys/dev/parport/parport0/devices/$module") { log::l("$module loaded but is not useful, removing"); unload($module); @@ -122,54 +163,36 @@ sub load_category { my @try_modules = ( if_($category =~ /scsi/, - if_(arch() !~ /ppc/, 'parport_pc', 'imm', 'ppa'), - if_(detect_devices::usbStorage(), 'usb-storage'), + if_(detect_devices::usbStorage(), 'usb_storage'), ), - arch() =~ /ppc/ ? ( - if_($category =~ /scsi/, - if_(detect_devices::has_mesh(), 'mesh'), - if_(detect_devices::has_53c94(), 'mac53c94'), - ), - if_($category =~ /net/, 'bmac', 'gmac', 'mace', 'airport'), - ) : (), ); - grep { + my @l = ( + (map { + my $other = { ahci => 'ata_piix', ata_piix => 'ahci' }->{$_->{driver}}; + $_->{try} = 1 if $other; + ($_, if_($other, { %$_, driver => $other })); + } detect_devices::probe_category($category)), + (map { { driver => $_, description => $_, try => 1 } } @try_modules), + ); + + foreach (@l) { $o_wait_message->($_->{description}, $_->{driver}) if $o_wait_message; eval { load_and_configure($conf, $_->{driver}, $_->{options}) }; $_->{error} = $@; $_->{try} = 1 if member($_->{driver}, 'hptraid', 'ohci1394'); #- do not warn when this fails - - !($_->{error} && $_->{try}); - } probe_category($category), - map { { driver => $_, description => $_, try => 1 } } @try_modules; + } + eval { load_and_configure($conf, 'ide_generic') } if $category eq 'disk/ide'; + grep { !($_->{error} && $_->{try}) } @l; } -sub probe_category { - my ($category) = @_; - - my @modules = category2modules($category); - - if_($category =~ /sound/ && arch() =~ /ppc/ && detect_devices::get_mac_model() !~ /IBM/, - { driver => 'snd-powermac', description => 'Macintosh built-in' }, - ), - grep { - if ($category eq 'network/isdn') { - my $b = $_->{driver} =~ /ISDN:([^,]*),?([^,]*)(?:,firmware=(.*))?/; - if ($b) { - $_->{driver} = $1; - $_->{type} = $2; - $_->{type} =~ s/type=//; - $_->{firmware} = $3; - $_->{driver} eq "hisax" and $_->{options} .= " id=HiSax"; - } - $b; - } else { - member($_->{driver}, @modules); - } - } detect_devices::probeall(); -} +sub load_parallel_zip { + my ($conf) = @_; + grep { + eval { load_and_configure($conf, $_); 1 }; + } @parallel_zip_modules; +} #-############################################################################### #- modules.conf functions @@ -177,22 +200,21 @@ sub probe_category { sub write_preload_conf { my ($conf) = @_; my @l; + my $is_laptop = detect_devices::isLaptop(); + my $manufacturer = detect_devices::dmidecode_category('System')->{Manufacturer}; push @l, 'scsi_hostadapter' if $conf->get_probeall('scsi_hostadapter'); - push @l, intersection([ list_modules::category2modules('multimedia/dvb'), list_modules::category2modules('multimedia/tv') ], - [ map { $_->{driver} } detect_devices::probeall() ]); - push @l, 'nvram' if cat_('/proc/bus/input/devices') =~ m!^N: Name="SynPS/2 Synaptics TouchPad"$!m; - push @l, map { $_->{driver} } probe_category('various/laptop'); - push @l, map { $_->{driver} } probe_category('multimedia/joystick'); - push @l, map { $_->{driver} } probe_category('various/crypto'); - push @l, 'padlock' if cat_("/proc/cpuinfo") =~ /rng_en/; - my @l_26 = @l; - push @l_26, map { $_->{driver} } probe_category('various/agpgart'); - append_to_modules_loaded_at_startup("$::prefix/etc/modules", @l); - append_to_modules_loaded_at_startup("$::prefix/etc/modprobe.preload", @l_26); + push @l, detect_devices::probe_name('Module'); + push @l, 'nvram' if $is_laptop; + push @l, map { $_->{driver} } detect_devices::probe_category($_) foreach qw(multimedia/dvb multimedia/tv various/agpgart various/laptop input/joystick various/crypto disk/card_reader); + push @l, 'padlock-aes', 'padlock-sha' if cat_("/proc/cpuinfo") =~ /rng_en/; + push @l, 'evdev' if detect_devices::hasTouchpad(); + push @l, 'evdev' if any { $_->{HWHEEL} } detect_devices::getInputDevices(); + push @l, 'hdaps' if $is_laptop && $manufacturer eq 'LENOVO'; + append_to_modules_loaded_at_startup("$::prefix/etc/modprobe.preload", @l); } sub append_to_modules_loaded_at_startup_for_all_kernels { - append_to_modules_loaded_at_startup($_, @_) foreach "$::prefix/etc/modules", "$::prefix/etc/modprobe.preload"; + append_to_modules_loaded_at_startup($_, @_) foreach "$::prefix/etc/modprobe.preload"; } sub append_to_modules_loaded_at_startup { @@ -206,6 +228,17 @@ sub append_to_modules_loaded_at_startup { } $file; } +sub set_preload_modules { + my ($service, @modules) = @_; + my $preload_file = "$::prefix/etc/modprobe.preload.d/$service"; + if (@modules) { + output_p($preload_file, join("\n", @modules, '')); + } else { + unlink($preload_file); + } + eval { load(@modules) } if @modules && !$::isInstall; +} + #-############################################################################### #- internal functions @@ -213,7 +246,7 @@ sub append_to_modules_loaded_at_startup { sub loaded_modules() { map { /(\S+)/ } cat_("/proc/modules"); } -sub remove_loaded_modules { +sub filter_out_loaded_modules { my (@l) = @_; difference2([ uniq(@l) ], [ map { my $s = $_; $s =~ s/_/-/g; $s, $_ } loaded_modules() ]); } @@ -223,13 +256,6 @@ sub read_already_loaded { when_load($conf, $_) foreach reverse loaded_modules(); } -my $module_extension = c::kernel_version() =~ /^\Q2.4/ ? 'o' : 'ko'; - -sub name2file { - my ($name) = @_; - "$name.$module_extension"; -} - sub when_load { my ($conf, $name) = @_; @@ -237,24 +263,27 @@ sub when_load { when_load_category($conf, $name, $category); } - if (my $above = $conf->get_above($name)) { - load($above); #- eg: for snd-pcm-oss set by set_sound_slot() + if (my @above = $conf->get_above($name)) { + load(@above); #- eg: for snd-pcm-oss set by set_sound_slot() } } sub when_load_category { my ($conf, $name, $category) = @_; - if ($category =~ m,disk/(ide|scsi|hardware_raid|sata|usb|firewire),) { + if ($category =~ m,disk/ide,) { + $conf->add_probeall('ide-controller', $name); + eval { load('ide_gd_mod') }; + } elsif ($category =~ m,disk/(scsi|hardware_raid|sata|firewire|virtual),) { $conf->add_probeall('scsi_hostadapter', $name); eval { load('sd_mod') }; } elsif ($category eq 'bus/usb') { $conf->add_probeall('usb-interface', $name); - -f '/proc/bus/usb/devices' or eval { - require fs; fs::mount_usbfs(''); + -f '/sys/kernel/debug/usb/devices' or eval { + require fs::mount; fs::mount::sys_kernel_debug(''); #- ensure keyboard is working, the kernel must do the job the BIOS was doing sleep 4; - load("usbkbd", "keybdev") if detect_devices::usbKeyboards(); + load("usbhid") if detect_devices::usbKeyboards(); }; } elsif ($category eq 'bus/firewire') { $conf->set_alias('ieee1394-controller', $name); @@ -262,56 +291,10 @@ sub when_load_category { my $sound_alias = find { /^sound-slot-[0-9]+$/ && $conf->get_alias($_) eq $name } $conf->modules; $sound_alias ||= 'sound-slot-0'; $conf->set_sound_slot($sound_alias, $name); + } elsif ($category =~ m!disk/card_reader!) { + my @modules = ('mmc_block', if_($name =~ /tifm_7xx1/, 'tifm_sd')); + $conf->set_above($name, join(' ', @modules)); } } -#-############################################################################### -#- isInstall functions -#-############################################################################### -sub cz_file() { - "/lib/modules" . (arch() eq 'sparc64' && "64") . ".cz-" . c::kernel_version(); -} - -sub extract_modules { - my ($dir, @modules) = @_; - my $cz = cz_file(); - if (!-e $cz) { - unlink $_ foreach glob_("/lib/modules*.cz*"); - require install_any; - install_any::getAndSaveFile("install/stage2/live$cz", $cz) or die "failed to get modules $cz: $!"; - } - eval { - require packdrake; - my $packer = new packdrake($cz, quiet => 1); - $packer->extract_archive($dir, map { name2file($_) } @modules) if @modules; - map { $dir . '/' . name2file($_) } @modules; - }; -} - -sub load_raw_install { - my ($l, $options) = @_; - - extract_modules('/tmp', @$l); - my @failed = grep { - my $m = '/tmp/' . name2file($_); - if (-e $m) { - my $stdout; - my $rc = run_program::run(["/usr/bin/insmod_", "insmod"], '2>', \$stdout, $m, split(' ', $options->{$_})); - log::l(chomp_($stdout)) if $stdout; - if ($rc) { - unlink $m; - ''; - } else { - 'error'; - } - } else { - log::l("missing module $_"); - 'error'; - } - } @$l; - - die "insmod'ing module " . join(", ", @failed) . " failed" if @failed; - -} - 1; |
