Przeglądaj źródła

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 lat temu
rodzic
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
    {

Plik diff jest za duży
+ 445 - 0
test/integration/Packages-bug-lp1347721-dpkg-ordering


Plik diff jest za duży
+ 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