use strict; BEGIN { #- for testing purpose (my $f = __FILE__) =~ s|/[^/]*$||; push @INC, $f; } use MDK::Common; use list_modules; sub flatten_and_check { my ($h) = @_; map { my $category = $_; my @l = @{$h->{$category}}; if (my @bad = difference2(\@l, [ category2modules($category) ])) { foreach (@bad) { if (my $cat = module2category($_)) { warn "ERROR in modules.pl: module $_ is in category $cat, not in $category\n"; } else { warn "ERROR in modules.pl: unknown module $_\n"; } } exit 1; } @l; } keys %$h; } my $images_cat = 'fs/* disk/* bus/* network/* input/* various/*'; #- ie everything except multimedia my $verbose = $ARGV[0] eq '-v' && shift; my ($f, @para) = @ARGV; $::{$f}->(@para); sub modules() { my @nls_modules = ('nls_cp437', 'nls_iso8859_1'); @nls_modules, map { category2modules($_) } split(' ', $images_cat); } sub list_needed_modules { my ($kern_ver) = @_; load_dependencies("/lib/modules/$kern_ver/modules.dep"); my @all = modules(); my @all_with_deps = map { dependencies_closure($_) } @all; my %wanted_modules = map { (list_modules::modname2filename($_) => 1) } @all_with_deps; foreach (`find /lib/modules/$kern_ver -name '*.ko.?z'`) { my $modfile = basename($_); $modfile =~ s/\.ko\.xz//; $wanted_modules{$modfile} and print "$modfile\n"; } } sub list_fake_modules { my ($kern_ver) = @_; load_dependencies("/lib/modules/$kern_ver/modules.dep"); my @all = map { category2modules($_) } split(' ', 'multimedia/*'); my %wanted_modules = map { (list_modules::modname2filename($_) => 1) } @all; foreach (`find /lib/modules/$kern_ver -name '*.ko.?z'`) { my $modfile = basename($_); $modfile =~ s/\.ko\.xz//; $wanted_modules{$modfile} and print "$modfile\n"; } } sub pci_modules4stage1 { my ($category) = @_; my @modules = difference2([ category2modules($category) ]); print "$_\n" foreach uniq(map { dependencies_closure($_) } @modules); } sub get_kernel_modules { my ($kern_ver) = @_; my @module_list; foreach (sort(cat_("/lib/modules/$kern_ver/modules.dep"))) { my ($module, $discard) = split(':', $_); push @module_list, $module; } foreach (sort(cat_("/lib/modules/$kern_ver/modules.builtin"))) { my ($module, $discard) = split(':', $_); push @module_list, $module; } @module_list; } sub check() { my ($kern_ver) = @_; if (!$kern_ver) { $kern_ver = `uname -r`; chomp($kern_ver); } my $error; my %listed; while (my ($t1, $l) = each %list_modules::l) { while (my ($t2, $l) = each %$l) { ref $l or die "bad $l in $t1/$t2"; foreach (@$l) { $listed{$_} = "$t1/$t2"; } } } my %module2category; my %deprecated_modules = %listed; my $not_listed = sub { my %not_listed; foreach (@_) { my $path = dirname($_); my $name = basename($_); $name =~ s/\.ko(\.xz)?$//; delete $deprecated_modules{$name}; next if $listed{$name}; $module2category{list_modules::filename2modname($name)} = $path; push @{$not_listed{$path}}, $name; } if ($verbose) { print "NOT LISTED $_: ", join(" ", @{$not_listed{$_}}), "\n" foreach sort keys %not_listed; } }; $not_listed->(get_kernel_modules($kern_ver)); if (%deprecated_modules) { my %per_cat; push @{$per_cat{$listed{$_}}}, $_ foreach keys %deprecated_modules; foreach my $cat (sort keys %per_cat) { print "bad/old modules ($cat) : ", join(" ", sort @{$per_cat{$cat}}), "\n"; } } { require '/usr/bin/merge2pcitable.pl'; my $pcitable = read_pcitable("/usr/share/ldetect-lst/pcitable"); my $usbtable = read_pcitable("/usr/share/ldetect-lst/usbtable"); my @l0 = map { list_modules::filename2modname($_) } keys %listed; my @l1 = uniq grep { !/:/ && $_ ne 'unknown' } map { $_->[0] } values %$pcitable; if (my @l = difference2(\@l1, \@l0)) { my %not_listed; push @{$not_listed{$module2category{$_}}}, $_ foreach @l; if (my $l = delete $not_listed{''}) { print "bad/old pcitable modules : ", join(" ", @$l), "\n"; } print STDERR "pcitable modules not listed in $_: ", join(" ", sort @{$not_listed{$_}}), "\n" foreach sort keys %not_listed; print STDERR "note: pcitable module names need to be mapped to file names when updating list_modules.pm\n" if %not_listed; $error = 1; } my @l2 = uniq grep { !/:/ && $_ ne 'unknown' } map { $_->[0] } values %$usbtable; if (my @l = difference2(\@l2, \@l0)) { my %not_listed; push @{$not_listed{$module2category{$_}}}, $_ foreach @l; if (my $l = delete $not_listed{''}) { print "bad/old usbtable modules : ", join(" ", @$l), "\n"; } print STDERR "usbtable modules not listed in $_: ", join(" ", sort @{$not_listed{$_}}), "\n" foreach sort keys %not_listed; print STDERR "note: usbtable module names need to be mapped to file names when updating list_modules.pm\n" if %not_listed; $error = 1; } } exit $error; } sub list_additional_firmware { my ($kern_ver) = @_; # The firmware reported by 'modinfo iwlwifi' is the latest supported version of each firmware # type. Sometimes the latest supported version is not available, and the driver falls back to # an older version. This means dracut doesn't automatically identify and include the necessary # firmware files, so we need to list them here (mga#9541). foreach (map { /^firmware:\s+(.*)/ ? $1 : () } split("\n", `modinfo -k $kern_ver iwlwifi`)) { next if -f "/lib/firmware/$_"; my ($basename, $version) = /(.*)-([0-9]+).ucode/; while ($version-- > 0) { my $filepath = "/lib/firmware/$basename-$version.ucode"; if (-f $filepath) { print "$filepath\n"; last; } } } }