Backport "Implement color filtering when adding update targets"

Resolves: RHEL-103995
This commit is contained in:
Evan Goode 2026-01-22 16:42:08 -05:00
parent 8a736da8fc
commit fc4406d37b
5 changed files with 340 additions and 1 deletions

View File

@ -0,0 +1,152 @@
From af1731646829f799f837b009c3a24e246f64d857 Mon Sep 17 00:00:00 2001
From: Michael Schroeder <mls@suse.de>
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

View File

@ -0,0 +1,35 @@
From e704dd6833f908a4e4960c976bab3ebfdcc397b2 Mon Sep 17 00:00:00 2001
From: Michael Schroeder <mls@suse.de>
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

View File

@ -0,0 +1,68 @@
From 50e04ee7d6ea612b3b7193b4c0c4ff8484ca04dc Mon Sep 17 00:00:00 2001
From: Michael Schroeder <mls@suse.de>
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

View File

@ -0,0 +1,74 @@
From 24a7a79595a1f7e35a4ac430d3075e27a9a1fc2f Mon Sep 17 00:00:00 2001
From: Evan Goode <mail@evangoo.de>
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 <inline>
+#>=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 <inline>
+#>=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 <inline>
+#>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

View File

@ -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 <egoode@redhat.com> - 0.7.24-4
- Backport "Implement color filtering when adding update targets"
Resolves: RHEL-103995
* Tue Apr 09 2024 Petr Pisar <ppisar@redhat.com> - 0.7.24-3
- Some static analysis fixes for unitialized structs
Resolves: RHEL-25498