summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorespie <espie@openbsd.org>2018-06-15 10:28:21 +0000
committerespie <espie@openbsd.org>2018-06-15 10:28:21 +0000
commit4fe8a6753fdaaed1439f03e7746f44061ee15458 (patch)
treed0ec52d6683becccb4417ec11c8c3a65bf114ac0
parentno need to always use 1 for the constant, knowing how it got solved can (diff)
downloadwireguard-openbsd-4fe8a6753fdaaed1439f03e7746f44061ee15458.tar.xz
wireguard-openbsd-4fe8a6753fdaaed1439f03e7746f44061ee15458.zip
fix for the infamous "cups" bug. Finally.
the problem was in solve_wantlibs, which is invoked fairly early in the game (before actually committing to install the set) and which would walk the "current" dependency tree and solve libs accordingly. The problem being that sometimes, the libraries were in an older set... so the fix is to do the dependency adjustment at this point as well, to properly peek in the new set. The main problem with that bug was how hard it was to reproduce, because it depends on several conditions: - the old and new package must have different names, but contain some shared libraries with the same version. - it has to be an UpdateSet with several packages tied together - reaching the library must be possible through several paths. This usually happens after several sets got merged together. - taking the wrong path is dependent on the hash key order of the dependencies, which is random.
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Dependencies.pm34
1 files changed, 33 insertions, 1 deletions
diff --git a/usr.sbin/pkg_add/OpenBSD/Dependencies.pm b/usr.sbin/pkg_add/OpenBSD/Dependencies.pm
index 1d86ecdf842..819f6bc07db 100644
--- a/usr.sbin/pkg_add/OpenBSD/Dependencies.pm
+++ b/usr.sbin/pkg_add/OpenBSD/Dependencies.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: Dependencies.pm,v 1.159 2018/06/15 09:39:03 espie Exp $
+# $OpenBSD: Dependencies.pm,v 1.160 2018/06/15 10:28:21 espie Exp $
#
# Copyright (c) 2005-2010 Marc Espie <espie@openbsd.org>
#
@@ -37,10 +37,17 @@ sub lookup
}
# lookup through the rest of the tree...
my $done = $self->{done};
+
while (my $dep = pop @{$self->{todo}}) {
require OpenBSD::RequiredBy;
next if $done->{$dep};
+ # may need to replace older dep with newer ?
+ my $newer = $self->may_adjust($solver, $state, $dep);
+ if (defined $newer) {
+ push(@{$self->{todo}}, $newer);
+ next;
+ }
$done->{$dep} = 1;
for my $dep2 (OpenBSD::Requiring->new($dep)->list) {
push(@{$self->{todo}}, $dep2) unless $done->{$dep2};
@@ -59,6 +66,31 @@ sub lookup
return 0;
}
+# While walking the dependency tree, we may loop back to an older package,
+# because we're relying on dep lists on disk, that we haven't adjusted yet
+# since we're just checking. We need to prepare for the update here as well!
+sub may_adjust
+{
+ my ($self, $solver, $state, $dep) = @_;
+ my $h = $solver->{set}{older}{$dep};
+ if (defined $h) {
+ $state->print("Detecting older #1...", $dep)
+ if $state->verbose >=3;
+ my $u = $h->{update_found};
+ if (!defined $u) {
+ $state->errsay("NO UPDATE FOUND for #1!", $dep);
+ } elsif ($u->pkgname ne $dep) {
+ $state->say("converting into #1", $u->pkgname)
+ if $state->verbose >=3;
+ return $u;
+ } else {
+ $state->say("didn't change")
+ if $state->verbose >=3;
+ }
+ }
+ return undef;
+}
+
sub new
{
my ($class, $solver) = @_;