[ostree] bootloader: fdatasync() bootloader configuration
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree] bootloader: fdatasync() bootloader configuration
- Date: Fri, 4 Apr 2014 11:46:52 +0000 (UTC)
commit 829e0382ab2a2ad1a741bbabeb5ef9a7fd7cfb75
Author: Colin Walters <walters verbum org>
Date: Thu Apr 3 22:20:59 2014 -0400
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.
src/libostree/ostree-bootloader-syslinux.c | 15 ++++---
src/libostree/ostree-bootloader-uboot.c | 13 ++++--
src/libotutil/ot-gio-utils.c | 61 ++++++++++++++++++++++++++++
src/libotutil/ot-gio-utils.h | 5 ++
4 files changed, 83 insertions(+), 11 deletions(-)
---
diff --git a/src/libostree/ostree-bootloader-syslinux.c b/src/libostree/ostree-bootloader-syslinux.c
index 4327381..0934bb8 100644
--- a/src/libostree/ostree-bootloader-syslinux.c
+++ b/src/libostree/ostree-bootloader-syslinux.c
@@ -236,12 +236,15 @@ _ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader,
goto out;
new_config_contents = _ostree_sysroot_join_lines (new_lines);
-
- if (!g_file_replace_contents (new_config_path, new_config_contents,
- strlen (new_config_contents),
- NULL, FALSE, G_FILE_CREATE_NONE,
- NULL, cancellable, error))
- goto out;
+ {
+ gs_unref_bytes GBytes *new_config_contents_bytes =
+ g_bytes_new_static (new_config_contents,
+ strlen (new_config_contents));
+
+ if (!ot_gfile_replace_contents_fsync (new_config_path, new_config_contents_bytes,
+ cancellable, error))
+ goto out;
+ }
ret = TRUE;
out:
diff --git a/src/libostree/ostree-bootloader-uboot.c b/src/libostree/ostree-bootloader-uboot.c
index c56d5ac..cd25e56 100644
--- a/src/libostree/ostree-bootloader-uboot.c
+++ b/src/libostree/ostree-bootloader-uboot.c
@@ -124,12 +124,15 @@ _ostree_bootloader_uboot_write_config (OstreeBootloader *bootloader,
return FALSE;
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,
- strlen (new_config_contents),
- NULL, FALSE, G_FILE_CREATE_NONE,
- NULL, cancellable, error))
- return FALSE;
+ if (!ot_gfile_replace_contents_fsync (new_config_path, new_config_contents_bytes,
+ cancellable, error))
+ return FALSE;
+ }
return TRUE;
}
diff --git a/src/libotutil/ot-gio-utils.c b/src/libotutil/ot-gio-utils.c
index f250f15..da895fb 100644
--- a/src/libotutil/ot-gio-utils.c
+++ b/src/libotutil/ot-gio-utils.c
@@ -25,6 +25,7 @@
#include <gio/gio.h>
#include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h>
+#include <gio/gfiledescriptorbased.h>
#include <string.h>
@@ -272,6 +273,66 @@ ot_gfile_load_contents_utf8_allow_noent (GFile *path,
}
/**
+ * 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:
*
* Like gs_file_unlink(), but return successfully if the file doesn't
diff --git a/src/libotutil/ot-gio-utils.h b/src/libotutil/ot-gio-utils.h
index 184c770..2d585ba 100644
--- a/src/libotutil/ot-gio-utils.h
+++ b/src/libotutil/ot-gio-utils.h
@@ -69,6 +69,11 @@ gboolean ot_gfile_load_contents_utf8_allow_noent (GFile *path,
GCancellable *cancellable,
GError **error);
+gboolean ot_gfile_replace_contents_fsync (GFile *path,
+ GBytes *contents,
+ GCancellable *cancellable,
+ GError **error);
+
gboolean ot_gfile_ensure_unlinked (GFile *path,
GCancellable *cancellable,
GError **error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]