Hello community, here is the log from the commit of package dracut for openSUSE:Factory checked in at 2019-03-05 12:15:09 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/dracut (Old) and /work/SRC/openSUSE:Factory/.dracut.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "dracut" Tue Mar 5 12:15:09 2019 rev:134 rq:678954 version:044.1 Changes: -------- --- /work/SRC/openSUSE:Factory/dracut/dracut.changes 2019-02-24 17:07:27.148564682 +0100 +++ /work/SRC/openSUSE:Factory/.dracut.new.28833/dracut.changes 2019-03-05 12:15:10.905028185 +0100 @@ -1,0 +2,6 @@ +Mon Feb 25 14:51:07 UTC 2019 - Daniel Molkentin <[email protected]> + +- purge-kernels: Avoid endless loop when uninstalling kernels that depend on + KMPs which in themselves depend on other packages (bsc#1125327) + +------------------------------------------------------------------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ purge-kernels ++++++ --- /var/tmp/diff_new_pack.Skardp/_old 2019-03-05 12:15:14.905026941 +0100 +++ /var/tmp/diff_new_pack.Skardp/_new 2019-03-05 12:15:14.905026941 +0100 @@ -268,8 +268,37 @@ return @packages; } +sub find_package { + my $name = shift @_; + my $version = shift @_; + my @packages = @_; + my $expr = "^" . quotemeta("$name-$version"); + my @found = grep { $_ =~ $expr } @packages; + return @found if @found; + $expr = "^" . quotemeta($name) . " = " . quotemeta($version) . "\$"; + @found = grep { + my @provides = qx/rpm -q --provides $_/; + chomp (@provides); + grep { $_ =~ $expr} @provides; + } @packages; + return @found; +} + +# Try to remove a list of packages. +# +# If there is a KMP or livepatch depending on the package remove it as well. If +# there is another package depending on the kernel keep the kernel. If there is +# a package that depends on a KMP keep the KMP and a kernel required to use the +# KMP. +# In each step a KMP or livepatch may be added or a package which cannot be +# removed due to dependencies is marked as taboo and removed from the list. +# +# Finish when packages uninstall successfully or we can't find any packages to +# add or remove from the list to make it uninstallable. + sub remove_packages { my @packages = @_; + my %taboo_packages; while (1) { pipe(my $read, my $write); @@ -296,25 +325,30 @@ print "Removed:\n ", join("\n ", @packages), "\n"; return 1; } - my ($retry, @problems); + my $retry = 0; my %old_packages = map { $_ => 1 } @packages; my %new_packages; for (@out) { if (/ is needed by \(installed\) (kernel-syms-.*|kgraft-patch-.*|kernel-livepatch-.*|.*-kmp-.*)/ && - !$old_packages{$1}) { + !$old_packages{$1} && !$taboo_packages{$1}) { push(@packages, $1) unless $new_packages{$1}; $new_packages{$1} = 1; $retry = 1; } elsif (/([^ \t]*) = ([^ \t]*) is needed by \(installed\) /) { - print STDERR "$0: $_\n"; - @packages = grep ! /$1-$2/, @packages; - $retry = 1; - } else { - push(@problems, $_); + my @unremovable = find_package($1, $2, @packages); + my $match = $unremovable[$#unremovable]; + if ($match) { + print STDERR "$0: $_\n"; + print STDERR "$0: Keeping $1 = $2 ($match)\n"; + @packages = grep { $_ !~ $match } @packages; + $taboo_packages{$match} = 1; + $retry = 1; + last; # Only remove one package providing the dependency from the list + } } } if (!$retry) { - print STDERR join("\n", @problems), "\n"; + print STDERR join("\n", @out), "\n"; print STDERR "$0: giving up.\n"; return 0; }
