ldconfig: Call fsync on temporary files before renaming them [BZ #20890]
Commit Message
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
Comments
On 01/19/2018 05:39 PM, Florian Weimer wrote:
> 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.
Ping?
<https://sourceware.org/ml/libc-alpha/2018-01/msg00660.html>
Thanks,
Florian
On 20/02/2018 10:59, Florian Weimer wrote:
> On 01/19/2018 05:39 PM, Florian Weimer wrote:
>> 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.
>
> Ping?
LGTM.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
>
> <https://sourceware.org/ml/libc-alpha/2018-01/msg00660.html>
>
> 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.
@@ -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;