From 4264ebebe1826781e5b863a13041a6972ace01db Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Mon, 27 Jun 2011 14:34:00 +0100 Subject: Initial commit from my GSoC project. Added a verification function (VerifyConfigure) to the configuration methods. --- apt-pkg/packagemanager.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'apt-pkg/packagemanager.h') diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index 053b4dc13..070b9c04b 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -73,7 +73,9 @@ class pkgPackageManager : protected pkgCache::Namespace bool SmartUnPack(PkgIterator Pkg); bool SmartUnPack(PkgIterator Pkg, bool const Immediate); bool SmartRemove(PkgIterator Pkg); - bool EarlyRemove(PkgIterator Pkg); + bool EarlyRemove(PkgIterator Pkg); + bool VerifyAndConfigure(PkgIterator Pkg, pkgOrderList &OList); + bool VerifyConfigure(PkgIterator Pkg, pkgOrderList &OList); // The Actual installation implementation virtual bool Install(PkgIterator /*Pkg*/,string /*File*/) {return false;}; -- cgit v1.2.3-70-g09d2 From a6c8798a6390b5c3a0775f8914e1cff2795e4cc1 Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Wed, 6 Jul 2011 22:13:59 +0100 Subject: Added a APT::Immediate-Configure-All option to enable imediate configuration for all packages. Began adding to the SmartUnpack method to prevent dependancy loops breaking apt. --- apt-pkg/packagemanager.cc | 105 +++++++++++++++++++++++++++++++++++++++++----- apt-pkg/packagemanager.h | 1 + 2 files changed, 95 insertions(+), 11 deletions(-) (limited to 'apt-pkg/packagemanager.h') diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index a39e412bd..ad59470ac 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -167,6 +167,10 @@ bool pkgPackageManager::CreateOrderList() List = new pkgOrderList(&Cache); static bool const NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true); + ImmConfigureAll = _config->FindB("APT::Immediate-Configure-All",true); + + if (Debug && ImmConfigureAll) + clog << "CreateOrderList(): Adding Immediate flag for all packages because of APT::Immediate-Configure-All" << endl; // Generate the list of affected packages and sort it for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) @@ -176,19 +180,23 @@ bool pkgPackageManager::CreateOrderList() continue; // Mark the package and its dependends for immediate configuration - if (((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential || + if ((((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential || (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) && - NoImmConfigure == false) + NoImmConfigure == false) || ImmConfigureAll) { - if(Debug) + if(Debug && !ImmConfigureAll) clog << "CreateOrderList(): Adding Immediate flag for " << I.Name() << endl; List->Flag(I,pkgOrderList::Immediate); + + if (!ImmConfigureAll) { + continue; - // Look for other install packages to make immediate configurea - ImmediateAdd(I, true); + // Look for other install packages to make immediate configurea + ImmediateAdd(I, true); - // And again with the current version. - ImmediateAdd(I, false); + // And again with the current version. + ImmediateAdd(I, false); + } } // Not interesting @@ -467,7 +475,33 @@ bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth) { VerIterator Ver(Cache,*I); PkgIterator Pkg = Ver.ParentPkg(); - + VerIterator InstallVer(Cache,Cache[Pkg].InstallVer); + + if (Debug) { + if (Ver==0) { + cout << OutputInDepth(Depth) << "Checking if the dependancy on " << Ver << " of " << Pkg.Name() << " is satisfied" << endl; + } else { + cout << OutputInDepth(Depth) << "Checking if the dependancy on " << Ver.VerStr() << " of " << Pkg.Name() << " is satisfied" << endl; + } + } + if (Debug) { + if (Pkg.CurrentVer()==0) { + cout << OutputInDepth(Depth) << " CurrentVer " << Pkg.CurrentVer() << " IsNow " << List->IsNow(Pkg) << " NeedsNothing " << (Pkg.State() == PkgIterator::NeedsNothing) << endl; + } else { + cout << OutputInDepth(Depth) << " CurrentVer " << Pkg.CurrentVer().VerStr() << " IsNow " << List->IsNow(Pkg) << " NeedsNothing " << (Pkg.State() == PkgIterator::NeedsNothing) << endl; + } + } + + if (Debug) { + if (InstallVer==0) { + cout << OutputInDepth(Depth )<< " InstallVer " << InstallVer << endl; + } else { + cout << OutputInDepth(Depth )<< " InstallVer " << InstallVer.VerStr() << endl; + } + } + if (Debug) + cout << OutputInDepth(Depth) << " Keep " << Cache[Pkg].Keep() << " Unpacked " << List->IsFlag(Pkg,pkgOrderList::UnPacked) << " Configured " << List->IsFlag(Pkg,pkgOrderList::Configured) << endl; + // See if the current version is ok if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true && Pkg.State() == PkgIterator::NeedsNothing) @@ -475,6 +509,8 @@ bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth) Bad = false; continue; } + + // Keep() , if upgradable, is the package left at the install version // Not the install version if (Cache[Pkg].InstallVer != *I || @@ -591,7 +627,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) "Please see man 5 apt.conf under APT::Immediate-Configure for details."),Pkg.Name()); return true; } - + VerIterator const instVer = Cache[Pkg].InstVerIter(Cache); /* See if this packages install version has any predependencies @@ -655,7 +691,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) End.TargetPkg().Name(),Pkg.Name()); Start++; } - else + else break; } @@ -693,10 +729,56 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) packages it breaks) breaks Pkg */ List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); // Found a break, so unpack the package + if (Debug) + cout << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl; SmartUnPack(BrokenPkg, false); } } } + + // Check for dependanices that have not been unpacked, probably due to loops. + bool Bad = true; + while (End->Type == pkgCache::Dep::Depends) { + PkgIterator DepPkg; + SPtrArray VList = Start.AllTargets(); + + for (Version **I = VList; *I != 0; I++) { + VerIterator Ver(Cache,*I); + DepPkg = Ver.ParentPkg(); + + if (!Bad) continue; + + if (Debug) + cout << " Checking dep on " << DepPkg.Name() << endl; + // Check if it satisfies this dependancy + if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true && + DepPkg.State() == PkgIterator::NeedsNothing) + { + Bad = false; + continue; + } + + if (Cache[DepPkg].InstallVer == *I && !List->IsNow(DepPkg)) { + Bad = false; + continue; + } + } + + if (Start==End) { + if (Bad) { + // FIXME Setting the flag here prevents a loop forming + List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); + // Found a break, so unpack the package + if (Debug) + cout << " Unpacking " << DepPkg.Name() << " to avoid loop" << endl; + //SmartUnPack(DepPkg, false); + } + break; + + } else { + Start++; + } + } } // Check for reverse conflicts. @@ -728,7 +810,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) if (Immediate == true && List->IsFlag(Pkg,pkgOrderList::Immediate) == true) if (SmartConfigure(Pkg) == false) - return _error->Error(_("Could not perform immediate configuration on '%s'. " + //return + _error->Error(_("Could not perform immediate configuration on '%s'. " "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2); return true; diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index 070b9c04b..dcc9dc2a2 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -48,6 +48,7 @@ class pkgPackageManager : protected pkgCache::Namespace pkgDepCache &Cache; pkgOrderList *List; bool Debug; + bool ImmConfigureAll; /** \brief saves packages dpkg let disappear -- cgit v1.2.3-70-g09d2 From b684d8c7b15fbbebb149afac4e374b025c1b335e Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Sat, 16 Jul 2011 22:10:52 +0100 Subject: Dont try to configure packages using SmartConfigure when not performing immediate configuration. --- apt-pkg/packagemanager.cc | 6 +++--- apt-pkg/packagemanager.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'apt-pkg/packagemanager.h') diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 874472a47..8112c7fa1 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -166,7 +166,7 @@ bool pkgPackageManager::CreateOrderList() delete List; List = new pkgOrderList(&Cache); - static bool const NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true); + NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true); ImmConfigureAll = _config->FindB("APT::Immediate-Configure-All",false); if (Debug && ImmConfigureAll) @@ -982,11 +982,11 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() if (List->IsNow(Pkg) == false) { - if (!List->IsFlag(Pkg,pkgOrderList::Configured)) { + if (!List->IsFlag(Pkg,pkgOrderList::Configured) && !NoImmConfigure) { if (SmartConfigure(Pkg) == false && Debug) _error->Warning("Internal Error, Could not configure %s",Pkg.Name()); // FIXME: The above warning message might need changing - } else { + } else { if (Debug == true) clog << "Skipping already done " << Pkg.Name() << endl; } diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index dcc9dc2a2..d4a25e982 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -48,6 +48,7 @@ class pkgPackageManager : protected pkgCache::Namespace pkgDepCache &Cache; pkgOrderList *List; bool Debug; + bool NoImmConfigure; bool ImmConfigureAll; /** \brief saves packages dpkg let disappear -- cgit v1.2.3-70-g09d2 From 590f1923121815b36ef889033c1c416a23cbe9a2 Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Wed, 27 Jul 2011 15:20:35 +0100 Subject: SmartConfigure and SmartUnPack have got smarter! The full descriptions of what they now do is in the apt-pkg/packagemanager.cc file. The short version is that they will both put the system in a state where there operation can be achived, this involves calling themselves and each other recursively. Because SmartConfigure can now configure a package and all its dependancies itself, there is no current need for DepAdd (at least in packagemanager.cc), SmartConfigure also performs the function of the short lived VerifyConfigure as it checks through all the dependancies before performing configuration. Another change is to use the ConfigureAll method in OrderInstall to clean up any packages left unconfigured during ImmConfigureAll. This is necessary to inprove the safety of ImmConfiguration and because of the new SIGINT functionality of dpkgpm.cc relies on no packages being left unconfigured between pairs of dpkg calls. While writing this commit log, I have realised that the SIGINT stuff is a prototype and not ready to be used yet as I have only tested it twice. --- apt-pkg/deb/dpkgpm.cc | 15 +- apt-pkg/deb/dpkgpm.h | 2 + apt-pkg/packagemanager.cc | 434 ++++++++++++++-------------------------------- apt-pkg/packagemanager.h | 4 +- 4 files changed, 141 insertions(+), 314 deletions(-) (limited to 'apt-pkg/packagemanager.h') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 5fbd1801a..3dbbd7c97 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -888,7 +889,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) OpenLog(); // this loop is runs once per operation - for (vector::const_iterator I = List.begin(); I != List.end();) + for (vector::const_iterator I = List.begin(); I != List.end() && !pkgPackageManager::SigINTStop;) { // Do all actions with the same Op in one run vector::const_iterator J = I; @@ -920,7 +921,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) // the argument list is split in a way that A depends on B // and they are in the same "--configure A B" run // - with the split they may now be configured in different - // runs + // runs if (J - I > (signed)MaxArgs) J = I + MaxArgs; @@ -1062,7 +1063,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) it to all processes in the group. Since dpkg ignores the signal it doesn't die but we do! So we must also ignore it */ sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN); - sighandler_t old_SIGINT = signal(SIGINT,SIG_IGN); + sighandler_t old_SIGINT = signal(SIGINT,SigINT); // ignore SIGHUP as well (debian #463030) sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN); @@ -1207,6 +1208,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) // Restore sig int/quit signal(SIGQUIT,old_SIGQUIT); signal(SIGINT,old_SIGINT); + signal(SIGHUP,old_SIGHUP); return _error->Errno("waitpid","Couldn't wait for subprocess"); } @@ -1247,6 +1249,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) // Restore sig int/quit signal(SIGQUIT,old_SIGQUIT); signal(SIGINT,old_SIGINT); + signal(SIGHUP,old_SIGHUP); if(master >= 0) @@ -1308,6 +1311,12 @@ bool pkgDPkgPM::Go(int OutStatusFd) Cache.writeStateFile(NULL); return true; } + +void SigINT(int sig) { + cout << " -- SIGINT -- " << endl; + if (_config->FindB("APT::Immediate-Configure-All",false)) + pkgPackageManager::SigINTStop = true; +} /*}}}*/ // pkgDpkgPM::Reset - Dump the contents of the command list /*{{{*/ // --------------------------------------------------------------------- diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index b7b5a6def..fb92c58ea 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -113,4 +113,6 @@ class pkgDPkgPM : public pkgPackageManager virtual ~pkgDPkgPM(); }; +void SigINT(int sig); + #endif diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 8112c7fa1..8bcf3d884 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -29,6 +29,8 @@ /*}}}*/ using namespace std; +bool pkgPackageManager::SigINTStop = false; + // PM::PackageManager - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -262,7 +264,8 @@ bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D, // PM::ConfigureAll - Run the all out configuration /*{{{*/ // --------------------------------------------------------------------- /* This configures every package. It is assumed they are all unpacked and - that the final configuration is valid. */ + that the final configuration is valid. This is also used to catch packages + that have not been configured when using ImmConfigureAll */ bool pkgPackageManager::ConfigureAll() { pkgOrderList OList(&Cache); @@ -284,7 +287,7 @@ bool pkgPackageManager::ConfigureAll() { PkgIterator Pkg(Cache,*I); - if (ConfigurePkgs == true && VerifyAndConfigure(Pkg,OList) == false) { + if (ConfigurePkgs == true && SmartConfigure(Pkg) == false) { _error->Error("Internal error, packages left unconfigured. %s",Pkg.Name()); return false; } @@ -297,244 +300,142 @@ bool pkgPackageManager::ConfigureAll() /*}}}*/ // PM::SmartConfigure - Perform immediate configuration of the pkg /*{{{*/ // --------------------------------------------------------------------- -/* This routine scheduals the configuration of the given package and all - of it's dependents. */ +/* This routine trys to put the system in a state where Pkg can be configured, + this involves checking each of Pkg's dependanies and unpacking and + configuring packages where needed. */ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) { if (Debug == true) clog << "SmartConfigure " << Pkg.Name() << endl; - - pkgOrderList OList(&Cache); - - if (DepAdd(OList,Pkg) == false) - return false; - - static std::string const conf = _config->Find("PackageManager::Configure","all"); - static bool const ConfigurePkgs = (conf == "all" || conf == "smart"); - - if (ConfigurePkgs == true) - if (OList.OrderConfigure() == false) - return false; - - // Perform the configuring - for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++) - { - PkgIterator Pkg(Cache,*I); - - if (ConfigurePkgs == true && VerifyAndConfigure(Pkg,OList) == false) - return false; - List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); - } - - if (Cache[Pkg].InstVerIter(Cache)->MultiArch == pkgCache::Version::Same) - for (PkgIterator P = Pkg.Group().PackageList(); - P.end() == false; P = Pkg.Group().NextPkg(P)) - { - if (Pkg == P || List->IsFlag(P,pkgOrderList::Configured) == true || - Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer && - (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) - continue; - SmartConfigure(P); - } - - // Sanity Check - if (List->IsFlag(Pkg,pkgOrderList::Configured) == false && Debug) - _error->Error(_("Could not perform immediate configuration on '%s'. " - "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1); - - return true; -} - -// PM::VerifyConfigure - Check configuration of dependancies /*{{{*/ -// --------------------------------------------------------------------- -/* This routine checks that all a packages dependancies have been - configured, before it is going to be configured. If this gives a warning - on a virtual package, it means that the package thats providing it is not - configured*/ -bool pkgPackageManager::VerifyConfigure(PkgIterator Pkg, pkgOrderList &OList) -{ - // If this is true at the end, then the package should not be configured - bool error=true; - // This holds the the OR status of the previous dependancy - bool previousOr=false; - - // First iterate through the dependancies of Pkg - for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false; D++) - { - - /* If the dependancy is of type Depends or PreDepends, we need to check it, but only if it is going to be - configured at some point */ - if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) { - - /* If the previous package and this package are OR dependancies, and the previous package satisfied the dependancy - then skip this dependancy as it is not relevent, this will repeat for the next package if the situation is the - same */ - if (previousOr && !error) { // As error has not been reset, this refers to the previous dependancy - previousOr = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; - continue; - } - - // Reset error - error = true; - - // Check thorugh all possible versions of this dependancy (D) - SPtrArray VList = D.AllTargets(); - for (Version **I = VList; *I != 0; I++) - { - VerIterator DepVer(Cache,*I); - PkgIterator DepPkg = DepVer.ParentPkg(); - VerIterator DepInstallVer(Cache,Cache[DepPkg].InstallVer); - - if (DepPkg.CurrentVer() == DepVer && !List->IsFlag(DepPkg,pkgOrderList::UnPacked)) { - error=false; - break; - } - - if (Cache[DepPkg].InstallVer == DepVer && - (List->IsFlag(DepPkg,pkgOrderList::Configured) || OList.IsFlag(DepPkg,pkgOrderList::InList))) { - error=false; - break; - } - } - - /* Only worry here if this package is a OR with the next, as even though this package does not satisfy the OR - the next one might */ - if (error && !((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)) { - _error->Error("Package %s should not be configured because package %s is not configured",Pkg.Name(),D.TargetPkg().Name()); - return false; - /* If the previous package is a OR but not this package, but there is still an error then fail as it will not - be satisfied */ - } else if (error && previousOr && !((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)) { - _error->Error("Package %s should not be configured because package %s (or any alternatives) are not configured",Pkg.Name(),D.TargetPkg().Name()); - return false; - } - - previousOr = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; - } else { - previousOr=false; - } - } - return true; -} - -// PM::VerifyAndConfigure - Check configuration of dependancies /*{{{*/ -// --------------------------------------------------------------------- -/* This routine verifies if a package can be configured and if so - configures it */ -bool pkgPackageManager::VerifyAndConfigure(PkgIterator Pkg, pkgOrderList &OList) -{ - if (VerifyConfigure(Pkg, OList)) - return Configure(Pkg); - else - return false; - -} - /*}}}*/ -// PM::DepAdd - Add all dependents to the oder list /*{{{*/ -// --------------------------------------------------------------------- -/* This recursively adds all dependents to the order list */ -bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth) -{ - if (OList.IsFlag(Pkg,pkgOrderList::Added) == true) - return true; - if (List->IsFlag(Pkg,pkgOrderList::Configured) == true) - return true; - if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false) - return false; - - if (Debug) - std::clog << OutputInDepth(Depth) << "DepAdd: " << Pkg.Name() << std::endl; + VerIterator const instVer = Cache[Pkg].InstVerIter(Cache); - // Put the package on the list - OList.push_back(Pkg); - OList.Flag(Pkg,pkgOrderList::Added); - Depth++; - - // Check the dependencies to see if they are all satisfied. + /* Because of the ordered list, most dependancies should be unpacked, + however if there is a loop this is not the case, so check for dependancies before configuring. + This is done after the package installation as it makes it easier to deal with conflicts problems */ bool Bad = false; - for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false;) + for (DepIterator D = instVer.DependsList(); + D.end() == false; ) { - if (D->Type != pkgCache::Dep::Depends && D->Type != pkgCache::Dep::PreDepends) - { - D++; - continue; - } + // Compute a single dependency element (glob or) + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); - // Grok or groups - Bad = true; - for (bool LastOR = true; D.end() == false && LastOR == true; D++) - { - LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; - - if (Bad == false) - continue; + if (End->Type == pkgCache::Dep::Depends) + Bad = true; - SPtrArray VList = D.AllTargets(); - for (Version **I = VList; *I != 0 && Bad == true; I++) - { + // Check for dependanices that have not been unpacked, probably due to loops. + while (End->Type == pkgCache::Dep::Depends) { + PkgIterator DepPkg; + VerIterator InstallVer; + SPtrArray VList = Start.AllTargets(); + + for (Version **I = VList; *I != 0; I++) { VerIterator Ver(Cache,*I); - PkgIterator Pkg = Ver.ParentPkg(); - VerIterator InstallVer(Cache,Cache[Pkg].InstallVer); - VerIterator CandVer(Cache,Cache[Pkg].CandidateVer); + DepPkg = Ver.ParentPkg(); + + if (!Bad) continue; + + InstallVer = VerIterator(Cache,Cache[DepPkg].InstallVer); + //VerIterator CandVer(Cache,Cache[DepPkg].CandidateVer); if (Debug && false) { if (Ver==0) { - cout << OutputInDepth(Depth) << "Checking if " << Ver << " of " << Pkg.Name() << " satisfies this dependancy" << endl; + cout << " Checking if " << Ver << " of " << DepPkg.Name() << " satisfies this dependancy" << endl; } else { - cout << OutputInDepth(Depth) << "Checking if " << Ver.VerStr() << " of " << Pkg.Name() << " satisfies this dependancy" << endl; + cout << " Checking if " << Ver.VerStr() << " of " << DepPkg.Name() << " satisfies this dependancy" << endl; } - - if (Pkg.CurrentVer()==0) { - cout << OutputInDepth(Depth) << " CurrentVer " << Pkg.CurrentVer() << " IsNow " << List->IsNow(Pkg) << " NeedsNothing " << (Pkg.State() == PkgIterator::NeedsNothing) << endl; + + if (DepPkg.CurrentVer()==0) { + cout << " CurrentVer " << DepPkg.CurrentVer() << " IsNow " << List->IsNow(DepPkg) << " NeedsNothing " << (DepPkg.State() == PkgIterator::NeedsNothing) << endl; } else { - cout << OutputInDepth(Depth) << " CurrentVer " << Pkg.CurrentVer().VerStr() << " IsNow " << List->IsNow(Pkg) << " NeedsNothing " << (Pkg.State() == PkgIterator::NeedsNothing) << endl; + cout << " CurrentVer " << DepPkg.CurrentVer().VerStr() << " IsNow " << List->IsNow(DepPkg) << " NeedsNothing " << (DepPkg.State() == PkgIterator::NeedsNothing) << endl; } - + if (InstallVer==0) { - cout << OutputInDepth(Depth )<< " InstallVer " << InstallVer << endl; + cout << " InstallVer " << InstallVer << endl; } else { - cout << OutputInDepth(Depth )<< " InstallVer " << InstallVer.VerStr() << endl; + cout << " InstallVer " << InstallVer.VerStr() << endl; } - if (CandVer != 0) - cout << OutputInDepth(Depth ) << " CandVer " << CandVer.VerStr() << endl; + //if (CandVer != 0) + // cout << " CandVer " << CandVer.VerStr() << endl; - cout << OutputInDepth(Depth) << " Keep " << Cache[Pkg].Keep() << " Unpacked " << List->IsFlag(Pkg,pkgOrderList::UnPacked) << " Configured " << List->IsFlag(Pkg,pkgOrderList::Configured) << endl; + cout << " Keep " << Cache[DepPkg].Keep() << " Unpacked " << List->IsFlag(DepPkg,pkgOrderList::UnPacked) << " Configured " << List->IsFlag(DepPkg,pkgOrderList::Configured) << endl; } - // See if the current version is ok - if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true && - Pkg.State() == PkgIterator::NeedsNothing) + + // Check if it satisfies this dependancy + if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true && + DepPkg.State() == PkgIterator::NeedsNothing) { Bad = false; continue; } - // Not the install version - if ((Cache[Pkg].InstallVer != *I && Cache[Pkg].CandidateVer != *I) || - (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing && - (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) + if (Cache[DepPkg].InstallVer == *I) { + if (List->IsFlag(DepPkg,pkgOrderList::UnPacked)) { + if (!List->IsFlag(DepPkg,pkgOrderList::Loop)) { + List->Flag(Pkg,pkgOrderList::Loop); + Bad = !SmartConfigure(DepPkg); + } else { + Bad = false; + } + } else if (List->IsFlag(DepPkg,pkgOrderList::Configured)) { + Bad = false; + } continue; - - if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == true) - Bad = !DepAdd(OList,Pkg,Depth); - if (List->IsFlag(Pkg,pkgOrderList::Configured) == true) - Bad = false; + } } + + if (InstallVer != 0 && Bad) { + Bad = false; + List->Flag(Pkg,pkgOrderList::Loop); + if (!List->IsFlag(DepPkg,pkgOrderList::Loop)) { + if (Debug) + cout << " Unpacking " << DepPkg.Name() << " to avoid loop" << endl; + SmartUnPack(DepPkg, true); + } + } + + if (Start==End) { + if (Bad && Debug) { + if (!List->IsFlag(DepPkg,pkgOrderList::Loop)) { + _error->Warning("Could not satisfy dependancies for %s",Pkg.Name()); + } + } + break; + + } else { + Start++; + } } + } + + static std::string const conf = _config->Find("PackageManager::Configure","all"); + static bool const ConfigurePkgs = (conf == "all" || conf == "smart"); + + if (ConfigurePkgs == true && Configure(Pkg) == false) + return false; - if (Bad == true) + List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); + + if (Cache[Pkg].InstVerIter(Cache)->MultiArch == pkgCache::Version::Same) + for (PkgIterator P = Pkg.Group().PackageList(); + P.end() == false; P = Pkg.Group().NextPkg(P)) { - if (Debug) - std::clog << OutputInDepth(Depth) << "DepAdd FAILS on: " << Pkg.Name() << std::endl; - OList.Flag(Pkg,0,pkgOrderList::Added); - OList.pop_back(); - Depth--; - return false; + if (Pkg == P || List->IsFlag(P,pkgOrderList::Configured) == true || + Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer && + (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) + continue; + SmartConfigure(P); } - } - - Depth--; + + // Sanity Check + if (List->IsFlag(Pkg,pkgOrderList::Configured) == false && Debug) + _error->Warning(_("Could not perform immediate configuration on '%s'. " + "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1); + return true; } /*}}}*/ @@ -603,7 +504,8 @@ bool pkgPackageManager::SmartRemove(PkgIterator Pkg) /*}}}*/ // PM::SmartUnPack - Install helper /*{{{*/ // --------------------------------------------------------------------- -/* This performs the task of handling pre-depends. */ +/* This puts the system in a state where it can Unpack Pkg, if Pkg is allready + unpacked, or when it has been unpacked, if Immediate==true it configures it. */ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) { return SmartUnPack(Pkg, true); @@ -628,8 +530,11 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) VerIterator const instVer = Cache[Pkg].InstVerIter(Cache); - /* See if this packages install version has any predependencies - that are not met by 'now' packages. */ + /* PreUnpack Checks: This loop checks and attemps to rectify and problems that would prevent the package being unpacked. + It addresses: PreDepends, Conflicts, Obsoletes and DpkgBreaks. Any resolutions that do not require it should + avoid configuration (calling SmartUnpack with Immediate=true), this is because any loops before Pkg is unpacked + can cause problems. This will be either dealt with if the package is configured as a dependancy of + Pkg (if and when Pkg is configured), or by the ConfigureAll call at the end of the for loop in OrderInstall. */ for (DepIterator D = instVer.DependsList(); D.end() == false; ) { @@ -763,7 +668,6 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) PkgIterator BrokenPkg = Ver.ParentPkg(); VerIterator InstallVer(Cache,Cache[BrokenPkg].InstallVer); - cout << " " << Pkg.Name() << " breaks " << BrokenPkg.Name() << endl; if (Debug && false) { if (Ver==0) { cout << " Checking if " << Ver << " of " << BrokenPkg.Name() << " satisfies this dependancy" << endl; @@ -793,6 +697,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) // Found a break, so unpack the package if (Debug) cout << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl; + /* */ SmartUnPack(BrokenPkg, false); } // Check if a package needs to be removed @@ -846,106 +751,13 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) if(Install(Pkg,FileNames[Pkg->ID]) == false) return false; - /* Because of the ordered list, most dependancies should be unpacked, - however if there is a loop this is not the case, so check for dependancies before configuring. - This is done after the package installation as it makes it easier to deal with conflicts problems */ - bool Bad = true; - for (DepIterator D = instVer.DependsList(); - D.end() == false; ) - { - // Compute a single dependency element (glob or) - pkgCache::DepIterator Start; - pkgCache::DepIterator End; - D.GlobOr(Start,End); - - if (End->Type == pkgCache::Dep::Depends) - Bad = true; - - // Check for dependanices that have not been unpacked, probably due to loops. - while (End->Type == pkgCache::Dep::Depends) { - PkgIterator DepPkg; - VerIterator InstallVer; - SPtrArray VList = Start.AllTargets(); - - for (Version **I = VList; *I != 0; I++) { - VerIterator Ver(Cache,*I); - DepPkg = Ver.ParentPkg(); - - if (!Bad) continue; - - InstallVer = VerIterator(Cache,Cache[DepPkg].InstallVer); - VerIterator CandVer(Cache,Cache[DepPkg].CandidateVer); - - if (Debug && false) { - if (Ver==0) { - cout << " Checking if " << Ver << " of " << DepPkg.Name() << " satisfies this dependancy" << endl; - } else { - cout << " Checking if " << Ver.VerStr() << " of " << DepPkg.Name() << " satisfies this dependancy" << endl; - } - - if (DepPkg.CurrentVer()==0) { - cout << " CurrentVer " << DepPkg.CurrentVer() << " IsNow " << List->IsNow(DepPkg) << " NeedsNothing " << (DepPkg.State() == PkgIterator::NeedsNothing) << endl; - } else { - cout << " CurrentVer " << DepPkg.CurrentVer().VerStr() << " IsNow " << List->IsNow(DepPkg) << " NeedsNothing " << (DepPkg.State() == PkgIterator::NeedsNothing) << endl; - } - - if (InstallVer==0) { - cout << " InstallVer " << InstallVer << endl; - } else { - cout << " InstallVer " << InstallVer.VerStr() << endl; - } - if (CandVer != 0) - cout << " CandVer " << CandVer.VerStr() << endl; - - cout << " Keep " << Cache[DepPkg].Keep() << " Unpacked " << List->IsFlag(DepPkg,pkgOrderList::UnPacked) << " Configured " << List->IsFlag(DepPkg,pkgOrderList::Configured) << endl; - - } - - // Check if it satisfies this dependancy - if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true && - DepPkg.State() == PkgIterator::NeedsNothing) - { - Bad = false; - continue; - } - - if (Cache[DepPkg].InstallVer == *I && !List->IsNow(DepPkg)) { - Bad = false; - continue; - } - } - - if (InstallVer != 0 && Bad) { - Bad = false; - // Found a break, so unpack the package - List->Flag(Pkg,pkgOrderList::Loop); - if (!List->IsFlag(DepPkg,pkgOrderList::Loop)) { - if (Debug) - cout << " Unpacking " << DepPkg.Name() << " to avoid loop" << endl; - SmartUnPack(DepPkg, false); - } - } - - if (Start==End) { - if (Bad && Debug) { - if (!List->IsFlag(DepPkg,pkgOrderList::Loop)) { - _error->Warning("Could not satisfy dependancies for %s",Pkg.Name()); - } - } - break; - - } else { - Start++; - } - } - } + if (Immediate == true && List->IsFlag(Pkg,pkgOrderList::Immediate) == true) { - // Perform immedate configuration of the package. - if (Immediate == true && - List->IsFlag(Pkg,pkgOrderList::Immediate) == true && !Bad) - if (SmartConfigure(Pkg) == false) - _error->Warning(_("Could not perform immediate configuration on '%s'. " - "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2); + // Perform immedate configuration of the package. + if (SmartConfigure(Pkg) == false) + _error->Warning(_("Could not perform immediate configuration on '%s'. " + "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2); + } return true; } @@ -1025,6 +837,12 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() if (SmartUnPack(Pkg) == false) return Failed; DoneSomething = true; + + if (ImmConfigureAll) { + /* ConfigureAll here to pick up and packages left unconfigured becuase they were unpacked in the + "PreUnpack Checks" section */ + ConfigureAll(); + } } // Final run through the configure phase diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index d4a25e982..e1878ce46 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -42,6 +42,7 @@ class pkgPackageManager : protected pkgCache::Namespace public: enum OrderResult {Completed,Failed,Incomplete}; + static bool SigINTStop; protected: string *FileNames; @@ -59,7 +60,6 @@ class pkgPackageManager : protected pkgCache::Namespace */ std::set disappearedPkgs; - bool DepAdd(pkgOrderList &Order,PkgIterator P,int Depth = 0); void ImmediateAdd(PkgIterator P, bool UseInstallVer, unsigned const int &Depth = 0); virtual OrderResult OrderInstall(); bool CheckRConflicts(PkgIterator Pkg,DepIterator Dep,const char *Ver); @@ -76,8 +76,6 @@ class pkgPackageManager : protected pkgCache::Namespace bool SmartUnPack(PkgIterator Pkg, bool const Immediate); bool SmartRemove(PkgIterator Pkg); bool EarlyRemove(PkgIterator Pkg); - bool VerifyAndConfigure(PkgIterator Pkg, pkgOrderList &OList); - bool VerifyConfigure(PkgIterator Pkg, pkgOrderList &OList); // The Actual installation implementation virtual bool Install(PkgIterator /*Pkg*/,string /*File*/) {return false;}; -- cgit v1.2.3-70-g09d2 From d41d0e0113208aa1752344a13e8a962a1ad4f76e Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Mon, 15 Aug 2011 22:31:09 +0100 Subject: Fixed a bug where SmartUnPack would be called with Immediate=true (to resolve dependancies in SmartConfigure) yet Pkg would not be immediately configured. This was because SmartUnPack still required the immediate flag to be set on Pkg. Also inproved the debuging adding indented output for SmartUnPack and SmartConfigure and specifying in the output if SmartConfigure or SmartUnPack was called just to Correct something (PkgLoop = true) or not. --- apt-pkg/packagemanager.cc | 75 +++++++++++++++++++++++++---------------------- apt-pkg/packagemanager.h | 4 +-- 2 files changed, 42 insertions(+), 37 deletions(-) (limited to 'apt-pkg/packagemanager.h') diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 4c827af6d..53bb507b6 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -291,7 +291,7 @@ bool pkgPackageManager::ConfigureAll() calls its self */ if (List->IsFlag(Pkg,pkgOrderList::Configured)) continue; - if (ConfigurePkgs == true && SmartConfigure(Pkg) == false) { + if (ConfigurePkgs == true && SmartConfigure(Pkg, 0) == false) { if (ImmConfigureAll) _error->Error(_("Could not perform immediate configuration on '%s'. " "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1); @@ -318,16 +318,19 @@ bool pkgPackageManager::ConfigureAll() a error will only be reported if ConfigureAll fails. This is why some of the messages this function reports on failure (return false;) as just warnings only shown when debuging*/ -bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) +bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth) { + // If this is true, only check and correct and dependancies without the Loop flag + bool PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop); + if (Debug) { VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer); - clog << "SmartConfigure " << Pkg.Name() << " " << InstallVer.VerStr() << endl; + clog << OutputInDepth(Depth) << "SmartConfigure " << Pkg.Name() << " (" << InstallVer.VerStr() << ")"; + if (PkgLoop) + clog << " (Only Correct Dependancies)"; + clog << endl; } - // If this is true, only check and correct and dependancies without the Loop flag - bool PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop); - VerIterator const instVer = Cache[Pkg].InstVerIter(Cache); /* Because of the ordered list, most dependancies should be unpacked, @@ -378,7 +381,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) just hop between them if this is not checked */ List->Flag(Pkg,pkgOrderList::Loop); // If SmartConfigure was succesfull, Bad is false, so break - Bad = !SmartConfigure(DepPkg); + Bad = !SmartConfigure(DepPkg, Depth + 1); List->RmFlag(Pkg,pkgOrderList::Loop); if (!Bad) break; } else if (List->IsFlag(DepPkg,pkgOrderList::Configured)) { @@ -394,8 +397,8 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) if (List->IsNow(DepPkg) && !List->IsFlag(DepPkg,pkgOrderList::Loop)) { List->Flag(Pkg,pkgOrderList::Loop); if (Debug) - cout << " Unpacking " << DepPkg.Name() << " to avoid loop" << endl; - SmartUnPack(DepPkg, true); + cout << OutputInDepth(Depth) << "Unpacking " << DepPkg.Name() << " to avoid loop" << endl; + SmartUnPack(DepPkg, true, Depth + 1); List->RmFlag(Pkg,pkgOrderList::Loop); } } @@ -440,7 +443,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer && (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) continue; - SmartConfigure(P); + SmartConfigure(P, (Depth +1)); } // Sanity Check @@ -519,29 +522,32 @@ bool pkgPackageManager::SmartRemove(PkgIterator Pkg) unpacked, or when it has been unpacked, if Immediate==true it configures it. */ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) { - return SmartUnPack(Pkg, true); + return SmartUnPack(Pkg, true, 0); } -bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) +bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int const Depth) { + bool PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop); + if (Debug) { - clog << "SmartUnPack " << Pkg.Name(); + clog << OutputInDepth(Depth) << "SmartUnPack " << Pkg.Name(); VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer); if (Pkg.CurrentVer() == 0) - cout << " (install version " << InstallVer.VerStr() << ")" << endl; + cout << " (install version " << InstallVer.VerStr() << ")"; else - cout << " (replace version " << Pkg.CurrentVer().VerStr() << " with " << InstallVer.VerStr() << ")" << endl; + cout << " (replace version " << Pkg.CurrentVer().VerStr() << " with " << InstallVer.VerStr() << ")"; + if (PkgLoop) + cout << " (Only Perform PreUnpack Checks)"; + cout << endl; } // Check if it is already unpacked if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && Cache[Pkg].Keep() == true) { - cout << "SmartUnPack called on Package " << Pkg.Name() << " but its unpacked" << endl; + cout << OutputInDepth(Depth) << "SmartUnPack called on Package " << Pkg.Name() << " but its unpacked" << endl; return false; } - bool PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop); - VerIterator const instVer = Cache[Pkg].InstVerIter(Cache); /* PreUnpack Checks: This loop checks and attempts to rectify and problems that would prevent the package being unpacked. @@ -561,7 +567,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) while (End->Type == pkgCache::Dep::PreDepends) { if (Debug) - clog << "PreDepends order for " << Pkg.Name() << std::endl; + clog << OutputInDepth(Depth) << "PreDepends order for " << Pkg.Name() << std::endl; // Look for possible ok targets. SPtrArray VList = Start.AllTargets(); @@ -577,7 +583,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) { Bad = false; if (Debug) - clog << "Found ok package " << Pkg.Name() << endl; + clog << OutputInDepth(Depth) << "Found ok package " << Pkg.Name() << endl; continue; } } @@ -599,8 +605,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) } if (Debug) - clog << "Trying to SmartConfigure " << Pkg.Name() << endl; - Bad = !SmartConfigure(Pkg); + clog << OutputInDepth(Depth) << "Trying to SmartConfigure " << Pkg.Name() << endl; + Bad = !SmartConfigure(Pkg, Depth + 1); } /* If this or element did not match then continue on to the @@ -633,15 +639,15 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) // See if the current version is conflicting if (ConflictPkg.CurrentVer() == Ver && List->IsNow(ConflictPkg)) { - cout << Pkg.Name() << " conflicts with " << ConflictPkg.Name() << endl; + cout << OutputInDepth(Depth) << Pkg.Name() << " conflicts with " << ConflictPkg.Name() << endl; /* If a loop is not present or has not yet been detected, attempt to unpack packages to resolve this conflict. If there is a loop present, remove packages to resolve this conflict */ if (!List->IsFlag(ConflictPkg,pkgOrderList::Loop)) { if (Cache[ConflictPkg].Keep() == 0 && Cache[ConflictPkg].InstallVer != 0) { if (Debug) - cout << "Unpacking " << ConflictPkg.Name() << " to prevent conflict" << endl; + cout << OutputInDepth(Depth) << OutputInDepth(Depth) << "Unpacking " << ConflictPkg.Name() << " to prevent conflict" << endl; List->Flag(Pkg,pkgOrderList::Loop); - SmartUnPack(ConflictPkg,false); + SmartUnPack(ConflictPkg,false, Depth + 1); // Remove loop to allow it to be used later if needed List->RmFlag(Pkg,pkgOrderList::Loop); } else { @@ -651,7 +657,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) } else { if (!List->IsFlag(ConflictPkg,pkgOrderList::Removed)) { if (Debug) - cout << "Because of conficts knot, removing " << ConflictPkg.Name() << " to conflict violation" << endl; + cout << OutputInDepth(Depth) << "Because of conficts knot, removing " << ConflictPkg.Name() << " to conflict violation" << endl; if (EarlyRemove(ConflictPkg) == false) return _error->Error("Internal Error, Could not early remove %s",ConflictPkg.Name()); } @@ -679,15 +685,15 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) List->Flag(Pkg,pkgOrderList::Loop); // Found a break, so unpack the package if (Debug) - cout << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl; + cout << OutputInDepth(Depth) << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl; - SmartUnPack(BrokenPkg, false); + SmartUnPack(BrokenPkg, false, Depth + 1); List->RmFlag(Pkg,pkgOrderList::Loop); } // Check if a package needs to be removed if (Cache[BrokenPkg].Delete() == true && !List->IsFlag(BrokenPkg,pkgOrderList::Configured)) { if (Debug) - cout << " Removing " << BrokenPkg.Name() << " to avoid break" << endl; + cout << OutputInDepth(Depth) << " Removing " << BrokenPkg.Name() << " to avoid break" << endl; SmartRemove(BrokenPkg); } } @@ -715,16 +721,15 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer && (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) continue; - SmartUnPack(P, false); + SmartUnPack(P, false, Depth + 1); } if(Install(Pkg,FileNames[Pkg->ID]) == false) return false; - if (Immediate == true && List->IsFlag(Pkg,pkgOrderList::Immediate) == true) { - + if (Immediate == true) { // Perform immedate configuration of the package. - if (SmartConfigure(Pkg) == false) + if (SmartConfigure(Pkg, Depth + 1) == false) _error->Warning(_("Could not perform immediate configuration on '%s'. " "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2); } @@ -765,7 +770,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() if (List->IsNow(Pkg) == false) { if (!List->IsFlag(Pkg,pkgOrderList::Configured) && !NoImmConfigure) { - if (SmartConfigure(Pkg) == false && Debug) + if (SmartConfigure(Pkg, 0) == false && Debug) _error->Warning("Internal Error, Could not configure %s",Pkg.Name()); // FIXME: The above warning message might need changing } else { @@ -804,7 +809,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() return Failed; } else - if (SmartUnPack(Pkg) == false) + if (SmartUnPack(Pkg,List->IsFlag(Pkg,pkgOrderList::Immediate),0) == false) return Failed; DoneSomething = true; diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index e1878ce46..96dc5f236 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -70,10 +70,10 @@ class pkgPackageManager : protected pkgCache::Namespace // Install helpers bool ConfigureAll(); - bool SmartConfigure(PkgIterator Pkg); + bool SmartConfigure(PkgIterator Pkg, int const Depth); //FIXME: merge on abi break bool SmartUnPack(PkgIterator Pkg); - bool SmartUnPack(PkgIterator Pkg, bool const Immediate); + bool SmartUnPack(PkgIterator Pkg, bool const Immediate, int const Depth); bool SmartRemove(PkgIterator Pkg); bool EarlyRemove(PkgIterator Pkg); -- cgit v1.2.3-70-g09d2