diff --git a/0047-filterAdvisory-installed_solvables-sort-RhBug2212838.patch b/0047-filterAdvisory-installed_solvables-sort-RhBug2212838.patch new file mode 100644 index 0000000..f4a3d4a --- /dev/null +++ b/0047-filterAdvisory-installed_solvables-sort-RhBug2212838.patch @@ -0,0 +1,37 @@ +From d138dbf60588b73a8ee9499540c82a8950ba9432 Mon Sep 17 00:00:00 2001 +From: Aleš Matěj +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 + diff --git a/0048-Avoid-reinstal-installonly-packages-marked-for-ERASE.patch b/0048-Avoid-reinstal-installonly-packages-marked-for-ERASE.patch new file mode 100644 index 0000000..520da71 --- /dev/null +++ b/0048-Avoid-reinstal-installonly-packages-marked-for-ERASE.patch @@ -0,0 +1,99 @@ +From c32ce1071807176eb31d884d4185b20d944a28b9 Mon Sep 17 00:00:00 2001 +From: Aleš Matěj +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 b771030..6939d8a 100644 +--- a/libdnf/goal/Goal.cpp ++++ b/libdnf/goal/Goal.cpp +@@ -639,6 +639,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) +@@ -1324,10 +1330,24 @@ Goal::Impl::limitInstallonlyPackages(Solver *solv, Queue *job) + for (int i = 0; i < onlies->count; ++i) { + Id p, pp; + IdQueue q, installing; ++ std::vector 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; + } +@@ -1345,17 +1365,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 + diff --git a/libdnf.spec b/libdnf.spec index 8c7c270..3c9d0cc 100644 --- a/libdnf.spec +++ b/libdnf.spec @@ -56,7 +56,7 @@ Name: libdnf Version: %{libdnf_major_version}.%{libdnf_minor_version}.%{libdnf_micro_version} -Release: 17%{?dist} +Release: 18%{?dist} Summary: Library providing simplified C and Python API to libsolv License: LGPLv2+ URL: https://github.com/rpm-software-management/libdnf @@ -107,6 +107,8 @@ Patch43: 0043-Update-translations.patch Patch44: 0044-Add_repoid_to_solver_error_messagase.patch Patch45: 0045-conf-Support-proxy-_none_-in-main-config-RhBug-21557.patch Patch46: 0046-Update-translations-RHEL-8.9.patch +Patch47: 0047-filterAdvisory-installed_solvables-sort-RhBug2212838.patch +Patch48: 0048-Avoid-reinstal-installonly-packages-marked-for-ERASE.patch BuildRequires: cmake @@ -352,6 +354,10 @@ popd %endif %changelog +* Fri Oct 13 2023 Jaroslav Rohel - 0.63.0-18 +- filterAdvisory: match installed_solvables sort with lower_bound (RhBug:2212838, RHEL-1244) +- Avoid reinstalling installonly packages marked for ERASE (RhBug:2163474, RHEL-1253) + * Fri Sep 08 2023 Marek Blaha - 0.63.0-17 - Update translations