From 99d35011a057a112957c6e878f4ac0b7ab0d0e7a Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
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 <strings.h>
#include <fcntl.h>
@@ -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<LrHandle> &&
}
}
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