Backport patches

Resolves: RHEL-12123
Resolves: RHEL-6304
Resolves: RHEL-12124
This commit is contained in:
Jaroslav Rohel 2023-10-25 07:14:43 +02:00
parent 43a1d546c2
commit 3b2be39421
4 changed files with 229 additions and 1 deletions

View File

@ -0,0 +1,37 @@
From ccd66a3cb4ddb7a0f0d914ee06eed58121dbe7ce Mon Sep 17 00:00:00 2001
From: Aleš Matěj <amatej@redhat.com>
Date: Tue, 27 Jun 2023 07:24:28 +0200
Subject: [PATCH] filterAdvisory: match installed_solvables sort with lower_bound (RhBug:2212838)
`std::lower_bound` expects that the range it operates on is sorted by
the provided comparator.
`lower_bound()` is used on `installed_solvables` twice, first with
comparator `NameSolvableComparator` and later with
`SolvableCompareAdvisoryPkgNameArch` to cover both we need to sort
`installed_solvables` by name and arch.
Otherwise this can lead to problems if multiple architectures of a pkg
are installed.
For: https://bugzilla.redhat.com/show_bug.cgi?id=2212838
---
libdnf/sack/query.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
index b7b1560..7937770 100644
--- a/libdnf/sack/query.cpp
+++ b/libdnf/sack/query.cpp
@@ -1903,7 +1903,7 @@ Query::Impl::filterAdvisory(const Filter & f, Map *m, int keyname)
while ((installed_id = installed.pImpl->result->next(installed_id)) != -1) {
installed_solvables.push_back(pool_id2solvable(pool, installed_id));
}
- std::sort(installed_solvables.begin(), installed_solvables.end(), NameSolvableComparator);
+ std::sort(installed_solvables.begin(), installed_solvables.end(), NameArchSolvableComparator);
Query obsoletes(sack, ExcludeFlags::IGNORE_EXCLUDES);
obsoletes.addFilter(HY_PKG, HY_EQ, resultPset);
--
libgit2 1.6.4

View File

@ -0,0 +1,84 @@
From dadfe65ce753ba8a8bdb5e38d7929135526edbd5 Mon Sep 17 00:00:00 2001
From: Marek Blaha <mblaha@redhat.com>
Date: Thu, 31 Aug 2023 13:18:03 +0200
Subject: [PATCH] hawkey.subject: get_best_selectors only obsoleters of latest
In situation where a package exists in multiple versions and some older
version is being obsoleted, any of obsoleters was considered a valid
solution.
The result could be really misleading. For example let's have this package set:
systemd-udev-1.0
systemd-udev-2.0
Obsoletes: systemd-udev < 2
systemd-boot-unsigned-2.0
Obsoletes: systemd-udev < 2
In this case `dnf install systemd-udev` may lead to installation of
systemd-boot-unsigned which is probably not what the user expected. The
reason is the split in the upgrade-path created by obsolete and both
branches - systemd-udev-2.0 and systemd-boot-unsigned-2.0 are considered
valid.
With this patch install command takes into account only obsoleters of
the best version of the package so the `dnf install systemd-udev`
results in correct installation of systemd-udev-2.0 package.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2183279
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2176263
---
python/hawkey/__init__.py | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/python/hawkey/__init__.py b/python/hawkey/__init__.py
index 45bdc3a..1ec1ef4 100644
--- a/python/hawkey/__init__.py
+++ b/python/hawkey/__init__.py
@@ -291,13 +291,13 @@ class Subject(_hawkey.Subject):
# after movement of base.install() or base.distro_sync()
return []
+ installed_query = q.installed()
if not self._filename_pattern and is_glob_pattern(self.pattern) \
or solution['nevra'] and solution['nevra'].name is None:
with_obsoletes = False
if obsoletes and solution['nevra'] and solution['nevra'].has_just_name():
with_obsoletes = True
- installed_query = q.installed()
if reponame:
q = q.filter(reponame=reponame)
available_query = q.available()
@@ -309,13 +309,24 @@ class Subject(_hawkey.Subject):
sltrs = []
for name, pkgs_list in q._name_dict().items():
if with_obsoletes:
+ # If there is no installed package in the pkgs_list, add only
+ # obsoleters of the latest versions. Otherwise behave consistently
+ # with upgrade and add all obsoleters.
+ # See https://bugzilla.redhat.com/show_bug.cgi?id=2176263
+ # for details of the problem.
+ obsoletes_query = base.sack.query().filterm(pkg=pkgs_list)
+ if not obsoletes_query.installed():
+ obsoletes_query.filterm(latest_per_arch_by_priority=True)
pkgs_list = pkgs_list + base.sack.query().filter(
- obsoletes=pkgs_list).run()
+ obsoletes=obsoletes_query).run()
sltrs.append(self._list_or_query_to_selector(base.sack, pkgs_list))
return sltrs
else:
if obsoletes and solution['nevra'] and solution['nevra'].has_just_name():
- q = q.union(base.sack.query().filter(obsoletes=q))
+ if installed_query:
+ q = q.union(base.sack.query().filter(obsoletes=q))
+ else:
+ q = q.union(base.sack.query().filter(obsoletes=q.filter(latest_per_arch_by_priority=True)))
installed_query = q.installed()
if reports:
--
libgit2 1.6.4

View File

@ -0,0 +1,99 @@
From 2ffe58595baa2a51700a1210b1d3a2124f805756 Mon Sep 17 00:00:00 2001
From: Aleš Matěj <amatej@redhat.com>
Date: Mon, 25 Sep 2023 08:24:40 +0200
Subject: [PATCH] Avoid reinstalling installonly packages marked for ERASE
Without this patch reinstalling installonly pkg marked for ERASE might
be a valid smallest solution to our job.
For example when user wants to install through a provide we select all
packages that provide it and put them inside a `job install oneof ...`
if one of the providers is also marked for ERASE due to installonly
limit libsolv might decide to reinstall it.
To make sure it doesn't happen mark the available package also as ERASE.
https://github.com/openSUSE/libsolv/issues/540
https://issues.redhat.com/browse/RHEL-1253
(https://bugzilla.redhat.com/show_bug.cgi?id=2163474)
---
libdnf/goal/Goal.cpp | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/libdnf/goal/Goal.cpp b/libdnf/goal/Goal.cpp
index 7def837..ba938e1 100644
--- a/libdnf/goal/Goal.cpp
+++ b/libdnf/goal/Goal.cpp
@@ -643,6 +643,12 @@ erase_flags2libsolv(int flags)
return ret;
}
+static bool
+NameSolvableComparator(const Solvable * first, const Solvable * second)
+{
+ return first->name < second->name;
+}
+
Goal::Goal(const Goal & goal_src) : pImpl(new Impl(*goal_src.pImpl)) {}
Goal::Impl::Impl(const Goal::Impl & goal_src)
@@ -1436,10 +1442,24 @@ Goal::Impl::limitInstallonlyPackages(Solver *solv, Queue *job)
for (int i = 0; i < onlies->count; ++i) {
Id p, pp;
IdQueue q, installing;
+ std::vector<Solvable *> available_unused_providers;
+ // Add all providers of installonly provides that are marked for install
+ // to `q` IdQueue those that are not marked for install and are not already
+ // installed are added to available_unused_providers.
FOR_PKG_PROVIDES(p, pp, onlies->elements[i])
- if (solver_get_decisionlevel(solv, p) > 0)
+ // According to libsolv-bindings the decision level is positive for installs
+ // and negative for conflicts (conflicts with another package or dependency
+ // conflicts = dependencies cannot be met).
+ if (solver_get_decisionlevel(solv, p) > 0) {
q.pushBack(p);
+ } else {
+ Solvable *s = pool_id2solvable(pool, p);
+ if (s->repo != pool->installed) {
+ available_unused_providers.push_back(s);
+ }
+ }
+
if (q.size() <= (int) dnf_sack_get_installonly_limit(sack)) {
continue;
}
@@ -1457,17 +1477,28 @@ Goal::Impl::limitInstallonlyPackages(Solver *solv, Queue *job)
struct InstallonliesSortCallback s_cb = {pool, dnf_sack_running_kernel(sack)};
solv_sort(q.data(), q.size(), sizeof(q[0]), sort_packages, &s_cb);
+ std::sort(available_unused_providers.begin(), available_unused_providers.end(), NameSolvableComparator);
IdQueue same_names;
while (q.size() > 0) {
same_name_subqueue(pool, q.getQueue(), same_names.getQueue());
if (same_names.size() <= (int) dnf_sack_get_installonly_limit(sack))
continue;
reresolve = 1;
for (int j = 0; j < same_names.size(); ++j) {
Id id = same_names[j];
Id action = SOLVER_ERASE;
- if (j < (int) dnf_sack_get_installonly_limit(sack))
+ if (j < (int) dnf_sack_get_installonly_limit(sack)) {
action = SOLVER_INSTALL;
+ } else {
+ // We want to avoid reinstalling packages marked for ERASE, therefore
+ // if some unused provider is also available we need to mark it ERASE as well.
+ Solvable *s = pool_id2solvable(pool, id);
+ auto low = std::lower_bound(available_unused_providers.begin(), available_unused_providers.end(), s, NameSolvableComparator);
+ while (low != available_unused_providers.end() && (*low)->name == s->name) {
+ queue_push2(job, SOLVER_ERASE | SOLVER_SOLVABLE, pool_solvable2id(pool, *low));
+ ++low;
+ }
+ }
queue_push2(job, action | SOLVER_SOLVABLE, id);
}
}
--
libgit2 1.6.4

View File

@ -56,7 +56,7 @@
Name: libdnf
Version: %{libdnf_major_version}.%{libdnf_minor_version}.%{libdnf_micro_version}
Release: 6%{?dist}
Release: 7%{?dist}
Summary: Library providing simplified C and Python API to libsolv
License: LGPLv2+
URL: https://github.com/rpm-software-management/libdnf
@ -65,6 +65,9 @@ Patch1: 0001-Allow-change-of-arch-during-security-updates-with-no.patch
Patch2: 0002-Add-repoid-to-solver-error-messages.patch
Patch3: 0003-Update-translations-RHEL-9-2.patch
Patch4: 0004-Update-translations-RHEL-9.3.patch
Patch5: 0005-filterAdvisory-installed_solvables-sort-RhBug2212838.patch
Patch6: 0006-hawkeysubject-get_best_selectors-only-obsol-oflatest.patch
Patch7: 0007-Avoid-reinstal-installonly-packages-marked-for-ERASE.patch
BuildRequires: cmake
@ -309,6 +312,11 @@ popd
%endif
%changelog
* Wed Oct 25 2023 Jaroslav Rohel <jrohel@redhat.com> - 0.69.0-7
- filterAdvisory: match installed_solvables sort with lower_bound (RhBug:2212838, RHEL-12123)
- hawkey.subject: get_best_selectors only obsoleters of latest (RhBug:2183279, RHEL-6304)
- Avoid reinstalling installonly packages marked for ERASE (RhBug:2163474, RHEL-12124)
* Fri Sep 08 2023 Marek Blaha <mblaha@redhat.com> - 0.69.0-6
- Update translations