Commit bc765818 authored by Colin Walters's avatar Colin Walters Committed by Bastien Nocera
Browse files

Call fdatasync() before renaming files into place

In order to implement fully atomic upgrades, the OSTree system expects
that "triggers" such as this tool ensure that any data they generate
are on durable storage.  Thus, we use fdatasync() before calling
rename().

https://bugs.freedesktop.org/show_bug.cgi?id=61472
parent b58fea97
...@@ -20,6 +20,8 @@ GETTEXT_PACKAGE=shared-mime-info ...@@ -20,6 +20,8 @@ GETTEXT_PACKAGE=shared-mime-info
AC_SUBST(GETTEXT_PACKAGE) AC_SUBST(GETTEXT_PACKAGE)
AM_GLIB_GNU_GETTEXT AM_GLIB_GNU_GETTEXT
AC_CHECK_FUNCS(fdatasync)
dnl Check for cross compiling dnl Check for cross compiling
AM_CONDITIONAL(CROSS_COMPILING, test $cross_compiling = yes) AM_CONDITIONAL(CROSS_COMPILING, test $cross_compiling = yes)
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <libxml/tree.h> #include <libxml/tree.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h>
#define XML_NS XML_XML_NAMESPACE #define XML_NS XML_XML_NAMESPACE
#define XMLNS_NS "http://www.w3.org/2000/xmlns/" #define XMLNS_NS "http://www.w3.org/2000/xmlns/"
...@@ -941,6 +942,7 @@ static gboolean atomic_update(const gchar *pathname, GError **error) ...@@ -941,6 +942,7 @@ static gboolean atomic_update(const gchar *pathname, GError **error)
gboolean ret = FALSE; gboolean ret = FALSE;
gchar *new_name = NULL; gchar *new_name = NULL;
int len; int len;
int fd;
len = strlen(pathname); len = strlen(pathname);
...@@ -948,6 +950,25 @@ static gboolean atomic_update(const gchar *pathname, GError **error) ...@@ -948,6 +950,25 @@ static gboolean atomic_update(const gchar *pathname, GError **error)
new_name = g_strndup(pathname, len - 4); new_name = g_strndup(pathname, len - 4);
#ifdef HAVE_FDATASYNC
fd = open(pathname, O_RDONLY);
if (fd == -1)
{
set_error_from_errno(error);
goto out;
}
if (fdatasync(fd) == -1)
{
set_error_from_errno(error);
goto out;
}
if (close(fd) == -1)
{
set_error_from_errno(error);
goto out;
}
#endif
#ifdef _WIN32 #ifdef _WIN32
/* we need to remove the old file first! */ /* we need to remove the old file first! */
remove(new_name); remove(new_name);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment