diff --git a/0009-Do-not-minimize-from-an-installed-to-an-uninstalled-.patch b/0009-Do-not-minimize-from-an-installed-to-an-uninstalled-.patch new file mode 100644 index 0000000..351ff3a --- /dev/null +++ b/0009-Do-not-minimize-from-an-installed-to-an-uninstalled-.patch @@ -0,0 +1,152 @@ +From af1731646829f799f837b009c3a24e246f64d857 Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Wed, 6 Sep 2023 14:10:17 +0200 +Subject: [PATCH 1/3] Do not minimize from an installed to an uninstalled + package when checking recommends + +Also prune to installed packages (or their update candidates) +when doing extra reordering, i.e. when the update roles are +not yet resolved. + +Fixes issue #539 +--- + src/solver.c | 94 +++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 63 insertions(+), 31 deletions(-) + +diff --git a/src/solver.c b/src/solver.c +index b1a10c0d..2963223f 100644 +--- a/src/solver.c ++++ b/src/solver.c +@@ -1135,6 +1135,58 @@ queue_prunezeros(Queue *q) + queue_truncate(q, j); + } + ++static int ++replaces_installed_package(Pool *pool, Id p, Map *noupdate) ++{ ++ Repo *installed = pool->installed; ++ Solvable *s = pool->solvables + p, *s2; ++ Id p2, pp2; ++ Id obs, *obsp; ++ ++ if (s->repo == installed && !(noupdate && MAPTST(noupdate, p - installed->start))) ++ return 1; ++ FOR_PROVIDES(p2, pp2, s->name) ++ { ++ s2 = pool->solvables + p2; ++ if (s2->repo == installed && s2->name == s->name && !(noupdate && MAPTST(noupdate, p - installed->start))) ++ return 1; ++ } ++ if (!s->obsoletes) ++ return 0; ++ obsp = s->repo->idarraydata + s->obsoletes; ++ while ((obs = *obsp++) != 0) ++ { ++ FOR_PROVIDES(p2, pp2, obs) ++ { ++ s2 = pool->solvables + p2; ++ if (s2->repo != pool->installed || (noupdate && MAPTST(noupdate, p - installed->start))) ++ continue; ++ if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, s2, obs)) ++ continue; ++ if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2)) ++ continue; ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++static void ++prune_dq_for_future_installed(Solver *solv, Queue *dq) ++{ ++ Pool *pool = solv->pool; ++ int i, j; ++ for (i = j = 0; i < dq->count; i++) ++ { ++ Id p = dq->elements[i]; ++ if (replaces_installed_package(pool, p, &solv->noupdate)) ++ dq->elements[j++] = p; ++ } ++ if (j) ++ queue_truncate(dq, j); ++} ++ ++ + static void + reorder_dq_for_future_installed(Solver *solv, int level, Queue *dq) + { +@@ -1314,9 +1366,13 @@ selectandinstall(Solver *solv, int level, Queue *dq, int disablerules, Id ruleid + if (dq->count > 1) + policy_filter_unwanted(solv, dq, POLICY_MODE_CHOOSE); + /* if we're resolving rules and didn't resolve the installed packages yet, +- * do some special supplements ordering */ ++ * do some special pruning and supplements ordering */ + if (dq->count > 1 && solv->do_extra_reordering) +- reorder_dq_for_future_installed(solv, level, dq); ++ { ++ prune_dq_for_future_installed(solv, dq); ++ if (dq->count > 1) ++ reorder_dq_for_future_installed(solv, level, dq); ++ } + /* check if the candidates are all connected via yumobs rules */ + if (dq->count > 1 && solv->yumobsrules_end > solv->yumobsrules) + prune_yumobs(solv, dq, ruleid); +@@ -2935,6 +2991,8 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) + continue; + if (solv->favormap && solv->favormap[p] > solv->favormap[solv->branches.elements[lastsi]]) + continue; /* current selection is more favored */ ++ if (replaces_installed_package(pool, p, &solv->noupdate)) ++ continue; /* current selection replaces an installed package */ + if (!(MAPTST(&solv->recommendsmap, p) || solver_is_supplementing(solv, pool->solvables + p))) + { + lasti = lastsi; +@@ -4626,7 +4684,7 @@ pool_job2solvables(Pool *pool, Queue *pkgs, Id how, Id what) + int + pool_isemptyupdatejob(Pool *pool, Id how, Id what) + { +- Id p, pp, pi, pip; ++ Id p, pp; + Id select = how & SOLVER_SELECTMASK; + if ((how & SOLVER_JOBMASK) != SOLVER_UPDATE) + return 0; +@@ -4639,34 +4697,8 @@ pool_isemptyupdatejob(Pool *pool, Id how, Id what) + return 0; + /* hard work */ + FOR_JOB_SELECT(p, pp, select, what) +- { +- Solvable *s = pool->solvables + p; +- FOR_PROVIDES(pi, pip, s->name) +- { +- Solvable *si = pool->solvables + pi; +- if (si->repo != pool->installed || si->name != s->name) +- continue; +- return 0; +- } +- if (s->obsoletes) +- { +- Id obs, *obsp = s->repo->idarraydata + s->obsoletes; +- while ((obs = *obsp++) != 0) +- { +- FOR_PROVIDES(pi, pip, obs) +- { +- Solvable *si = pool->solvables + pi; +- if (si->repo != pool->installed) +- continue; +- if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, si, obs)) +- continue; +- if (pool->obsoleteusescolors && !pool_colormatch(pool, s, si)) +- continue; +- return 0; +- } +- } +- } +- } ++ if (replaces_installed_package(pool, p, 0)) ++ return 0; + return 1; + } + +-- +2.52.0 + diff --git a/0010-Use-the-correct-solvable-id-when-checking-the-noarch.patch b/0010-Use-the-correct-solvable-id-when-checking-the-noarch.patch new file mode 100644 index 0000000..fd3e463 --- /dev/null +++ b/0010-Use-the-correct-solvable-id-when-checking-the-noarch.patch @@ -0,0 +1,35 @@ +From e704dd6833f908a4e4960c976bab3ebfdcc397b2 Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Tue, 12 Nov 2024 10:44:07 +0100 +Subject: [PATCH 2/3] Use the correct solvable id when checking the noarch map + +Fixes issue #574 +--- + src/solver.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/solver.c b/src/solver.c +index 2963223f..a8a9aa74 100644 +--- a/src/solver.c ++++ b/src/solver.c +@@ -1148,7 +1148,7 @@ replaces_installed_package(Pool *pool, Id p, Map *noupdate) + FOR_PROVIDES(p2, pp2, s->name) + { + s2 = pool->solvables + p2; +- if (s2->repo == installed && s2->name == s->name && !(noupdate && MAPTST(noupdate, p - installed->start))) ++ if (s2->repo == installed && s2->name == s->name && !(noupdate && MAPTST(noupdate, p2 - installed->start))) + return 1; + } + if (!s->obsoletes) +@@ -1159,7 +1159,7 @@ replaces_installed_package(Pool *pool, Id p, Map *noupdate) + FOR_PROVIDES(p2, pp2, obs) + { + s2 = pool->solvables + p2; +- if (s2->repo != pool->installed || (noupdate && MAPTST(noupdate, p - installed->start))) ++ if (s2->repo != pool->installed || (noupdate && MAPTST(noupdate, p2 - installed->start))) + continue; + if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, s2, obs)) + continue; +-- +2.52.0 + diff --git a/0011-Implement-color-filtering-when-adding-update-targets.patch b/0011-Implement-color-filtering-when-adding-update-targets.patch new file mode 100644 index 0000000..08cfdae --- /dev/null +++ b/0011-Implement-color-filtering-when-adding-update-targets.patch @@ -0,0 +1,68 @@ +From 50e04ee7d6ea612b3b7193b4c0c4ff8484ca04dc Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Mon, 14 Apr 2025 14:14:59 +0200 +Subject: [PATCH 3/3] Implement color filtering when adding update targets + +The old code created update jobs spanning multiple architectures +even if "implicitobsoleteusescolors" was set. +Also add color filtering in replaces_installed_package, where it +seems to be also missing + +Fixes issue #583. +--- + src/solver.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/src/solver.c b/src/solver.c +index a8a9aa74..6fdeeb27 100644 +--- a/src/solver.c ++++ b/src/solver.c +@@ -1148,8 +1148,11 @@ replaces_installed_package(Pool *pool, Id p, Map *noupdate) + FOR_PROVIDES(p2, pp2, s->name) + { + s2 = pool->solvables + p2; +- if (s2->repo == installed && s2->name == s->name && !(noupdate && MAPTST(noupdate, p2 - installed->start))) +- return 1; ++ if (s2->name != s->name || s2->repo != installed || (noupdate && MAPTST(noupdate, p2 - installed->start))) ++ continue; ++ if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, s2)) ++ continue; ++ return 1; + } + if (!s->obsoletes) + return 0; +@@ -1159,7 +1162,7 @@ replaces_installed_package(Pool *pool, Id p, Map *noupdate) + FOR_PROVIDES(p2, pp2, obs) + { + s2 = pool->solvables + p2; +- if (s2->repo != pool->installed || (noupdate && MAPTST(noupdate, p2 - installed->start))) ++ if (s2->repo != installed || (noupdate && MAPTST(noupdate, p2 - installed->start))) + continue; + if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, s2, obs)) + continue; +@@ -3254,8 +3257,11 @@ add_update_target(Solver *solv, Id p, Id how) + FOR_PROVIDES(pi, pip, s->name) + { + Solvable *si = pool->solvables + pi; +- if (si->repo == installed && si->name == s->name && pi != p) +- queue_push2(solv->update_targets, pi, p); ++ if (si->repo != installed || si->name != s->name || pi == p) ++ continue; ++ if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, si)) ++ continue; ++ queue_push2(solv->update_targets, pi, p); + } + return; + } +@@ -3266,6 +3272,8 @@ add_update_target(Solver *solv, Id p, Id how) + Solvable *si = pool->solvables + pi; + if (si->repo != installed || si->name != s->name) + continue; ++ if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, si)) ++ continue; + if (how & SOLVER_FORCEBEST) + { + if (!solv->bestupdatemap.size) +-- +2.52.0 + diff --git a/0012-Add-testcase-for-color-filtering-when-adding-update-.patch b/0012-Add-testcase-for-color-filtering-when-adding-update-.patch new file mode 100644 index 0000000..89470a4 --- /dev/null +++ b/0012-Add-testcase-for-color-filtering-when-adding-update-.patch @@ -0,0 +1,74 @@ +From 24a7a79595a1f7e35a4ac430d3075e27a9a1fc2f Mon Sep 17 00:00:00 2001 +From: Evan Goode +Date: Tue, 20 Jan 2026 14:11:40 -0500 +Subject: [PATCH] Add testcase for color filtering when adding update targets + +Related: https://github.com/openSUSE/libsolv/issues/583 +--- + ...est_multiarch_implicitobsoleteusescolors.t | 54 +++++++++++++++++++ + 1 file changed, 54 insertions(+) + create mode 100644 test/testcases/forcebest/forcebest_multiarch_implicitobsoleteusescolors.t + +diff --git a/test/testcases/forcebest/forcebest_multiarch_implicitobsoleteusescolors.t b/test/testcases/forcebest/forcebest_multiarch_implicitobsoleteusescolors.t +new file mode 100644 +index 00000000..97660e36 +--- /dev/null ++++ b/test/testcases/forcebest/forcebest_multiarch_implicitobsoleteusescolors.t +@@ -0,0 +1,54 @@ ++repo @System 0 testtags ++#>=Ver: 3.0 ++#>=Pkg: a 1 1 x86_64 ++#>=Prv: a = 1-1 ++#>=Con: c < 1-1 ++#> ++#>=Pkg: c 1 1 x86_64 ++#>=Req: c-dep = 1-1 ++#>=Prv: c = 1-1 ++#> ++#>=Pkg: c-dep 1 1 x86_64 ++#>=Prv: c-dep = 1-1 ++#> ++#>=Pkg: d 1 1 x86_64 ++#>=Req: c = 1-1 ++#>=Req: multiarch = 1-1 ++#>=Prv: d = 1-1 ++#> ++#>=Pkg: multiarch 1 1 x86_64 ++#>=Prv: multiarch = 1-1 ++ ++repo available 0 testtags ++#>=Ver: 3.0 ++#>=Pkg: a 2 2 x86_64 ++#>=Prv: a = 2-2 ++#>=Con: c < 2-2 ++#> ++#>=Pkg: c 2 2 x86_64 ++#>=Req: c-dep = 2-2 ++#>=Prv: c = 2-2 ++#> ++#>=Pkg: c-dep 2 2 x86_64 ++#>=Prv: c-dep = 2-2 ++#> ++#>=Pkg: d 2 2 x86_64 ++#>=Req: multiarch >= 2-2 ++#>=Prv: d = 2-2 ++#> ++#>=Pkg: multiarch 2 2 x86_64 ++#>=Prv: multiarch = 2-2 ++#> ++#>=Pkg: multiarch 2 2 i686 ++#>=Prv: multiarch = 2-2 ++ ++system x86_64 rpm @System ++poolflags implicitobsoleteusescolors ++solverflags bestobeypolicy ++job update oneof a-2-2.x86_64@available multiarch-1-1.x86_64@@System multiarch-2-2.i686@available [forcebest,targeted,setevr,setarch] ++result transaction,problems ++#>upgrade a-1-1.x86_64@@System a-2-2.x86_64@available ++#>upgrade multiarch-1-1.x86_64@@System multiarch-2-2.x86_64@available ++#>upgrade c-dep-1-1.x86_64@@System c-dep-2-2.x86_64@available ++#>upgrade c-1-1.x86_64@@System c-2-2.x86_64@available ++#>upgrade d-1-1.x86_64@@System d-2-2.x86_64@available +-- +2.52.0 + diff --git a/libsolv.spec b/libsolv.spec index 14666d3..758b8f0 100644 --- a/libsolv.spec +++ b/libsolv.spec @@ -23,7 +23,7 @@ Name: lib%{libname} Version: 0.7.24 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Package dependency solver License: BSD @@ -38,6 +38,12 @@ Patch5: 0005-Treat-condition-both-as-positive-and-negative-litera.patch Patch6: 0006-Allow_break_arch_lock_step_on_erase.patch Patch7: libsolv-0.7.24-static_analysis_fixes.patch Patch8: libsolv-0.7.24-repo_conda-overwrite-the-package-subdir-with-the-inf.patch +Patch9: 0009-Do-not-minimize-from-an-installed-to-an-uninstalled-.patch +Patch10: 0010-Use-the-correct-solvable-id-when-checking-the-noarch.patch +Patch11: 0011-Implement-color-filtering-when-adding-update-targets.patch + +# Patch merged upstream: https://github.com/openSUSE/libsolv/pull/604 +Patch12: 0012-Add-testcase-for-color-filtering-when-adding-update-.patch BuildRequires: cmake BuildRequires: gcc-c++ @@ -264,6 +270,10 @@ export LD_LIBRARY_PATH=%{buildroot}%{_libdir} %endif %changelog +* Thu Jan 22 2026 Evan Goode - 0.7.24-4 +- Backport "Implement color filtering when adding update targets" + Resolves: RHEL-103995 + * Tue Apr 09 2024 Petr Pisar - 0.7.24-3 - Some static analysis fixes for unitialized structs Resolves: RHEL-25498