bootloader: fdatasync() bootloader configuration

Let's be a bit more conservative here and actually fdatasync() the
configurations we're generating.

I'm seeing an issue at the moment where syslinux isn't finding the
config sometimes, and while I don't think this is the issue, let's try
it.
This commit is contained in:
Colin Walters 2014-04-03 22:20:59 -04:00
parent cc8bacf8b4
commit 829e0382ab
4 changed files with 82 additions and 10 deletions

View File

@ -236,12 +236,15 @@ _ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader,
goto out; goto out;
new_config_contents = _ostree_sysroot_join_lines (new_lines); new_config_contents = _ostree_sysroot_join_lines (new_lines);
{
gs_unref_bytes GBytes *new_config_contents_bytes =
g_bytes_new_static (new_config_contents,
strlen (new_config_contents));
if (!g_file_replace_contents (new_config_path, new_config_contents, if (!ot_gfile_replace_contents_fsync (new_config_path, new_config_contents_bytes,
strlen (new_config_contents), cancellable, error))
NULL, FALSE, G_FILE_CREATE_NONE, goto out;
NULL, cancellable, error)) }
goto out;
ret = TRUE; ret = TRUE;
out: out:

View File

@ -124,12 +124,15 @@ _ostree_bootloader_uboot_write_config (OstreeBootloader *bootloader,
return FALSE; return FALSE;
new_config_contents = _ostree_sysroot_join_lines (new_lines); new_config_contents = _ostree_sysroot_join_lines (new_lines);
{
gs_unref_bytes GBytes *new_config_contents_bytes =
g_bytes_new_static (new_config_contents,
strlen (new_config_contents));
if (!g_file_replace_contents (new_config_path, new_config_contents, if (!ot_gfile_replace_contents_fsync (new_config_path, new_config_contents_bytes,
strlen (new_config_contents), cancellable, error))
NULL, FALSE, G_FILE_CREATE_NONE, return FALSE;
NULL, cancellable, error)) }
return FALSE;
return TRUE; return TRUE;
} }

View File

@ -25,6 +25,7 @@
#include <gio/gio.h> #include <gio/gio.h>
#include <gio/gunixinputstream.h> #include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h> #include <gio/gunixoutputstream.h>
#include <gio/gfiledescriptorbased.h>
#include <string.h> #include <string.h>
@ -271,6 +272,66 @@ ot_gfile_load_contents_utf8_allow_noent (GFile *path,
return ret; return ret;
} }
/**
* ot_gfile_replace_contents_fsync:
*
* Like g_file_replace_contents(), except always uses fdatasync().
*/
gboolean
ot_gfile_replace_contents_fsync (GFile *path,
GBytes *contents,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
int fd;
gs_unref_object GFile *parent = NULL;
gs_unref_object GFile *tmpfile = NULL;
gs_unref_object GOutputStream *stream = NULL;
gs_unref_object GInputStream *instream = NULL;
parent = g_file_get_parent (path);
if (!gs_file_open_in_tmpdir (parent, 0644, &tmpfile, &stream,
cancellable, error))
goto out;
g_assert (G_IS_FILE_DESCRIPTOR_BASED (stream));
fd = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (stream));
instream = g_memory_input_stream_new_from_bytes (contents);
if (posix_fallocate (fd, 0, g_bytes_get_size (contents)) != 0)
{
ot_util_set_error_from_errno (error, errno);
goto out;
}
if (g_output_stream_splice (stream, instream, 0,
cancellable, error) < 0)
goto out;
if (fdatasync (fd) != 0)
{
ot_util_set_error_from_errno (error, errno);
goto out;
}
if (!g_output_stream_close (stream, cancellable, error))
goto out;
if (!gs_file_rename (tmpfile, path, cancellable, error))
goto out;
g_clear_object (&tmpfile);
ret = TRUE;
out:
if (tmpfile)
(void) gs_file_unlink (tmpfile, NULL, NULL);
return ret;
}
/** /**
* ot_gfile_ensure_unlinked: * ot_gfile_ensure_unlinked:
* *

View File

@ -69,6 +69,11 @@ gboolean ot_gfile_load_contents_utf8_allow_noent (GFile *path,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
gboolean ot_gfile_replace_contents_fsync (GFile *path,
GBytes *contents,
GCancellable *cancellable,
GError **error);
gboolean ot_gfile_ensure_unlinked (GFile *path, gboolean ot_gfile_ensure_unlinked (GFile *path,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);