sync upstream patch

This commit is contained in:
chenhaixing 2024-01-02 09:03:11 +00:00
parent 9390284323
commit 2fce2ae05b
5 changed files with 309 additions and 1 deletions

View File

@ -0,0 +1,97 @@
From 4b016cee3ff42c36349714c1b38b394b4317174f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <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)
Conflict:NA
Reference:https://github.com/rpm-software-management/libdnf/commit/4b016cee3ff42c36349714c1b38b394b4317174f
---
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 42c078286..269f6b398 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,6 +1477,7 @@ 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());
@@ -1466,8 +1487,18 @@ Goal::Impl::limitInstallonlyPackages(Solver *solv, Queue *job)
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);
}
}

View File

@ -0,0 +1,26 @@
From 933f00f5366e9935c9f00f842a4bb60b7da87ad4 Mon Sep 17 00:00:00 2001
From: Alessandro Astone <ales.astone@gmail.com>
Date: Sun, 1 Oct 2023 19:18:54 +0200
Subject: [PATCH] dnf-repo: Fix utimes error message
Oops, syscall returns 0 on success
Conflict:NA
Reference:https://github.com/rpm-software-management/libdnf/commit/933f00f5366e9935c9f00f842a4bb60b7da87ad4
---
libdnf/dnf-repo.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libdnf/dnf-repo.cpp b/libdnf/dnf-repo.cpp
index c2495f564..ca3d1920a 100644
--- a/libdnf/dnf-repo.cpp
+++ b/libdnf/dnf-repo.cpp
@@ -1798,7 +1798,7 @@ dnf_repo_update(DnfRepo *repo,
if (repoImpl->isInSync()) {
/* reset timestamp */
ret = utimes(repoImpl->repomdFn.c_str(), NULL);
- if (!ret)
+ if (ret != 0)
g_debug("Failed to reset timestamp on repomd.xml");
ret = dnf_state_done(state, error);
if (!ret)

View File

@ -0,0 +1,95 @@
From e7cf3d198e7b107cffc788f96f51fde2d843dd82 Mon Sep 17 00:00:00 2001
From: Alessandro Astone <ales.astone@gmail.com>
Date: Thu, 28 Sep 2023 14:50:22 +0200
Subject: [PATCH] dnf-repo: Don't download repository if our local cache is up
to date
Verified by comparing the hash of repomd.xml
Conflict:NA
Reference:https://github.com/rpm-software-management/libdnf/commit/e7cf3d198e7b107cffc788f96f51fde2d843dd82
---
libdnf/dnf-repo.cpp | 34 ++++++++++++++++++++++++++++++----
1 file changed, 30 insertions(+), 4 deletions(-)
diff --git a/libdnf/dnf-repo.cpp b/libdnf/dnf-repo.cpp
index 48434fd9be..c2495f564e 100644
--- a/libdnf/dnf-repo.cpp
+++ b/libdnf/dnf-repo.cpp
@@ -969,6 +969,9 @@ dnf_repo_set_keyfile_data(DnfRepo *repo, gboolean reloadFromGKeyFile, GError **e
dnf_repo_apply_setopts(*conf, repoId);
}
+ if (dnf_context_get_cache_dir(priv->context))
+ conf->basecachedir().set(libdnf::Option::Priority::REPOCONFIG, dnf_context_get_cache_dir(priv->context));
+
/* baseurl is optional; if missing, unset it */
g_auto(GStrv) baseurls = NULL;
auto & repoBaseurls = conf->baseurl().getValue();
@@ -1463,6 +1466,7 @@ dnf_repo_check_internal(DnfRepo *repo,
error_local->message);
return FALSE;
}
+ repoImpl->repomdFn = yum_repo->repomd;
/* get timestamp */
ret = lr_result_getinfo(priv->repo_result, &error_local,
@@ -1765,8 +1769,10 @@ dnf_repo_update(DnfRepo *repo,
if (!dnf_repo_set_keyfile_data(repo, TRUE, error))
return FALSE;
+ auto repoImpl = libdnf::repoGetImpl(priv->repo);
+
/* countme support */
- libdnf::repoGetImpl(priv->repo)->addCountmeFlag(priv->repo_handle);
+ repoImpl->addCountmeFlag(priv->repo_handle);
/* take lock */
ret = dnf_state_take_lock(state,
@@ -1784,6 +1790,28 @@ dnf_repo_update(DnfRepo *repo,
if (!ret)
goto out;
+ state_local = dnf_state_get_child(state);
+ dnf_state_action_start(state_local,
+ DNF_STATE_ACTION_DOWNLOAD_METADATA, NULL);
+
+ try {
+ if (repoImpl->isInSync()) {
+ /* reset timestamp */
+ ret = utimes(repoImpl->repomdFn.c_str(), NULL);
+ if (!ret)
+ g_debug("Failed to reset timestamp on repomd.xml");
+ ret = dnf_state_done(state, error);
+ if (!ret)
+ goto out;
+
+ /* skip check */
+ ret = dnf_state_finished(state, error);
+ goto out;
+ }
+ } catch (std::exception & ex) {
+ g_debug("Failed to verify if metadata is in sync: \"%s\". Proceding with download", ex.what());
+ }
+
/* remove the temporary space if it already exists */
if (g_file_test(priv->location_tmp, G_FILE_TEST_EXISTS)) {
ret = dnf_remove_recursive(priv->location_tmp, error);
@@ -1842,7 +1870,7 @@ dnf_repo_update(DnfRepo *repo,
goto out;
/* Callback to display progress of downloading */
- state_local = updatedata.state = dnf_state_get_child(state);
+ updatedata.state = state_local;
ret = lr_handle_setopt(priv->repo_handle, error,
LRO_PROGRESSDATA, &updatedata);
if (!ret)
@@ -1867,8 +1895,6 @@ dnf_repo_update(DnfRepo *repo,
}
lr_result_clear(priv->repo_result);
- dnf_state_action_start(state_local,
- DNF_STATE_ACTION_DOWNLOAD_METADATA, NULL);
ret = lr_handle_perform(priv->repo_handle,
priv->repo_result,
&error_local);

View File

@ -0,0 +1,76 @@
From 8a8548de607e0488fd4b8ab05373749545a29342 Mon Sep 17 00:00:00 2001
From: Mark Johnston <markj@FreeBSD.org>
Date: Thu, 24 Aug 2023 17:43:36 -0400
Subject: [PATCH] python bindings: Load all modules with RTLD_GLOBAL
libdnf's python bindings are implemented by a set of C++ shared objects
generated by swig. Some generated code is duplicated between modules,
in particular the SwigPyIterator class templates, which use exceptions
of type swig::stop_iteration to signal an end-of-iteration condition.
The modules do not depend on each other and thus belong to different
DAGs from the perspective of the runtime linker.
It turns out that this stop_iteration exception can be thrown between
modules. This happens at least during dnf startup with python 3.9:
cli.py(935): subst.update_from_etc(from_root, varsdir=conf._get_value('varsdir'))
--- modulename: config, funcname: _get_value
config.py(102): method = getattr(self._config, name, None)
config.py(103): if method is None:
config.py(105): return method().getValue()
--- modulename: conf, funcname: varsdir
conf.py(1183): return _conf.ConfigMain_varsdir(self)
--- modulename: conf, funcname: getValue
conf.py(512): return _conf.OptionStringList_getValue(self)
--- modulename: substitutions, funcname: update_from_etc
substitutions.py(47): for vars_path in varsdir:
--- modulename: module, funcname: __iter__
module.py(557): return self.iterator()
--- modulename: module, funcname: iterator
module.py(555): return _module.VectorString_iterator(self)
--- modulename: transaction, funcname: __next__
transaction.py(94): return _transaction.SwigPyIterator___next__(self)
In particular, the module and transaction modules are somehow both
involved: module returns the iterator, and transaction advances the
iterator. Both modules contain the same iterator code, so I'm not sure
why it works this way. The behaviour is sensitive to import order; for
example, if transaction is imported before module, then the code above
ends up using module's implementation of SwigPyItreator___next__.
In any case, the use of swig::stop_iteration is broken in the above
scenario since the exception is thrown by module with module.so's copy
of the swig::stop_iteration type info, and caught by transaction.so
using transaction.so's copy of the type info, resulting in an uncaught
exception.
Work around the problem by loading all modules with RTLD_GLOBAL to
ensure that RTTI is unique. This is required when throwing exceptions
across DSO boundaries, see https://gcc.gnu.org/faq.html#dso for example.
Conflict:NA
Reference:https://github.com/rpm-software-management/libdnf/commit/8a8548de607e0488fd4b8ab05373749545a29342
---
bindings/python/__init__.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/bindings/python/__init__.py b/bindings/python/__init__.py
index 3bfd3a9441..07cf1959d5 100644
--- a/bindings/python/__init__.py
+++ b/bindings/python/__init__.py
@@ -6,11 +6,14 @@
import sys, os
sys.setdlopenflags(os.RTLD_NOW | os.RTLD_GLOBAL)
from . import error
-sys.setdlopenflags(os.RTLD_NOW)
+# Other modules also need to be loaded with RTLD_GLOBAL to preserve uniqueness
+# of RTTI. There are code paths where an exception thrown in one module is
+# supposed to be caught in another.
from . import common_types
from . import conf
from . import module
from . import repo
from . import transaction
from . import utils
+sys.setdlopenflags(os.RTLD_NOW)

View File

@ -18,7 +18,7 @@
Name: libdnf
Version: 0.70.2
Release: 1
Release: 2
Summary: Library providing simplified C and Python API to libsolv
License: LGPL-2.1-or-later
URL: https://github.com/rpm-software-management/libdnf
@ -44,6 +44,11 @@ Obsoletes: python2-libdnf-debuginfo < %{version}-%{release}
Patch6001: 0001-libdnf-0.65.0-add-loongarch-support.patch
%endif
Patch6002: backport-python-bindings-Load-all-modules-with-RTLD_GLOBAL.patch
Patch6003: backport-Avoid-reinstalling-installonly-packages-marked-for-ERASE.patch
Patch6004: backport-dnf-repo-do-not-download-repository-if-our-local-cache-is-up-to-date.patch
Patch6005: backport-dnf-repo-Fix-utimes-error-messages.patch
%description
A Library providing simplified C and Python API to libsolv.
@ -122,6 +127,15 @@ popd
%{python3_sitearch}/hawkey/
%changelog
* Tue Jan 02 2024 chenhaixing <chenhaixing@huawei.com> - 0.70.2-2
- Type:bugfix
- CVE:NA
- SUG:NA
- DESC:libdnf:Avoid reinstalling installonly packages marked for ERASE
Fix utimes error message in dnf-repo
Do not download repository if our local cache is up to date in dnf-repo
python bindings:Load all modules with RTLD_GLOBAL
* Sat Jul 29 2023 zhangrui <zhangrui182@huawei.com> - 0.70.2-1
- Type:bugfix
- CVE:NA