This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] ldconfig: Call fsync on temporary files before renaming them [BZ #20890]


On 01/13/2018 03:28 AM, Paul Eggert wrote:
Florian Weimer wrote:
    if (write (fd, strings, total_strlen) != (ssize_t) total_strlen
-      || close (fd))
+      || fsync (fd) != 0
+      || close (fd) != 0)
      error (EXIT_FAILURE, errno, _("Writing of cache data failed"));

Would fdatasync suffice, instead of fsync?

One can be fdatasync, I think.

The first one should actually happen after the chmod call, and then we need fsync.

Thanks,
Florian
Subject: [PATCH] ldconfig: Sync temporary files to disk before renaming them [BZ #20890]
To: libc-alpha@sourceware.org

If the system crashes before the file data has been written to disk, the
file system recovery upon the next mount may restore a partially
rewritten temporary file under the non-temporary (final) name (after the
rename operation).

2018-01-12  Florian Weimer  <fweimer@redhat.com>

	[BZ #20890]
	* elf/cache.c (save_cache): Call fsync on temporary file before
	renaming it.
	(save_aux_cache): Call fdatasync on temporary file before renaming
	it.

diff --git a/elf/cache.c b/elf/cache.c
index 1ec6ab36e7..f032081e5c 100644
--- a/elf/cache.c
+++ b/elf/cache.c
@@ -448,8 +448,7 @@ save_cache (const char *cache_name)
 	error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
     }
 
-  if (write (fd, strings, total_strlen) != (ssize_t) total_strlen
-      || close (fd))
+  if (write (fd, strings, total_strlen) != (ssize_t) total_strlen)
     error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
 
   /* Make sure user can always read cache file */
@@ -458,6 +457,10 @@ save_cache (const char *cache_name)
 	   _("Changing access rights of %s to %#o failed"), temp_name,
 	   S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR);
 
+  /* Make sure that data is written to disk.  */
+  if (fsync (fd) != 0 || close (fd) != 0)
+    error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
+
   /* Move temporary to its final location.  */
   if (rename (temp_name, cache_name))
     error (EXIT_FAILURE, errno, _("Renaming of %s to %s failed"), temp_name,
@@ -812,7 +815,8 @@ save_aux_cache (const char *aux_cache_name)
 
   if (write (fd, file_entries, file_entries_size + total_strlen)
       != (ssize_t) (file_entries_size + total_strlen)
-      || close (fd))
+      || fdatasync (fd) != 0
+      || close (fd) != 0)
     {
       unlink (temp_name);
       goto out_fail;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]