[ostree] core: Use temp dir when creating GVariant metadata



commit b11096cdd780596ad70c7a14f5c260c299809a13
Author: Colin Walters <walters verbum org>
Date:   Tue Nov 8 18:17:07 2011 -0500

    core: Use temp dir when creating GVariant metadata

 libostree/ostree-repo.c |   74 ++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 64 insertions(+), 10 deletions(-)
---
diff --git a/libostree/ostree-repo.c b/libostree/ostree-repo.c
index 97c9f42..1a03bf7 100644
--- a/libostree/ostree-repo.c
+++ b/libostree/ostree-repo.c
@@ -56,6 +56,7 @@ typedef struct _OstreeRepoPrivate OstreeRepoPrivate;
 struct _OstreeRepoPrivate {
   char *path;
   GFile *repo_file;
+  GFile *tmp_dir;
   GFile *local_heads_dir;
   GFile *remote_heads_dir;
   char *objects_path;
@@ -75,6 +76,7 @@ ostree_repo_finalize (GObject *object)
 
   g_free (priv->path);
   g_clear_object (&priv->repo_file);
+  g_clear_object (&priv->tmp_dir);
   g_clear_object (&priv->local_heads_dir);
   g_clear_object (&priv->remote_heads_dir);
   g_free (priv->objects_path);
@@ -142,6 +144,7 @@ ostree_repo_constructor (GType                  gtype,
   g_assert (priv->path != NULL);
   
   priv->repo_file = ot_util_new_file_for_path (priv->path);
+  priv->tmp_dir = g_file_resolve_relative_path (priv->repo_file, "tmp");
   priv->local_heads_dir = g_file_resolve_relative_path (priv->repo_file, "refs/heads");
   priv->remote_heads_dir = g_file_resolve_relative_path (priv->repo_file, "refs/remotes");
   
@@ -538,23 +541,25 @@ ostree_repo_is_archive (OstreeRepo  *self)
 }
 
 static gboolean
-import_gvariant_object (OstreeRepo  *self,
-                        OstreeSerializedVariantType type,
-                        GVariant       *variant,
-                        GChecksum    **out_checksum,
-                        GError       **error)
+write_gvariant_to_tmp (OstreeRepo  *self,
+                       OstreeSerializedVariantType type,
+                       GVariant    *variant,
+                       GChecksum    **out_checksum,
+                       GError       **error)
 {
   OstreeRepoPrivate *priv = GET_PRIVATE (self);
   GVariant *serialized = NULL;
   gboolean ret = FALSE;
   gsize bytes_written;
   char *tmp_name = NULL;
+  char *dest_name = NULL;
   int fd = -1;
   GUnixOutputStream *stream = NULL;
+  GChecksum *checksum;
 
   serialized = g_variant_new ("(uv)", GUINT32_TO_BE ((guint32)type), variant);
 
-  tmp_name = g_build_filename (priv->objects_path, "variant-tmp-XXXXXX", NULL);
+  tmp_name = g_build_filename (ot_gfile_get_path_cached (priv->tmp_dir), "variant-tmp-XXXXXX", NULL);
   fd = g_mkstemp (tmp_name);
   if (fd < 0)
     {
@@ -562,6 +567,8 @@ import_gvariant_object (OstreeRepo  *self,
       goto out;
     }
 
+  checksum = g_checksum_new (G_CHECKSUM_SHA256);
+
   stream = (GUnixOutputStream*)g_unix_output_stream_new (fd, FALSE);
   if (!g_output_stream_write_all ((GOutputStream*)stream,
                                   g_variant_get_data (serialized),
@@ -570,27 +577,74 @@ import_gvariant_object (OstreeRepo  *self,
                                   NULL,
                                   error))
     goto out;
+
+  g_checksum_update (checksum, (guint8*)g_variant_get_data (serialized), g_variant_get_size (serialized));
+
   if (!g_output_stream_close ((GOutputStream*)stream,
                               NULL, error))
     goto out;
 
-  if (!link_one_file (self, tmp_name, OSTREE_OBJECT_TYPE_META, 
-                      TRUE, FALSE, out_checksum, error))
-    goto out;
-  
+  dest_name = g_build_filename (ot_gfile_get_path_cached (priv->tmp_dir), g_checksum_get_string (checksum), NULL);
+  if (rename (tmp_name, dest_name) < 0)
+    {
+      ot_util_set_error_from_errno (error, errno);
+      goto out;
+    }
+
   ret = TRUE;
+  *out_checksum = checksum;
+  checksum = NULL;
  out:
   /* Unconditionally unlink; if we suceeded, there's a new link, if not, clean up. */
   (void) unlink (tmp_name);
   if (fd != -1)
     close (fd);
+  if (checksum)
+    g_checksum_free (checksum);
   if (serialized != NULL)
     g_variant_unref (serialized);
   g_free (tmp_name);
+  g_free (dest_name);
   g_clear_object (&stream);
   return ret;
 }
 
+static gboolean
+import_gvariant_object (OstreeRepo  *self,
+                        OstreeSerializedVariantType type,
+                        GVariant       *variant,
+                        GChecksum    **out_checksum,
+                        GError       **error)
+{
+  gboolean ret = FALSE;
+  OstreeRepoPrivate *priv = GET_PRIVATE (self);
+  char *tmp_name = NULL;
+  GChecksum *ret_checksum = NULL;
+  gboolean did_exist;
+  
+  if (!write_gvariant_to_tmp (self, type, variant, &ret_checksum, error))
+    goto out;
+
+  tmp_name = g_build_filename (ot_gfile_get_path_cached (priv->tmp_dir),
+                               g_checksum_get_string (ret_checksum), NULL);
+
+  if (!ostree_repo_store_object_trusted (self, tmp_name,
+                                         g_checksum_get_string (ret_checksum),
+                                         OSTREE_OBJECT_TYPE_META,
+                                         TRUE, FALSE, &did_exist, error))
+    goto out;
+
+  ret = TRUE;
+  *out_checksum = ret_checksum;
+  ret_checksum = NULL;
+ out:
+  (void) unlink (tmp_name);
+  g_free (tmp_name);
+  if (ret_checksum)
+    g_checksum_free (ret_checksum);
+  return ret;
+}
+
 gboolean
 ostree_repo_load_variant_checked (OstreeRepo  *self,
                                   OstreeSerializedVariantType expected_type,



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