diff --git a/debian/changelog b/debian/changelog index c5cc469d..8392d81a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +debian-cd (3.1.31) UNRELEASED; urgency=medium + + [ Steve McIntyre ] + * tools/generate_di_list: Only include kernel udebs for the highest + ABI we know about. Don't waste space on new installation media + with older udebs from the archive. + + -- Steve McIntyre <93sam@debian.org> Sun, 27 Sep 2020 01:10:07 +0100 + debian-cd (3.1.30) unstable; urgency=medium [ Steve McIntyre ] diff --git a/tools/generate_di_list b/tools/generate_di_list index 3ab3c723..d7e29707 100755 --- a/tools/generate_di_list +++ b/tools/generate_di_list @@ -1,12 +1,18 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # Generate a list of packages required for debian-installer # This script makes use of the following variables that need to be preset: # MIRROR, DI_CODENAME, BASEDIR + +use strict; +use warnings; + die "Missing \$MIRROR variable" unless $ENV{MIRROR}; die "Missing \$DI_CODENAME variable" unless $ENV{DI_CODENAME}; die "Missing \$BASEDIR variable" unless $ENV{BASEDIR}; die "Missing \$ARCHES variable" unless $ENV{ARCHES}; +my $catz = $ENV{BASEDIR} . "/tools/catz"; + # Early exit if we're building a source-only CD exit 0 if $ENV{ARCHES} =~ /^\s*source\s*$/; @@ -38,6 +44,33 @@ print OUT << "EOF"; */ EOF +sub di_ker_abi_to_number ($$$$) { + # Make up a version we can compare sensibly from + # the version and ABI + my $maj = shift; + my $min = shift; + my $patch = shift; + my $abi = shift; + my $kernel_ver = ($maj * 1000000000) + + ($min * 1000000) + + ($patch * 1000) + + $abi; + return $kernel_ver; +} + +sub number_to_di_ker_abi ($) { + # Convert back to a useful string + my $num = shift; + my $maj = int($num / 1000000000); + $num -= ($maj * 1000000000); + my $min = int($num / 1000000); + $num -= ($min * 1000000); + my $patch = int($num / 1000); + $num -= ($patch * 1000); + my $abi = $num; + return "$maj.$min.$patch-$abi"; +} + my @common_excludes = read_exclude("exclude-udebs"); my $mirror_path = "$ENV{MIRROR}/dists/$ENV{DI_CODENAME}"; my @components = qw(main); @@ -65,18 +98,71 @@ foreach my $arch (@ARCHES) { push @exclude, read_exclude("exclude-udebs-$arch") if -e exclude_path("exclude-udebs-$arch"); - if (-f $pgz) { - foreach my $udeb (map { chomp; $_ } `zcat $pgz | awk '/^Package:/ {print \$2}'`) { - $output .= "$udeb\n" unless grep { $udeb =~ /^${_}$/ } @exclude; - } - } elsif (-f $pxz) { - foreach my $udeb (map { chomp; $_ } `xzcat $pxz | awk '/^Package:/ {print \$2}'`) { - $output .= "$udeb\n" unless grep { $udeb =~ /^${_}$/ } @exclude; - } - } else { + my $pz = $pgz; + if (! -f $pz) { + $pz = $pxz; + } + if (! -f $pz) { print "Missing package file for $arch/$component.\n"; next; - } + } + + # Two passes here + # First, need to find the highest kernel ABI in the archive + # Next, list all the udebs that: + # 1. are not otherwise excluded + # 2. are not kernel driver udebs, OR + # are kernel driver udebs with the right kernel ABI + + unless ( open (PZ, "$catz $pz |") ) { + warn "failed to read package file $pz: $1"; + next; + } + + my @output_udebs; + my %driver_udebs; + my $highest_kernel_ver = 0; + + while (defined (my $line = )) { + chomp $line; + if ($line =~ m/^Package: (\S+)/) { + my $udeb = $1; + if (grep { $udeb =~ /^${_}$/ } @exclude) { + next; + } + if ($udeb =~ m/-modules-([0-9]*)\.([0-9]*)\.([0-9]*)-(\d+)-.*-di/) { + my $kernel_ver = di_ker_abi_to_number($1, $2, $3, $4); + if ($kernel_ver > $highest_kernel_ver) { + $highest_kernel_ver = $kernel_ver; + } + # Append this driver udeb to a list for that kernel_ver + push(@{ $driver_udebs{$kernel_ver} }, $udeb); + } else { + #print "found non-driver udeb $udeb\n"; + push @output_udebs, $udeb; + } + } + } + close PZ; + $output .= "/* First, generic udebs */\n"; + foreach my $udeb (@output_udebs) { + $output .= "$udeb\n"; + } + my $num_this_abi = scalar (@{ $driver_udebs{$highest_kernel_ver}}); + $output .= "/* Next: $num_this_abi udebs for kernel/ABI version "; + $output .= number_to_di_ker_abi($highest_kernel_ver); + $output .= " */\n"; + foreach my $udeb (@{ $driver_udebs{$highest_kernel_ver}}) { + $output .= "$udeb\n"; + } + foreach my $key (keys (%driver_udebs)) { + if ($key != $highest_kernel_ver) { + $num_this_abi = scalar (@{ $driver_udebs{$key}}); + $output .= "/* IGNORING $num_this_abi udebs for kernel/ABI version "; + $output .= number_to_di_ker_abi($key); + $output .= " */\n"; + } + } } next unless $output;