diff options
Diffstat (limited to 'perl-install')
-rw-r--r-- | perl-install/modules.pm | 83 | ||||
-rw-r--r-- | perl-install/modules/any_conf.pm | 122 | ||||
-rw-r--r-- | perl-install/modules/modprobe_conf.pm | 134 | ||||
-rw-r--r-- | perl-install/modules/modules_conf.pm | 58 |
4 files changed, 224 insertions, 173 deletions
diff --git a/perl-install/modules.pm b/perl-install/modules.pm index 7ca4b6ba4..685ca2550 100644 --- a/perl-install/modules.pm +++ b/perl-install/modules.pm @@ -159,91 +159,10 @@ sub probe_category { #-############################################################################### #- modules.conf functions #-############################################################################### - -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+$//; - - if ($type eq 'probeall') { - $val = [ split ' ', $val ]; - } - - $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 write_conf { - my ($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}) { #TODO - $_ = ''; - } elsif ($type eq 'alias' && !defined $conf->{$module}{alias}) { #TODO - $_ = ''; - } elsif ($conf->{$module}{$type} && $conf->{$module}{$type} ne $val) { #TODO - my $v = join(' ', uniq(deref($conf->{$module}{$type}))); #TODO - $_ = "$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) { #TODO - 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($conf); -} - sub write_preload_conf { my ($conf) = @_; my @l; - push @l, 'scsi_hostadapter' if !is_empty_array_ref($conf->get_probeall('scsi_hostadapter')); + push @l, 'scsi_hostadapter' if $conf->get_probeall('scsi_hostadapter'); push @l, intersection([ qw(bttv cx8800 saa7134) ], [ map { $_->{driver} } detect_devices::probeall() ]); my @l_26 = @l; diff --git a/perl-install/modules/any_conf.pm b/perl-install/modules/any_conf.pm index 10d21e712..21c8c3eec 100644 --- a/perl-install/modules/any_conf.pm +++ b/perl-install/modules/any_conf.pm @@ -5,7 +5,7 @@ use common; sub vnew { - if (0 && c::kernel_version() =~ /^\Q2.6/) { + if (c::kernel_version() =~ /^\Q2.6/) { require modules::modprobe_conf; modules::modprobe_conf->new; } else { @@ -20,27 +20,6 @@ sub new { bless {}, ref($type) || $type; } -sub read { - my ($_type, $o_file) = @_; - - my $conf = vnew(); - my $raw_conf = modules::read_conf($o_file || "$::prefix/etc/modules.conf"); - foreach my $key (keys %$raw_conf) { - my $raw = $raw_conf->{$key}; - my $keep = $conf->{$key} = {}; - $keep->{alias} ||= $raw->{alias}; - $keep->{above} ||= $raw->{above}; - $keep->{options} = $raw->{options} if $raw->{options}; - push @{$keep->{probeall} ||= []}, deref($raw->{probeall}) if $raw->{probeall}; - } - $conf; -} - -sub write { - my ($conf) = @_; - modules::write_conf($conf); -} - sub modules { my ($conf) = @_; keys %$conf; @@ -64,6 +43,25 @@ sub get_parameters { map { if_(/(.*)=(.*)/, $1 => $2) } split(' ', $conf->get_options($name)); } +sub get_probeall { + my ($conf, $alias) = @_; + $conf->{$alias}{probeall}; +} +sub set_probeall { + my ($conf, $alias, $modules) = @_; + $conf->{$alias}{probeall} = $modules; + log::l("setting probeall $alias to $modules"); +} +sub add_probeall { + my ($conf, $alias, $module) = @_; + my $modules = join(' ', uniq(split(' ', $conf->{$alias}{probeall}), $module)); + set_probeall($conf, $alias, $modules); +} +sub remove_probeall { + my ($conf, $alias, $module) = @_; + my $modules = join(' ', grep { $_ ne $module } split(' ', $conf->{$alias}{probeall})); + set_probeall($conf, $alias, $modules); +} sub set_alias { my ($conf, $alias, $module) = @_; @@ -108,10 +106,88 @@ sub remove_module { sub set_sound_slot { my ($conf, $alias, $module) = @_; if (my $old = $conf->get_alias($alias)) { - $conf->remove_above($old); + $conf->set_above($old, undef); } $conf->set_alias($alias, $module); $conf->set_above($module, 'snd-pcm-oss') if $module =~ /^snd-/; } + +sub read { + my ($type, $o_file) = @_; + + my $conf = modules::any_conf::vnew(); + my $raw_conf = modules::any_conf::read_raw($o_file || $::prefix . $conf->file); + + foreach my $module (keys %$raw_conf) { + my $raw = $raw_conf->{$module}; + my $keep = $conf->{$module} = {}; + foreach ($conf->handled_fields) { + $keep->{$_} = $raw->{$_} if $raw->{$_}; + } + } + + $conf; +} + +sub write { + my ($conf, $o_file) = @_; + my $file = $o_file || $::prefix . $conf->file; + + my %written; + + #- Substitute new config (if config has changed) + substInFile { + my ($type, $module, $val) = split(' ', chomp_($_), 3); + if ($type eq 'post-install' && $module eq 'supermount') { + #- remove the post-install supermount stuff. + $_ = ''; + } elsif (member($type, $conf->handled_fields)) { + my $new_val = $conf->{$module}{$type}; + if (!$new_val) { + $_ = ''; + } elsif ($new_val ne $val) { + $_ = "$type $module $new_val\n"; + } + } + $written{$module}{$type} = 1; + } $file; + + my $to_add; + while (my ($module, $h) = each %$conf) { + while (my ($type, $v) = each %$h) { + $to_add .= "$type $module $v\n" if $v && !$written{$module}{$type}; + } + } + append_to_file($file, $to_add); + + modules::write_preload_conf($conf); +} + + + + +################################################################################ +sub read_raw { + my ($file) = @_; + my %c; + + foreach (cat_($file)) { + next if /^\s*#/; + s/#.*$//; + s/\s+$//; + + s/\b(snd-card-)/snd-/g; + s/\b(snd-via686|snd-via8233)\b/snd-via82xx/g; + + my ($type, $module, $val) = split(' ', $_, 3) or next; + + $c{$module}{$type} = $val; + } + + #- NB: not copying alias options to the module anymore, hopefully not useful :) + + \%c; +} + 1; diff --git a/perl-install/modules/modprobe_conf.pm b/perl-install/modules/modprobe_conf.pm index 8b1e8305f..6c1eb7391 100644 --- a/perl-install/modules/modprobe_conf.pm +++ b/perl-install/modules/modprobe_conf.pm @@ -6,34 +6,60 @@ use common; our @ISA = qw(modules::any_conf); +sub file { '/etc/modprobe.conf' } +sub handled_fields { qw(alias options install remove) } + sub get_above { - my ($conf, $name) = @_; - after_modules($name, $conf->{$name}{install}); + my ($conf, $module) = @_; + + my (undef, $after) = parse_non_virtual($module, $conf->{$module}{install}) or return; + my ($l, $_other_cmds) = partition_modprobes($after); + join(' ', @$l); } sub set_above { - my ($conf, $name, $modules) = @_; - #TODO -} + my ($conf, $module, $o_modules) = @_; -sub get_probeall { - my ($conf, $alias) = @_; - #TODO + { #- first add to "install" command + my ($before, $after) = parse_non_virtual($module, $conf->{$module}{install}); + my ($_previous_modules, $other_cmds) = partition_modprobes($after || ''); + $after = join('; ', @$other_cmds, map { "/sbin/modprobe $_" } split(' ', $o_modules || '')); + $conf->{$module}{install} = unparse_non_virtual($module, '--ignore-install', $before, $after); + } + { #- then to "remove" command + my ($before, $after) = parse_non_virtual($module, $conf->{$module}{remove}); + my ($_previous_modules, $other_cmds) = partition_modprobes($before || ''); + $before = join('; ', @$other_cmds, map { "/sbin/modprobe -r $_" } split(' ', $o_modules || '')); + $conf->{$module}{remove} = unparse_non_virtual($module, '-r --ignore-remove', $before, $after); + } } -sub add_probeall { - my ($conf, $alias, $module) = @_; - #TODO - my $l = $conf->{$alias}{probeall} ||= []; - @$l = uniq(@$l, $module); - log::l("setting probeall $alias to @$l"); +sub read { + my ($type, $o_file) = @_; + + my $file = $o_file || do { + my $f = $::prefix . file(); + if (!-e $f && -e "$::prefix/etc/modules.conf") { + #- use module-init-tools script + run_program::rooted($::prefix, "/sbin/generate-modprobe.conf", ">", file()); + } + $f; + }; + + my $conf = modules::any_conf::read($type, $file); + + extract_probeall_field($conf); + + $conf; } -sub remove_probeall { - my ($conf, $alias, $module) = @_; - #TODO - my $l = $conf->{$alias}{probeall} ||= []; - @$l = grep { $_ ne $module } @$l; - log::l("setting probeall $alias to @$l"); +sub write { + my ($conf, $o_file) = @_; + + remove_probeall_field($conf); + + my $_b = before_leaving { extract_probeall_field($conf) }; + + modules::any_conf::write($conf, $o_file); } @@ -45,7 +71,7 @@ sub remove_braces { $s; } -sub non_virtual { +sub parse_non_virtual { my ($module, $s) = @_; my ($before, $options, $after) = $s =~ m!^(?:(.*);)? @@ -60,16 +86,32 @@ sub non_virtual { $before, $after; } -sub after_modules { - my ($module, $s) = @_; - my (undef, $after) = non_virtual($module, $s) or return; - +sub unparse_non_virtual { + my ($module, $mode, $before, $after) = @_; + ($before ? "$before; " : '') + . "/sbin/modprobe --first-time $mode $module" + . ($after ? " && { $after; /bin/true; }" : ''); +} + +sub partition_modprobes { + my ($s) = @_; + + my (@modprobes, @other_cmds); + my @l = split(/\s*;\s*/, $s); + foreach (@l) { + if (m!^(?:/sbin/)?modprobe\s+(?:-r\s+)?(\S+)$!) { + push @modprobes, $1; + } else { + push @other_cmds, $1; + } + } + \@modprobes, \@other_cmds; } -sub probeall { +sub parse_for_probeall { my ($module, $s) = @_; - non_virtual($module, $s) and return; + parse_non_virtual($module, $s) and return; if ($s =~ /[{&|]/) { log::l("weird install line in modprobe.conf for $module: $s"); return; @@ -78,30 +120,30 @@ sub probeall { $s =~ s!\s*;\s*/bin/true$!!; - my @l = split(/\s*;\s*/, $s); + my ($l, $other_cmds) = partition_modprobes($s); - [ map { - if (m!^(?:/sbin/)?modprobe\s+(\S+)$!) { - $1 - } else { - log::l("weird probeall string $_ (from install $module $s)"); - (); - } - } @l ]; + @$other_cmds ? undef : $l; +} + +sub extract_probeall_field { + my ($conf) = @_; + + foreach my $module (keys %$conf) { + $conf->{$module}{install} or next; + my $l = parse_for_probeall($module, $conf->{$module}{install}) or next; + + $conf->{$module}{probeall} = join(' ', @$l); + delete $conf->{$module}{install}; + } } -sub parse { - my ($type, $module, $s) = @_; +sub remove_probeall_field { + my ($conf) = @_; - member($type, 'install', 'remove') or return; + foreach my $module (keys %$conf) { + my $modules = delete $conf->{$module}{probeall} or next; - if (my ($before, $after) = non_virtual($module, $s)) { - [ - if_($after, [ "post-$type", $after ]), - if_($before, [ "pre-$type", $before ]), - ]; - } elsif (my $l = probeall($module, $s)) { - [ [ 'probeall', @$l ] ]; + $conf->{$module}{install} = join('; ', (map { "/sbin/modprobe $_" } split(' ', $modules)), '/bin/true'); } } diff --git a/perl-install/modules/modules_conf.pm b/perl-install/modules/modules_conf.pm index 2a720fc70..0436d56cc 100644 --- a/perl-install/modules/modules_conf.pm +++ b/perl-install/modules/modules_conf.pm @@ -5,36 +5,50 @@ use common; our @ISA = qw(modules::any_conf); + +sub file { '/etc/modules.conf' } +sub handled_fields { qw(alias above options probeall) } + sub get_above { - my ($conf, $name) = @_; - $conf->{$name} && $conf->{$name}{above}; + my ($conf, $module) = @_; + $conf->{$module} && $conf->{$module}{above}; } sub set_above { - my ($conf, $name, $modules) = @_; - $conf->{$name}{above} = $modules; -} -sub remove_above { - my ($conf, $name) = @_; - delete $conf->{$name}{above}; + my ($conf, $module, $o_modules) = @_; + if ($o_modules) { + $conf->{$module}{above} = $o_modules; + } else { + delete $conf->{$module}{above}; + } } -sub get_probeall { - my ($conf, $alias) = @_; - $conf->{$alias}{probeall}; -} -sub add_probeall { - my ($conf, $alias, $module) = @_; +sub read { + my ($type, $o_file) = @_; - my $l = $conf->{$alias}{probeall} ||= []; - @$l = uniq(@$l, $module); - log::l("setting probeall $alias to @$l"); + my $conf = modules::any_conf::read($type, $o_file); + + #- 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*)/ && $conf->{$_}{alias}, [ $_, $1 || 0 ]) } keys %$conf; + foreach my $alias (@old_aliases) { + $conf->add_probeall($name, delete $conf->{$alias}{alias}); + } + } + + $conf; } -sub remove_probeall { - my ($conf, $alias, $module) = @_; - my $l = $conf->{$alias}{probeall} ||= []; - @$l = grep { $_ ne $module } @$l; - log::l("setting probeall $alias to @$l"); +sub write { + my ($conf, $o_file) = @_; + my $file = $o_file || do { + my $f = $::prefix . file(); + rename "$::prefix/etc/conf.modules", $f; #- make the switch to new name if needed + $f; + }; + + modules::any_conf::write($conf, $file); } 1; |