From 99d35011a057a112957c6e878f4ac0b7ab0d0e7a Mon Sep 17 00:00:00 2001 From: Jaroslav Rohel Date: Tue, 3 Sep 2019 13:13:31 +0200 Subject: [PATCH 10/10] Use copy+delete fallback if moving of directory failed (RhBug:1700341) Uses dnf_move_recursive() instead of g_rename()/rename() for move a directories. The dnf_move_recursive() uses copy+delete fallback if native moving of directory failed (eg. moving between filesystems, overlayfs). https://bugzilla.redhat.com/show_bug.cgi?id=1700341 --- libdnf/dnf-repo.cpp | 19 +++++++++---------- libdnf/repo/Repo.cpp | 12 ++++++++---- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/libdnf/dnf-repo.cpp b/libdnf/dnf-repo.cpp index a358356a..568e4262 100644 --- a/libdnf/dnf-repo.cpp +++ b/libdnf/dnf-repo.cpp @@ -36,6 +36,7 @@ #include "conf/OptionBool.hpp" #include "hy-repo-private.hpp" +#include "hy-iutil-private.hpp" #include #include @@ -1826,14 +1827,13 @@ dnf_repo_update(DnfRepo *repo, /* move the packages directory from the old cache to the new cache */ if (g_file_test(priv->packages, G_FILE_TEST_EXISTS)) { - rc = g_rename(priv->packages, priv->packages_tmp); - if (rc != 0) { - ret = FALSE; + ret = dnf_move_recursive(priv->packages, priv->packages_tmp, &error_local); + if (!ret) { g_set_error(error, DNF_ERROR, DNF_ERROR_CANNOT_FETCH_SOURCE, - "cannot move %s to %s", - priv->packages, priv->packages_tmp); + "cannot move %s to %s: %s", + priv->packages, priv->packages_tmp, error_local->message); goto out; } } @@ -1844,14 +1844,13 @@ dnf_repo_update(DnfRepo *repo, goto out; /* rename .tmp actual name */ - rc = g_rename(priv->location_tmp, priv->location); - if (rc != 0) { - ret = FALSE; + ret = dnf_move_recursive(priv->location_tmp, priv->location, &error_local); + if (!ret) { g_set_error(error, DNF_ERROR, DNF_ERROR_CANNOT_FETCH_SOURCE, - "cannot move %s to %s", - priv->location_tmp, priv->location); + "cannot move %s to %s: %s", + priv->location_tmp, priv->location, error_local->message); goto out; } ret = lr_handle_setopt(priv->repo_handle, error, diff --git a/libdnf/repo/Repo.cpp b/libdnf/repo/Repo.cpp index 23638839..0dbeed8b 100644 --- a/libdnf/repo/Repo.cpp +++ b/libdnf/repo/Repo.cpp @@ -31,6 +31,7 @@ #include "../hy-iutil.h" #include "../hy-repo-private.hpp" #include "../hy-util-private.hpp" +#include "../hy-iutil-private.hpp" #include "../hy-types.h" #include "libdnf/conf/ConfigParser.hpp" #include "libdnf/utils/File.hpp" @@ -1155,10 +1156,13 @@ void Repo::Impl::fetch(const std::string & destdir, std::unique_ptr && } } auto tempElement = tmpdir + "/" + elName; - if (rename(tempElement.c_str(), targetElement.c_str()) == -1) { - const char * errTxt = strerror(errno); - throw std::runtime_error(tfm::format( - _("Cannot rename directory \"%s\" to \"%s\": %s"), tempElement, targetElement, errTxt)); + GError * error = NULL; + if (!dnf_move_recursive(tempElement.c_str(), targetElement.c_str(), &error)) { + std::string errTxt = tfm::format( + _("Cannot rename directory \"%s\" to \"%s\": %s"), + tempElement, targetElement, error->message); + g_error_free(error); + throw std::runtime_error(errTxt); } } } -- 2.21.0