mirror of
https://github.com/ostreedev/ostree.git
synced 2025-03-22 06:50:47 +03:00
core: Use temp dir when creating GVariant metadata
This commit is contained in:
parent
7a67b17cd2
commit
b11096cdd7
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user