[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#777760: apt: fails to satisfy dependencies of the form package:arch with arch being the native architecture



Hi,

On Thu, Feb 12, 2015 at 11:25:33AM +0100, Johannes Schauer wrote:
> apt in unstable/jessie fails to satisfy binary dependencies of the form
> package:arch if arch happens to be the native architecture.

As briefly discussed on IRC, this happens also for /experimental, but it
happens only on single-architecture systems, multi-arch enabled systems
aren't effected.

The problem is a single-arch special casing generating incorrect
dependencies, which for foreign dependencies still means they are
unsatisfiable, but native ones are, too. This is especially true for
negative arch-specific dependencies, which do not match a native
conflict partner and hence trick apt into ignoring these conflicts.

Neither is really a problem for jessie as such dependencies do not exist
there. Even sid has only one such package: botch - maintained by the
bugreporter himself.

In terms of upgrade ability to stretch later on it might be beneficial
to apply this to jessie – after all, we can't botch the upgrade for all
botch users… ;)


The patch is 'trivial' one-line - the also included update to the
testcases to look for this and similar issues blows it out of proportion
through, but that can be skipped as it isn't run at buildtime.


Best regards

David Kalnischkies
commit 596ec43ce34421080a58b28299c1ed9cb0dbaa25
Author: David Kalnischkies <david@kalnischkies.de>
Date:   Sun Apr 12 19:16:01 2015 +0200

    parse specific-arch dependencies correctly on single-arch systems
    
    On single-arch the parsing was creating groupnames like 'apt:amd64' even
    through it should be 'apt' and a package in it belonging to architecture
    amd64. The result for foreign architectures was as expected: The
    dependency isn't satisfiable, but for native architecture it means the
    wrong package (ala apt:amd64:amd64) is linked so this is also not
    satisfiable, which is very much not expected.
    
    No longer excluding single-arch from this codepath allows the generation
    of the correct links, which still link to non-exisiting packages for
    foreign dependencies, but natives link to the expected native package
    just as if no architecture was given.
    
    For negative arch-specific dependencies ala Conflicts this matter was
    worse as apt will believe there isn't a Conflict to resolve, tricking it
    into calculating a solution dpkg will refuse.
    
    Architecture specific positive dependencies are rare in jessie – the
    only one in amd64 main is foreign –, negative dependencies do not even
    exist. Neither class has a native specimen, so no package in jessie is
    effected by this bug, but it might be interesting for stretch upgrades.
    This also means the regression potential is very low.
    
    Closes: 777760

diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 4eef66c..213235c 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -770,7 +770,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
 	 if (NewDepends(Ver,Package,"none",Version,Op,Type) == false)
 	    return false;
       }
-      else if (MultiArchEnabled == true && found != string::npos &&
+      else if (found != string::npos &&
 	       strcmp(Package.c_str() + found, ":any") != 0)
       {
 	 string Arch = Package.substr(found+1, string::npos);
diff --git a/test/integration/test-multiarch-foreign b/test/integration/test-multiarch-foreign
index 332466d..240f1a4 100755
--- a/test/integration/test-multiarch-foreign
+++ b/test/integration/test-multiarch-foreign
@@ -7,9 +7,13 @@ setupenvironment
 configarchitecture 'amd64' 'i386' 'armel'
 
 insertpackage 'unstable' 'cool-foo' 'amd64,i386' '1.0' 'Depends: foo'
+insertpackage 'unstable' 'cool-foo-x64' 'amd64' '1.0' 'Depends: foo:amd64'
+insertpackage 'unstable' 'cool-foo-x32' 'amd64' '1.0' 'Depends: foo:i386'
 insertpackage 'unstable' 'foo' 'amd64,i386,armel' '1.0' 'Multi-Arch: foreign'
 
 insertpackage 'unstable' 'cool-bar' 'amd64,i386' '1.0' 'Depends: bar-provider'
+insertpackage 'unstable' 'cool-bar-x64' 'amd64' '1.0' 'Depends: bar-provider:amd64'
+insertpackage 'unstable' 'cool-bar-x32' 'amd64' '1.0' 'Depends: bar-provider:i386'
 insertpackage 'unstable' 'bar' 'amd64,i386,armel' '1.0' 'Provides: bar-provider
 Multi-Arch: foreign'
 
@@ -29,28 +33,6 @@ Conf cool-foo:i386 (1.0 unstable [i386])' aptget install cool-foo:i386 -s
 
 testequal 'Reading package lists...
 Building dependency tree...
-The following extra packages will be installed:
-  foo
-The following NEW packages will be installed:
-  cool-foo foo
-0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
-Inst foo (1.0 unstable [amd64])
-Inst cool-foo (1.0 unstable [amd64])
-Conf foo (1.0 unstable [amd64])
-Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 -s
-
-testequal 'Reading package lists...
-Building dependency tree...
-The following NEW packages will be installed:
-  cool-foo foo
-0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
-Inst foo (1.0 unstable [amd64])
-Inst cool-foo (1.0 unstable [amd64])
-Conf foo (1.0 unstable [amd64])
-Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 foo:amd64 -s
-
-testequal 'Reading package lists...
-Building dependency tree...
 The following NEW packages will be installed:
   cool-foo foo:i386
 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
@@ -69,10 +51,6 @@ Inst cool-foo (1.0 unstable [amd64])
 Conf foo:armel (1.0 unstable [armel])
 Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 foo:armel -s
 
-
-
-
-
 testequal 'Reading package lists...
 Building dependency tree...
 The following extra packages will be installed:
@@ -87,6 +65,60 @@ Conf cool-bar:i386 (1.0 unstable [i386])' aptget install cool-bar:i386 -s
 
 testequal 'Reading package lists...
 Building dependency tree...
+The following NEW packages will be installed:
+  bar:i386 cool-bar
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst bar:i386 (1.0 unstable [i386])
+Inst cool-bar (1.0 unstable [amd64])
+Conf bar:i386 (1.0 unstable [i386])
+Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:i386 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  bar:armel cool-bar
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst bar:armel (1.0 unstable [armel])
+Inst cool-bar (1.0 unstable [amd64])
+Conf bar:armel (1.0 unstable [armel])
+Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:armel -s
+
+testequal "Reading package lists...
+Building dependency tree...
+Note, selecting 'bar:i386' instead of 'bar-provider:i386'
+The following NEW packages will be installed:
+  bar:i386 cool-bar
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst bar:i386 (1.0 unstable [i386])
+Inst cool-bar (1.0 unstable [amd64])
+Conf bar:i386 (1.0 unstable [i386])
+Conf cool-bar (1.0 unstable [amd64])" aptget install cool-bar bar-provider:i386 -s -q=0
+
+satisfiable_in_singlearch() {
+	testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  foo
+The following NEW packages will be installed:
+  cool-foo foo
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst foo (1.0 unstable [amd64])
+Inst cool-foo (1.0 unstable [amd64])
+Conf foo (1.0 unstable [amd64])
+Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 -s
+
+	testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  cool-foo foo
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst foo (1.0 unstable [amd64])
+Inst cool-foo (1.0 unstable [amd64])
+Conf foo (1.0 unstable [amd64])
+Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 foo:amd64 -s
+
+	testequal 'Reading package lists...
+Building dependency tree...
 The following extra packages will be installed:
   bar
 The following NEW packages will be installed:
@@ -97,7 +129,7 @@ Inst cool-bar (1.0 unstable [amd64])
 Conf bar (1.0 unstable [amd64])
 Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 -s
 
-testequal 'Reading package lists...
+	testequal 'Reading package lists...
 Building dependency tree...
 The following NEW packages will be installed:
   bar cool-bar
@@ -107,44 +139,71 @@ Inst cool-bar (1.0 unstable [amd64])
 Conf bar (1.0 unstable [amd64])
 Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:amd64 -s
 
-testequal 'Reading package lists...
+	testequal "Reading package lists...
 Building dependency tree...
+Note, selecting 'bar' instead of 'bar-provider'
 The following NEW packages will be installed:
-  bar:i386 cool-bar
+  bar cool-bar
 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
-Inst bar:i386 (1.0 unstable [i386])
+Inst bar (1.0 unstable [amd64])
 Inst cool-bar (1.0 unstable [amd64])
-Conf bar:i386 (1.0 unstable [i386])
-Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:i386 -s
+Conf bar (1.0 unstable [amd64])
+Conf cool-bar (1.0 unstable [amd64])" aptget install cool-bar bar-provider -s -q=0
 
-testequal 'Reading package lists...
+	testequal 'Reading package lists...
 Building dependency tree...
+The following extra packages will be installed:
+  foo
 The following NEW packages will be installed:
-  bar:armel cool-bar
+  cool-foo-x64 foo
 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
-Inst bar:armel (1.0 unstable [armel])
-Inst cool-bar (1.0 unstable [amd64])
-Conf bar:armel (1.0 unstable [armel])
-Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:armel -s
+Inst foo (1.0 unstable [amd64])
+Inst cool-foo-x64 (1.0 unstable [amd64])
+Conf foo (1.0 unstable [amd64])
+Conf cool-foo-x64 (1.0 unstable [amd64])' aptget install cool-foo-x64 -s
+}
 
-testequal "Reading package lists...
+#FIXME: do not work in single-arch as i386 isn't known at cache generation time
+	testequal 'Reading package lists...
 Building dependency tree...
-Note, selecting 'bar' instead of 'bar-provider'
+The following extra packages will be installed:
+  foo
 The following NEW packages will be installed:
-  bar cool-bar
+  cool-foo-x32 foo
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst foo (1.0 unstable [amd64])
+Inst cool-foo-x32 (1.0 unstable [amd64])
+Conf foo (1.0 unstable [amd64])
+Conf cool-foo-x32 (1.0 unstable [amd64])' aptget install cool-foo-x32 -s
+
+	testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  bar
+The following NEW packages will be installed:
+  bar cool-bar-x32
 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
 Inst bar (1.0 unstable [amd64])
-Inst cool-bar (1.0 unstable [amd64])
+Inst cool-bar-x32 (1.0 unstable [amd64])
 Conf bar (1.0 unstable [amd64])
-Conf cool-bar (1.0 unstable [amd64])" aptget install cool-bar bar-provider -s -q=0
+Conf cool-bar-x32 (1.0 unstable [amd64])' aptget install cool-bar-x32 -s -q=0
 
-testequal "Reading package lists...
+	testequal 'Reading package lists...
 Building dependency tree...
-Note, selecting 'bar:i386' instead of 'bar-provider:i386'
+The following extra packages will be installed:
+  bar
 The following NEW packages will be installed:
-  bar:i386 cool-bar
+  bar cool-bar-x64
 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
-Inst bar:i386 (1.0 unstable [i386])
-Inst cool-bar (1.0 unstable [amd64])
-Conf bar:i386 (1.0 unstable [i386])
-Conf cool-bar (1.0 unstable [amd64])" aptget install cool-bar bar-provider:i386 -s -q=0
+Inst bar (1.0 unstable [amd64])
+Inst cool-bar-x64 (1.0 unstable [amd64])
+Conf bar (1.0 unstable [amd64])
+Conf cool-bar-x64 (1.0 unstable [amd64])' aptget install cool-bar-x64 -s -q=0
+
+
+satisfiable_in_singlearch
+
+msgmsg 'switch to single architecture'
+configarchitecture 'amd64'
+
+satisfiable_in_singlearch
diff --git a/test/integration/test-specific-architecture-dependencies b/test/integration/test-specific-architecture-dependencies
index 078a846..ccfced1 100755
--- a/test/integration/test-specific-architecture-dependencies
+++ b/test/integration/test-specific-architecture-dependencies
@@ -12,16 +12,19 @@ insertinstalledpackage 'provider' 'amd64' '1' 'Provides: foo'
 
 insertpackage 'unstable' 'pre-depender' 'all' '1' 'Pre-Depends: libc6:i386'
 insertpackage 'unstable' 'depender' 'all' '1' 'Depends: libc6:i386'
+insertpackage 'unstable' 'depender-x32' 'i386,amd64' '1' 'Depends: libc6:i386'
+insertpackage 'unstable' 'depender-x64' 'i386,amd64' '1' 'Depends: libc6:amd64'
 
 insertpackage 'unstable' 'breaker' 'all' '1' 'Breaks: libold (<< 2)'
-insertpackage 'unstable' 'breaker-x32' 'amd64' '1' 'Breaks: libold:i386 (<< 2)'
-insertpackage 'unstable' 'breaker-x64' 'i386' '1' 'Breaks: libold:amd64 (<< 2)'
+insertpackage 'unstable' 'breaker-x32' 'i386,amd64' '1' 'Breaks: libold:i386 (<< 2)'
+insertpackage 'unstable' 'breaker-x64' 'i386,amd64' '1' 'Breaks: libold:amd64 (<< 2)'
 # conflicts with no effect
 insertpackage 'unstable' 'oldconflictor' 'all' '1' 'Conflicts: libold (<< 0)'
 insertpackage 'unstable' 'oldconflictor-x32' 'amd64' '1' 'Conflicts: libold:i386 (<< 0)'
 insertpackage 'unstable' 'oldconflictor-x64' 'i386' '1' 'Conflicts: libold:amd64 (<< 0)'
 
 insertpackage 'unstable' 'foo-depender' 'i386,amd64' '1' 'Depends: foo'
+insertpackage 'unstable' 'foo-native-depender' 'amd64' '1' 'Depends: foo:amd64'
 insertpackage 'unstable' 'foo-foreign-depender' 'i386' '1' 'Depends: foo:amd64'
 
 insertpackage 'unstable' 'foo-conflictor' 'i386,amd64' '1' 'Conflicts: foo'
@@ -56,6 +59,54 @@ Conf depender (1 unstable [all])' aptget install depender -s
 
 testequal 'Reading package lists...
 Building dependency tree...
+The following extra packages will be installed:
+  libc6:i386
+The following NEW packages will be installed:
+  depender-x32:i386 libc6:i386
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst libc6:i386 (1 unstable [i386])
+Inst depender-x32:i386 (1 unstable [i386])
+Conf libc6:i386 (1 unstable [i386])
+Conf depender-x32:i386 (1 unstable [i386])' aptget install depender-x32:i386 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  libc6:i386
+The following NEW packages will be installed:
+  depender-x32 libc6:i386
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst libc6:i386 (1 unstable [i386])
+Inst depender-x32 (1 unstable [amd64])
+Conf libc6:i386 (1 unstable [i386])
+Conf depender-x32 (1 unstable [amd64])' aptget install depender-x32:amd64 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  libc6
+The following NEW packages will be installed:
+  depender-x64 libc6
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst libc6 (1 unstable [amd64])
+Inst depender-x64 (1 unstable [amd64])
+Conf libc6 (1 unstable [amd64])
+Conf depender-x64 (1 unstable [amd64])' aptget install depender-x64:amd64 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  libc6
+The following NEW packages will be installed:
+  depender-x64:i386 libc6
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst libc6 (1 unstable [amd64])
+Inst depender-x64:i386 (1 unstable [i386])
+Conf libc6 (1 unstable [amd64])
+Conf depender-x64:i386 (1 unstable [i386])' aptget install depender-x64:i386 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
 The following packages will be REMOVED:
   libold libold:i386
 The following NEW packages will be installed:
@@ -75,7 +126,29 @@ The following NEW packages will be installed:
 0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
 Remv libold:i386 [1]
 Inst breaker-x32 (1 unstable [amd64])
-Conf breaker-x32 (1 unstable [amd64])' aptget install breaker-x32 -s
+Conf breaker-x32 (1 unstable [amd64])' aptget install breaker-x32:amd64 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following packages will be REMOVED:
+  libold:i386
+The following NEW packages will be installed:
+  breaker-x32:i386
+0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
+Remv libold:i386 [1]
+Inst breaker-x32:i386 (1 unstable [i386])
+Conf breaker-x32:i386 (1 unstable [i386])' aptget install breaker-x32:i386 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following packages will be REMOVED:
+  libold
+The following NEW packages will be installed:
+  breaker-x64
+0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
+Remv libold [1]
+Inst breaker-x64 (1 unstable [amd64])
+Conf breaker-x64 (1 unstable [amd64])' aptget install breaker-x64:amd64 -s
 
 testequal 'Reading package lists...
 Building dependency tree...
@@ -86,7 +159,7 @@ The following NEW packages will be installed:
 0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
 Remv libold [1]
 Inst breaker-x64:i386 (1 unstable [i386])
-Conf breaker-x64:i386 (1 unstable [i386])' aptget install breaker-x64 -s
+Conf breaker-x64:i386 (1 unstable [i386])' aptget install breaker-x64:i386 -s
 
 testequal 'Reading package lists...
 Building dependency tree...
@@ -135,6 +208,14 @@ E: Unable to correct problems, you have held broken packages.' aptget install fo
 testequal 'Reading package lists...
 Building dependency tree...
 The following NEW packages will be installed:
+  foo-native-depender
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst foo-native-depender (1 unstable [amd64])
+Conf foo-native-depender (1 unstable [amd64])' aptget install foo-native-depender -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
   foo-foreign-depender:i386
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
 Inst foo-foreign-depender:i386 (1 unstable [i386])
@@ -180,3 +261,62 @@ The following NEW packages will be installed:
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
 Inst foo-no-conflictor:i386 (1 unstable [i386])
 Conf foo-no-conflictor:i386 (1 unstable [i386])' aptget install foo-no-conflictor:i386 -s
+
+msgmsg 'switch to single architecture'
+configarchitecture 'amd64'
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  libc6
+The following NEW packages will be installed:
+  depender-x64 libc6
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst libc6 (1 unstable [amd64])
+Inst depender-x64 (1 unstable [amd64])
+Conf libc6 (1 unstable [amd64])
+Conf depender-x64 (1 unstable [amd64])' aptget install depender-x64 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+E: Unable to locate package depender-x64' aptget install depender-x64:i386 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  foo-native-depender
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst foo-native-depender (1 unstable [amd64])
+Conf foo-native-depender (1 unstable [amd64])' aptget install foo-native-depender -s
+
+# libold:i386 is installed, but we don't see it as i386 isn't configured
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  breaker-x32
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst breaker-x32 (1 unstable [amd64])
+Conf breaker-x32 (1 unstable [amd64])' aptget install breaker-x32:amd64 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following packages will be REMOVED:
+  libold
+The following NEW packages will be installed:
+  breaker-x64
+0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
+Remv libold [1]
+Inst breaker-x64 (1 unstable [amd64])
+Conf breaker-x64 (1 unstable [amd64])' aptget install breaker-x64:amd64 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ depender-x32 : Depends: libc6:i386 but it is not installable
+E: Unable to correct problems, you have held broken packages.' aptget install depender-x32 -s

Attachment: signature.asc
Description: Digital signature


Reply to: