diff options
| author | Julian Andres Klode <jak@debian.org> | 2023-07-11 13:47:17 +0000 |
|---|---|---|
| committer | Julian Andres Klode <jak@debian.org> | 2023-07-11 13:47:17 +0000 |
| commit | 7bb2b81090b1a5bd9ebb49a0d9fd5cfd9ddab95f (patch) | |
| tree | c7b46bfd6100fd4634fdfa00a39336ad57a10c83 /apt-pkg | |
| parent | 50efb65f339e715e04af114bca44c9b8c53ad3ad (diff) | |
| parent | 68ef41ea912f4879b0ee43419c13a3a8c9bfcd22 (diff) | |
Merge branch 'pu/ubuntu-bug-2025462' into 'main'
dist-upgrade: Revert phased updates using keeps only
See merge request apt-team/apt!299
Diffstat (limited to 'apt-pkg')
| -rw-r--r-- | apt-pkg/algorithms.cc | 3 | ||||
| -rw-r--r-- | apt-pkg/algorithms.h | 19 | ||||
| -rw-r--r-- | apt-pkg/upgrade.cc | 47 |
3 files changed, 55 insertions, 14 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 272917b08..3d4096a94 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1234,7 +1234,8 @@ bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I) } // a newly broken policy (recommends/suggests) is a problem - if (Cache[I].NowPolicyBroken() == false && + if ((Flags[I->ID] & BrokenPolicyAllowed) == 0 && + Cache[I].NowPolicyBroken() == false && Cache[I].InstPolicyBroken() == true) { if (Debug == true) diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 12a77d4b8..f06a38c1b 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -102,10 +102,16 @@ class APT_PUBLIC pkgProblemResolver /*{{{*/ typedef pkgCache::PrvIterator PrvIterator; typedef pkgCache::Version Version; typedef pkgCache::Package Package; - - enum Flags {Protected = (1 << 0), PreInstalled = (1 << 1), - Upgradable = (1 << 2), ReInstateTried = (1 << 3), - ToRemove = (1 << 4)}; + + enum Flags + { + Protected = (1 << 0), + PreInstalled = (1 << 1), + Upgradable = (1 << 2), + ReInstateTried = (1 << 3), + ToRemove = (1 << 4), + BrokenPolicyAllowed = (1 << 5) + }; int *Scores; unsigned char *Flags; bool Debug; @@ -129,7 +135,10 @@ class APT_PUBLIC pkgProblemResolver /*{{{*/ inline void Protect(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] |= Protected; Cache.MarkProtected(Pkg);}; inline void Remove(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] |= ToRemove;}; - inline void Clear(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] &= ~(Protected | ToRemove);}; + inline void Clear(pkgCache::PkgIterator Pkg) { Flags[Pkg->ID] &= ~(Protected | ToRemove | BrokenPolicyAllowed); }; +#ifdef APT_COMPILING_APT + inline void AllowBrokenPolicy(pkgCache::PkgIterator Pkg) { Flags[Pkg->ID] |= BrokenPolicyAllowed; }; +#endif // Try to intelligently resolve problems by installing and removing packages bool Resolve(bool BrokenFix = false, OpProgress * const Progress = NULL); diff --git a/apt-pkg/upgrade.cc b/apt-pkg/upgrade.cc index e3e98e5c6..994a05859 100644 --- a/apt-pkg/upgrade.cc +++ b/apt-pkg/upgrade.cc @@ -85,13 +85,13 @@ struct PhasedUpgrader { if (Pkg->CurrentVer == 0) return false; - if (Cache[Pkg].InstallVer == 0) + if (Cache[Pkg].CandidateVer == 0) return false; - if (Cache[Pkg].InstVerIter(Cache).PhasedUpdatePercentage() == 100) + if (Cache[Pkg].CandidateVerIter(Cache).PhasedUpdatePercentage() == 100) return false; - if (IsSecurityUpdate(Cache[Pkg].InstVerIter(Cache))) + if (IsSecurityUpdate(Cache[Pkg].CandidateVerIter(Cache))) return false; - if (!IsIgnoredPhasedUpdate(Cache[Pkg].InstVerIter(Cache))) + if (!IsIgnoredPhasedUpdate(Cache[Pkg].CandidateVerIter(Cache))) return false; return true; @@ -133,15 +133,18 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) Progress->OverallProgress(0, 100, 1, _("Calculating upgrade")); pkgDepCache::ActionGroup group(Cache); - - PhasedUpgrader().HoldBackIgnoredPhasedUpdates(Cache, nullptr); + PhasedUpgrader phasedUpgrader; /* Upgrade all installed packages first without autoinst to help the resolver in versioned or-groups to upgrade the old solver instead of installing a new one (if the old solver is not the first one [anymore]) */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + { + if (phasedUpgrader.ShouldKeep(Cache, I)) + continue; if (I->CurrentVer != 0) Cache.MarkInstall(I, false, 0, false); + } if (Progress != NULL) Progress->Progress(10); @@ -149,8 +152,12 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) /* Auto upgrade all installed packages, this provides the basis for the installation */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + { + if (phasedUpgrader.ShouldKeep(Cache, I)) + continue; if (I->CurrentVer != 0) Cache.MarkInstall(I, true, 0, false); + } if (Progress != NULL) Progress->Progress(50); @@ -178,13 +185,19 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) if (isEssential == false || instEssential == true) continue; pkgCache::PkgIterator P = G.FindPreferredPkg(); + if (phasedUpgrader.ShouldKeep(Cache, P)) + continue; Cache.MarkInstall(P, true, 0, false); } } else if (essential != "none") for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + { + if (phasedUpgrader.ShouldKeep(Cache, I)) + continue; if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) Cache.MarkInstall(I, true, 0, false); + } if (Progress != NULL) Progress->Progress(55); @@ -192,8 +205,12 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) /* We do it again over all previously installed packages to force conflict resolution on them all. */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + { + if (phasedUpgrader.ShouldKeep(Cache, I)) + continue; if (I->CurrentVer != 0) Cache.MarkInstall(I, false, 0, false); + } if (Progress != NULL) Progress->Progress(65); @@ -216,9 +233,23 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) } } - PhasedUpgrader().HoldBackIgnoredPhasedUpdates(Cache, &Fix); + bool success = Fix.ResolveInternal(false); + if (success) + { + // Revert phased updates using keeps. An issue with ResolveByKeep is + // that it also keeps back packages due to (new) broken Recommends, + // even if Upgrade already decided this is fine, so we will mark all + // packages that dist-upgrade decided may have a broken policy as allowed + // to do so such that we do not keep them back again. + pkgProblemResolver FixPhasing(&Cache); + + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + if (Cache[I].InstPolicyBroken()) + FixPhasing.AllowBrokenPolicy(I); + PhasedUpgrader().HoldBackIgnoredPhasedUpdates(Cache, &FixPhasing); + success = FixPhasing.ResolveByKeepInternal(); + } - bool const success = Fix.ResolveInternal(false); if (Progress != NULL) Progress->Done(); return success; |
