Home Home > GIT Browse
summaryrefslogtreecommitdiff
blob: df2b0bfbfb8e2b332ba409a84604dbee0bc0ea22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#! /usr/bin/perl

use File::Temp qw(tempdir);
use FileHandle;

sub module_aliases($) {
    my ($rpm) = @_;
    my $tempdir = tempdir( TMPDIR => 1, CLEANUP => 1 )
	or die "$0\n";

    unless (-e $rpm) {
	die "$rpm: File not found\n";
    }

    system("rpm2cpio \"$rpm\" | (cd \"$tempdir\" && cpio -dim --quiet)")
	and die "$rpm: $!\n";

    my $modules;
    my $fh = new FileHandle("find $tempdir -name '*.ko' |")
	or die "$rpm: $!\n";
    while (<$fh>) {
	chomp;
	push @$modules, $_;
    }
    $fh->close;

    my $aliases;
    foreach my $module (@$modules) {
	my $basename = $module;
	$basename =~ s<.*/><>;
	$basename =~ s<\.ko$><>;

	my $fh2 = new FileHandle("/sbin/modinfo -F alias \"$module\" |")
	    or die "$module: $!\n";
	while (<$fh2>) {
	    chomp;
	    push @{$aliases->{$basename}}, $_;
	}
	$fh2->close;
    }

    return $aliases
}

unless (@ARGV == 2) {
    print "USAGE: $0 kernel-old.rpm kernel-new.rpm\n";
    print "Checks which modules in the old kernel are obsoleted by which " .
    	  "modules in the new kernel.\n";
    exit 1
}

print STDERR "Extracting module aliases from $ARGV[0]\n";
my $old_modules = module_aliases($ARGV[0]);

print STDERR "Extracting module aliases from $ARGV[1]\n";
my $new_modules = module_aliases($ARGV[1]);

#foreach my $module (sort keys %$old_modules) {
#    foreach my $alias (sort @{$old_modules->{$module}}) {
#	print "old\t$module\t$alias\n";
#    }
#}

#foreach my $module (sort keys %$new_modules) {
#    foreach my $alias (sort @{$new_modules->{$module}}) {
#	print "new\t$module\t$alias\n";
#    }
#}

# Precompile regular expressions for fast matching (the matching
# itself scales quadratically with the number of obsolete modules).
my $regexps;
foreach my $module (keys %$new_modules) {
    foreach my $alias (@{$new_modules->{$module}}) {
	my $re = $alias;
	$re =~ s<\*><.*>g;
	$regexps->{$module}{$alias} = qr<^$re$>;
    }
}

print STDERR "Analyzing modules\n";
foreach my $old_module (sort keys %$old_modules) {
    next if exists $new_modules->{$old_module};

    my $old_aliases = $old_modules->{$old_module};
    my $hardware_aliases = 0;
    foreach my $alias (@$old_aliases) {
	$hardware_aliases++
	    if $alias =~ /:/;
    }
    next unless $hardware_aliases > 0;

    my $matches = 0;
    foreach my $new_module (sort keys %$new_modules) {
	my $matching_aliases = 0;
	foreach my $old_alias (@$old_aliases) {
	    foreach my $new_alias (@{$new_modules->{$new_module}}) {
		my $re = $regexps->{$new_module}{$new_alias};
		$matching_aliases++
		    if $old_alias =~ /$re/;
	    }
	}

	if ($matching_aliases == @$old_aliases) {
	    print "alias\t$old_module\t$new_module\n";
	    $matches++;
	}
    }
    if ($matches == 0) {
	print "# blacklist\t$old_module\n";
    }
}