Sfoglia il codice sorgente

Fix SmartConfigure to ignore ordering of packages that are already valid

With the change of SmartConfigure() in git commit 42d51f the ordering
code was trying to re-order dependencies, even when at this point in
time this was not needed. Now it will first check all targets of the
given dependency and only if there is not a good one try to reorder
and unpack/configure as needed.

Closes: LP: #1347721
Michael Vogt 12 anni fa
parent
commit
2f58969150

+ 48 - 1
apt-pkg/packagemanager.cc

@@ -372,6 +372,8 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
    std::list<DepIterator> needConfigure;
    do
    {
+      // Check each dependency and see if anything needs to be done
+      // so that it can be configured
       Changed = false;
       for (DepIterator D = instVer.DependsList(); D.end() == false; )
       {
@@ -383,7 +385,8 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 	    continue;
 	 Bad = true;
 
-	 // Check for dependencies that have not been unpacked, probably due to loops.
+         // the first pass checks if we its all good, i.e. if we have
+         // to do anything at all
 	 for (DepIterator Cur = Start; true; ++Cur)
 	 {
 	    SPtrArray<Version *> VList = Cur.AllTargets();
@@ -402,6 +405,47 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 		  break;
 	       }
 
+	       // Check if the version that is going to be installed will satisfy the dependency
+	       if (Cache[DepPkg].InstallVer != *I || List->IsNow(DepPkg) == false)
+		  continue;
+
+	       if (PkgLoop == true)
+	       {
+		  if (Debug)
+		     std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure" << std::endl;
+	          Bad = false;
+	       }
+	    }
+
+            if (Cur == End || Bad == false)
+	       break;
+         }
+
+         // this dependency is in a good state, so we can stop
+         if (Bad == false)
+         {
+            if (Debug)
+               std::clog << OutputInDepth(Depth) << "Found ok dep " << D.TargetPkg() << std::endl;
+            continue;
+         }
+
+	 // Check for dependencies that have not been unpacked, 
+         // probably due to loops.
+	 for (DepIterator Cur = Start; true; ++Cur)
+	 {
+	    SPtrArray<Version *> VList = Cur.AllTargets();
+
+	    for (Version **I = VList; *I != 0; ++I)
+	    {
+	       VerIterator Ver(Cache,*I);
+	       PkgIterator DepPkg = Ver.ParentPkg();
+
+	       // Check if the current version of the package is available and will satisfy this dependency
+	       if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true &&
+		   List->IsFlag(DepPkg,pkgOrderList::Removed) == false &&
+		   DepPkg.State() == PkgIterator::NeedsNothing)
+                  continue;
+
 	       // Check if the version that is going to be installed will satisfy the dependency
 	       if (Cache[DepPkg].InstallVer != *I || List->IsNow(DepPkg) == false)
 		  continue;
@@ -419,6 +463,8 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 		  if (NonLoopingSmart(UNPACK_IMMEDIATE, Pkg, DepPkg, Depth, PkgLoop, &Bad, &Changed) == false)
 		     return false;
 	       }
+               // at this point we either unpacked a Dep or we are in a loop,
+               // no need to unpack a second one
 	       break;
 	    }
 
@@ -435,6 +481,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
          return _error->Error("Internal error: MaxLoopCount reached in SmartUnPack (1) for %s, aborting", Pkg.FullName().c_str());
    } while (Changed == true);
 
+   // now go over anything that needs configuring
    Bad = false, Changed = false, i = 0;
    do
    {

File diff suppressed because it is too large
+ 445 - 0
test/integration/Packages-bug-lp1347721-dpkg-ordering


File diff suppressed because it is too large
+ 1942 - 0
test/integration/status-bug-lp1347721-dpkg-ordering


+ 11 - 0
test/integration/test-bug-lp1347721-dpkg-ordering

@@ -0,0 +1,11 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture "i386"
+setupaptarchive
+
+# ensure we find a valid ordering
+testsuccess aptget dist-upgrade -s