summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2020-05-18 01:03:52 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2020-05-18 15:55:36 +0200
commit1f641cf70e9cd52c093b4b62dc392f29cf34f03e (patch)
treeac76f9a5b5423ae850a6711a9262c5d16a41f6fe /apt-pkg
parentdbed89f296106f82e9fe8f866fa87a4c14b44584 (diff)
Recognize propagated protected in pkgProblemResolver
Turns out that pkgDepCache and pkgProblemResolver maintain two (semi) independent sets of protected flags – except that a package if marked protected in the pkgProblemResolver is automatically also marked in the pkgDepCache as protected. This way the pkgProblemResolver will have as protected only the direct user requests while pkgDepCache will (hopefully) propagate the flag to unavoidable dependencies of these requests nowadays. The pkgProblemResolver was only checking his own protected flag though and based on that calls our Mark* methods usually without checking return, leading to it believing it could e.g. remove packages it actually can't remove as pkgDepCache will not allow it as it is marked as protected there. Teaching it to check for the flag in the pkgDepCache instead avoids it believing in the wrong things eventually giving up. The scoring is keeping the behaviour of adding the large score boost only for the direct user requests though as there is no telling which other sideeffects this might have if too many packages get too many points from the get-go. Second part of fixing #960705, now with pkgProblemResolver output which looks more like the whole class of problem is resolved rather than a teeny tiny edgecase it was before.
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/algorithms.cc23
1 files changed, 12 insertions, 11 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index f2977b9af..f000b7f39 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -599,7 +599,8 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
Flags[Pkg->ID] &= ~Upgradable;
bool WasKept = Cache[Pkg].Keep();
- Cache.MarkInstall(Pkg, false, 0, false);
+ if (not Cache.MarkInstall(Pkg, false, 0, false))
+ return false;
// This must be a virtual package or something like that.
if (Cache[Pkg].InstVerIter(Cache).end() == true)
@@ -633,7 +634,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
// Do not change protected packages
PkgIterator P = Start.SmartTargetPkg();
- if ((Flags[P->ID] & Protected) == Protected)
+ if (Cache[P].Protect())
{
if (Debug == true)
clog << " Reinst Failed because of protected " << P.FullName(false) << endl;
@@ -800,7 +801,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
if (Cache[I].CandidateVer != Cache[I].InstallVer &&
I->CurrentVer != 0 && Cache[I].InstallVer != 0 &&
(Flags[I->ID] & PreInstalled) != 0 &&
- (Flags[I->ID] & Protected) == 0 &&
+ not Cache[I].Protect() &&
(Flags[I->ID] & ReInstateTried) == 0)
{
if (Debug == true)
@@ -849,7 +850,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
{
if (OrOp == OrRemove)
{
- if ((Flags[I->ID] & Protected) != Protected)
+ if (not Cache[I].Protect())
{
if (Debug == true)
clog << " Or group remove for " << I.FullName(false) << endl;
@@ -903,7 +904,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
targets then we keep the package and bail. This is necessary
if a package has a dep on another package that can't be found */
std::unique_ptr<pkgCache::Version *[]> VList(Start.AllTargets());
- if (VList[0] == 0 && (Flags[I->ID] & Protected) != Protected &&
+ if (VList[0] == 0 && not Cache[I].Protect() &&
Start.IsNegative() == false &&
Cache[I].NowBroken() == false)
{
@@ -950,7 +951,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
End.IsNegative() == false))
{
// Try a little harder to fix protected packages..
- if ((Flags[I->ID] & Protected) == Protected)
+ if (Cache[I].Protect())
{
if (DoUpgrade(Pkg) == true)
{
@@ -1037,7 +1038,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
}
// Skip adding to the kill list if it is protected
- if ((Flags[Pkg->ID] & Protected) != 0)
+ if (Cache[Pkg].Protect())
continue;
if (Debug == true)
@@ -1053,7 +1054,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
// Hm, nothing can possibly satisfy this dep. Nuke it.
if (VList[0] == 0 &&
Start.IsNegative() == false &&
- (Flags[I->ID] & Protected) != Protected)
+ not Cache[I].Protect())
{
bool Installed = Cache[I].Install();
Cache.MarkKeep(I);
@@ -1133,7 +1134,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
{
if (Cache[I].InstBroken() == false)
continue;
- if ((Flags[I->ID] & Protected) != Protected)
+ if (not Cache[I].Protect())
return _error->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages."));
}
return _error->Error(_("Unable to correct problems, you have held broken packages."));
@@ -1253,7 +1254,7 @@ bool pkgProblemResolver::ResolveByKeepInternal()
/* Keep the package. If this works then great, otherwise we have
to be significantly more aggressive and manipulate its dependencies */
- if ((Flags[I->ID] & Protected) == 0)
+ if (not Cache[I].Protect())
{
if (Debug == true)
clog << "Keeping package " << I.FullName(false) << endl;
@@ -1301,7 +1302,7 @@ bool pkgProblemResolver::ResolveByKeepInternal()
Pkg->CurrentVer == 0)
continue;
- if ((Flags[I->ID] & Protected) == 0)
+ if (not Cache[I].Protect())
{
if (Debug == true)
clog << " Keeping Package " << Pkg.FullName(false) << " due to " << Start.DepType() << endl;