summaryrefslogtreecommitdiffstats
path: root/perl-install/modules.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/modules.pm')
-rw-r--r--perl-install/modules.pm263
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;