[ostree] checkout: Add --fsync=false



commit f23f556f03f72b966c7a6cc8f4afa03a29d1ea5f
Author: Colin Walters <walters verbum org>
Date:   Tue Jan 6 16:00:27 2015 -0500

    checkout: Add --fsync=false
    
    Some use cases for checkouts don't need to fsync during checkout.
    Installer programs for example will just do a global fsync at the end.
    
    In the future, the default "ostree admin" core could also be
    rearchitected to only do a transaction commit right before reboot, and
    do the fsync then.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=742482

 Makefile-ostree.am                   |    2 +
 src/libostree/ostree-repo-checkout.c |   39 +++++++++++++++---------
 src/ostree/ot-builtin-checkout.c     |   22 ++++++++++++++
 src/ostree/ot-builtin-commit.c       |   43 ++++++++-------------------
 src/ostree/ot-tool-util.c            |   53 ++++++++++++++++++++++++++++++++++
 src/ostree/ot-tool-util.h            |   35 ++++++++++++++++++++++
 6 files changed, 149 insertions(+), 45 deletions(-)
---
diff --git a/Makefile-ostree.am b/Makefile-ostree.am
index dc7e83c..b82932c 100644
--- a/Makefile-ostree.am
+++ b/Makefile-ostree.am
@@ -47,6 +47,8 @@ ostree_SOURCES = src/ostree/main.c \
        src/ostree/ot-dump.c \
        src/ostree/ot-editor.c \
        src/ostree/ot-editor.h \
+       src/ostree/ot-tool-util.c \
+       src/ostree/ot-tool-util.h \
        $(NULL)
 
 # Admin subcommand
diff --git a/src/libostree/ostree-repo-checkout.c b/src/libostree/ostree-repo-checkout.c
index c31bd3d..1340484 100644
--- a/src/libostree/ostree-repo-checkout.c
+++ b/src/libostree/ostree-repo-checkout.c
@@ -64,13 +64,16 @@ checkout_object_for_uncompressed_cache (OstreeRepo      *self,
 
   fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)temp_out);
 
-  do
-    res = fsync (fd);
-  while (G_UNLIKELY (res == -1 && errno == EINTR));
-  if (G_UNLIKELY (res == -1))
+  if (!self->disable_fsync)
     {
-      gs_set_error_from_errno (error, errno);
-      goto out;
+      do
+        res = fsync (fd);
+      while (G_UNLIKELY (res == -1 && errno == EINTR));
+      if (G_UNLIKELY (res == -1))
+        {
+          gs_set_error_from_errno (error, errno);
+          goto out;
+        }
     }
 
   if (!g_output_stream_close (temp_out, cancellable, error))
@@ -100,7 +103,8 @@ checkout_object_for_uncompressed_cache (OstreeRepo      *self,
 }
 
 static gboolean
-write_regular_file_content (OstreeRepoCheckoutMode mode,
+write_regular_file_content (OstreeRepo            *self,
+                            OstreeRepoCheckoutMode mode,
                             GOutputStream         *output,
                             GFileInfo             *file_info,
                             GVariant              *xattrs,
@@ -150,10 +154,13 @@ write_regular_file_content (OstreeRepoCheckoutMode mode,
         }
     }
           
-  if (fsync (fd) == -1)
+  if (!self->disable_fsync)
     {
-      gs_set_error_from_errno (error, errno);
+      if (fsync (fd) == -1)
+        {
+          gs_set_error_from_errno (error, errno);
       goto out;
+        }
     }
           
   if (!g_output_stream_close (output, cancellable, error))
@@ -165,7 +172,8 @@ write_regular_file_content (OstreeRepoCheckoutMode mode,
 }
 
 static gboolean
-checkout_file_from_input_at (OstreeRepoCheckoutMode mode,
+checkout_file_from_input_at (OstreeRepo     *self,
+                             OstreeRepoCheckoutMode mode,
                              GFileInfo      *file_info,
                              GVariant       *xattrs,
                              GInputStream   *input,
@@ -231,7 +239,7 @@ checkout_file_from_input_at (OstreeRepoCheckoutMode mode,
       temp_out = g_unix_output_stream_new (fd, TRUE);
       fd = -1; /* Transfer ownership */
 
-      if (!write_regular_file_content (mode, temp_out, file_info, xattrs, input,
+      if (!write_regular_file_content (self, mode, temp_out, file_info, xattrs, input,
                                        cancellable, error))
         goto out;
     }
@@ -248,7 +256,8 @@ checkout_file_from_input_at (OstreeRepoCheckoutMode mode,
  * it into place.  This implements union-like behavior.
  */
 static gboolean
-checkout_file_unioning_from_input_at (OstreeRepoCheckoutMode mode,
+checkout_file_unioning_from_input_at (OstreeRepo     *repo,
+                                      OstreeRepoCheckoutMode mode,
                                       GFileInfo      *file_info,
                                       GVariant       *xattrs,
                                       GInputStream   *input,
@@ -291,7 +300,7 @@ checkout_file_unioning_from_input_at (OstreeRepoCheckoutMode mode,
                                       cancellable, error))
         goto out;
 
-      if (!write_regular_file_content (mode, temp_out, file_info, xattrs, input,
+      if (!write_regular_file_content (repo, mode, temp_out, file_info, xattrs, input,
                                        cancellable, error))
         goto out;
     }
@@ -498,7 +507,7 @@ checkout_one_file_at (OstreeRepo                        *repo,
 
       if (overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES)
         {
-          if (!checkout_file_unioning_from_input_at (mode, source_info, xattrs, input,
+          if (!checkout_file_unioning_from_input_at (repo, mode, source_info, xattrs, input,
                                                      destination_dfd, destination_parent,
                                                      destination_name,
                                                      cancellable, error)) 
@@ -509,7 +518,7 @@ checkout_one_file_at (OstreeRepo                        *repo,
         }
       else
         {
-          if (!checkout_file_from_input_at (mode, source_info, xattrs, input,
+          if (!checkout_file_from_input_at (repo, mode, source_info, xattrs, input,
                                             destination_dfd, destination_parent,
                                             destination_name,
                                             cancellable, error))
diff --git a/src/ostree/ot-builtin-checkout.c b/src/ostree/ot-builtin-checkout.c
index b3284ef..b6d150a 100644
--- a/src/ostree/ot-builtin-checkout.c
+++ b/src/ostree/ot-builtin-checkout.c
@@ -29,6 +29,7 @@
 #include "ot-builtins.h"
 #include "ostree.h"
 #include "otutil.h"
+#include "ot-tool-util.h"
 
 static gboolean opt_user_mode;
 static gboolean opt_allow_noent;
@@ -36,6 +37,23 @@ static char *opt_subpath;
 static gboolean opt_union;
 static gboolean opt_from_stdin;
 static char *opt_from_file;
+static gboolean opt_disable_fsync;
+
+static gboolean
+parse_fsync_cb (const char  *option_name,
+                const char  *value,
+                gpointer     data,
+                GError     **error)
+{
+  gboolean val;
+
+  if (!ot_parse_boolean (option_name, value, &val, error))
+    return FALSE;
+    
+  opt_disable_fsync = !val;
+
+  return TRUE;
+}
 
 static GOptionEntry options[] = {
   { "user-mode", 'U', 0, G_OPTION_ARG_NONE, &opt_user_mode, "Do not change file ownership or initialize 
extended attributes", NULL },
@@ -44,6 +62,7 @@ static GOptionEntry options[] = {
   { "allow-noent", 0, 0, G_OPTION_ARG_NONE, &opt_allow_noent, "Do nothing if specified path does not exist", 
NULL },
   { "from-stdin", 0, 0, G_OPTION_ARG_NONE, &opt_from_stdin, "Process many checkouts from standard input", 
NULL },
   { "from-file", 0, 0, G_OPTION_ARG_STRING, &opt_from_file, "Process many checkouts from input file", "FILE" 
},
+  { "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", "POLICY" },
   { NULL }
 };
 
@@ -186,6 +205,9 @@ ostree_builtin_checkout (int argc, char **argv, GCancellable *cancellable, GErro
   if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, 
cancellable, error))
     goto out;
 
+  if (opt_disable_fsync)
+    ostree_repo_set_disable_fsync (repo, TRUE);
+
   if (argc < 2)
     {
       gchar *help = g_option_context_get_help (context, TRUE, NULL);
diff --git a/src/ostree/ot-builtin-commit.c b/src/ostree/ot-builtin-commit.c
index 47c9b7c..79ee77c 100644
--- a/src/ostree/ot-builtin-commit.c
+++ b/src/ostree/ot-builtin-commit.c
@@ -27,6 +27,7 @@
 #include "ot-editor.h"
 #include "ostree.h"
 #include "otutil.h"
+#include "ot-tool-util.h"
 
 static char *opt_subject;
 static char *opt_body;
@@ -49,38 +50,20 @@ static char *opt_gpg_homedir;
 static gboolean opt_generate_sizes;
 static gboolean opt_disable_fsync;
 
-#define ARG_EQ(x, y) (g_ascii_strcasecmp(x, y) == 0)
-/* create a function to parse the --fsync option, and current parse it the
- * same as --disable-fsync. Allows us to add other things later, and not have
- * a double negative. */
-static gboolean opt__fsync(const gchar *option_name,
-                          const gchar *value,
-                          gpointer data,
-                          GError **error)
+static gboolean
+parse_fsync_cb (const char  *option_name,
+                const char  *value,
+                gpointer     data,
+                GError     **error)
 {
-  g_assert(g_str_equal(option_name, "--fsync"));
-
-  if (0) {}
-  else if (ARG_EQ(value, "1"))
-    opt_disable_fsync = 0;
-  else if (ARG_EQ(value, "true"))
-    opt_disable_fsync = 0;
-  else if (ARG_EQ(value, "yes"))
-    opt_disable_fsync = 0;
-  else if (ARG_EQ(value, "0"))
-    opt_disable_fsync = 1;
-  else if (ARG_EQ(value, "false"))
-    opt_disable_fsync = 1;
-  else if (ARG_EQ(value, "none"))
-    opt_disable_fsync = 1;
-  else if (ARG_EQ(value, "no"))
-    opt_disable_fsync = 1;
-  else
-    /* do we want to complain here? */
-    return 0;
+  gboolean val;
 
+  if (!ot_parse_boolean (option_name, value, &val, error))
+    return FALSE;
+    
+  opt_disable_fsync = !val;
 
-  return 1;
+  return TRUE;
 }
 
 static GOptionEntry options[] = {
@@ -104,7 +87,7 @@ static GOptionEntry options[] = {
 #endif
   { "generate-sizes", 0, 0, G_OPTION_ARG_NONE, &opt_generate_sizes, "Generate size information along with 
commit metadata", NULL },
   { "disable-fsync", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke 
fsync()", NULL },
-  { "fsync", 0, 0, G_OPTION_ARG_CALLBACK, opt__fsync, "Specify how to invoke fsync()", NULL },
+  { "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", "POLICY" },
   { NULL }
 };
 
diff --git a/src/ostree/ot-tool-util.c b/src/ostree/ot-tool-util.c
new file mode 100644
index 0000000..fd4bbf9
--- /dev/null
+++ b/src/ostree/ot-tool-util.c
@@ -0,0 +1,53 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2015 Colin Walters <walters verbum org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "ot-admin-functions.h"
+#include "otutil.h"
+#include "ostree.h"
+#include "libgsystem.h"
+#include "ot-tool-util.h"
+
+gboolean
+ot_parse_boolean (const char  *option_name,
+                  const char  *value,
+                  gboolean    *out_parsed,
+                  GError     **error)
+{
+#define ARG_EQ(x, y) (g_ascii_strcasecmp(x, y) == 0)
+  if (ARG_EQ(value, "1")
+      || ARG_EQ(value, "true")
+      || ARG_EQ(value, "yes"))
+    *out_parsed = TRUE;
+  else if (ARG_EQ(value, "0")
+           || ARG_EQ(value, "false")
+           || ARG_EQ(value, "no")
+           || ARG_EQ(value, "none"))
+    *out_parsed = FALSE;
+  else
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Invalid boolean argument '%s'", value);
+      return FALSE;
+    }
+
+  return TRUE;
+}
diff --git a/src/ostree/ot-tool-util.h b/src/ostree/ot-tool-util.h
new file mode 100644
index 0000000..201190e
--- /dev/null
+++ b/src/ostree/ot-tool-util.h
@@ -0,0 +1,35 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2015 Colin Walters <walters verbum org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#pragma once
+
+#include <gio/gio.h>
+#include <ostree.h>
+
+G_BEGIN_DECLS
+
+gboolean
+ot_parse_boolean (const char  *option_name,
+                  const char  *value,
+                  gboolean    *out_parsed,
+                  GError     **error);
+
+G_END_DECLS
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]