summaryrefslogtreecommitdiffstats
path: root/perl-install
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install')
-rw-r--r--perl-install/modules.pm83
-rw-r--r--perl-install/modules/any_conf.pm122
-rw-r--r--perl-install/modules/modprobe_conf.pm134
-rw-r--r--perl-install/modules/modules_conf.pm58
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;