lib: Use OtTmpFile for static delta processing
The `OstreeRepoContentBareCommit` struct was basically an `OtTmpFile`, so let's make it one. I moved the "convert to `GOutputStream`" logic into the callers, since that bit can't fail; it makes the implementation much simpler since we can just return the result of `ot_open_tmpfile_linkable_at()`. Prep for `GLnxTmpfile` porting. Closes: #957 Approved by: jlebon
This commit is contained in:
parent
4dee1984dc
commit
af3a96755b
|
|
@ -446,57 +446,39 @@ ot_fallocate (int fd, goffset size, GError **error)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Combines a check for whether or not we already have the object with
|
||||||
|
* allocating a tempfile if we don't. Used by the static delta code.
|
||||||
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
_ostree_repo_open_content_bare (OstreeRepo *self,
|
_ostree_repo_open_content_bare (OstreeRepo *self,
|
||||||
const char *checksum,
|
const char *checksum,
|
||||||
guint64 content_len,
|
guint64 content_len,
|
||||||
OstreeRepoContentBareCommit *out_state,
|
OtTmpfile *out_tmpf,
|
||||||
GOutputStream **out_stream,
|
|
||||||
gboolean *out_have_object,
|
gboolean *out_have_object,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
|
||||||
g_autofree char *temp_filename = NULL;
|
|
||||||
g_autoptr(GOutputStream) ret_stream = NULL;
|
|
||||||
gboolean have_obj;
|
gboolean have_obj;
|
||||||
|
|
||||||
if (!_ostree_repo_has_loose_object (self, checksum, OSTREE_OBJECT_TYPE_FILE, &have_obj,
|
if (!_ostree_repo_has_loose_object (self, checksum, OSTREE_OBJECT_TYPE_FILE, &have_obj,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
return FALSE;
|
||||||
|
/* Do we already have this object? */
|
||||||
if (!have_obj)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
if (!glnx_open_tmpfile_linkable_at (self->tmp_dir_fd, ".", O_WRONLY|O_CLOEXEC,
|
|
||||||
&fd, &temp_filename, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!ot_fallocate (fd, content_len, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret_stream = g_unix_output_stream_new (fd, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = TRUE;
|
|
||||||
if (!have_obj)
|
|
||||||
{
|
|
||||||
out_state->temp_filename = temp_filename;
|
|
||||||
temp_filename = NULL;
|
|
||||||
out_state->fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)ret_stream);
|
|
||||||
if (out_stream)
|
|
||||||
*out_stream = g_steal_pointer (&ret_stream);
|
|
||||||
}
|
|
||||||
*out_have_object = have_obj;
|
*out_have_object = have_obj;
|
||||||
out:
|
if (have_obj)
|
||||||
return ret;
|
{
|
||||||
|
/* Make sure the tempfile is unset */
|
||||||
|
out_tmpf->initialized = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ot_open_tmpfile_linkable_at (self->tmp_dir_fd, ".", O_WRONLY|O_CLOEXEC,
|
||||||
|
out_tmpf, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_ostree_repo_commit_trusted_content_bare (OstreeRepo *self,
|
_ostree_repo_commit_trusted_content_bare (OstreeRepo *self,
|
||||||
const char *checksum,
|
const char *checksum,
|
||||||
OstreeRepoContentBareCommit *state,
|
OtTmpfile *tmpf,
|
||||||
guint32 uid,
|
guint32 uid,
|
||||||
guint32 gid,
|
guint32 gid,
|
||||||
guint32 mode,
|
guint32 mode,
|
||||||
|
|
@ -504,25 +486,22 @@ _ostree_repo_commit_trusted_content_bare (OstreeRepo *self,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
/* I don't think this is necessary, but a similar check was here previously,
|
||||||
|
* keeping it for extra redundancy.
|
||||||
|
*/
|
||||||
|
if (!tmpf->initialized || tmpf->fd == -1)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
if (state->fd != -1)
|
if (!commit_loose_content_object (self, checksum,
|
||||||
{
|
tmpf->path,
|
||||||
if (!commit_loose_content_object (self, checksum,
|
FALSE, uid, gid, mode,
|
||||||
state->temp_filename,
|
xattrs, tmpf->fd,
|
||||||
FALSE, uid, gid, mode,
|
cancellable, error))
|
||||||
xattrs, state->fd,
|
return glnx_prefix_error (error, "Writing object %s.%s", checksum, ostree_object_type_to_string (OSTREE_OBJECT_TYPE_FILE));
|
||||||
cancellable, error))
|
/* The path was consumed */
|
||||||
{
|
g_clear_pointer (&tmpf->path, g_free);
|
||||||
g_prefix_error (error, "Writing object %s.%s: ", checksum, ostree_object_type_to_string (OSTREE_OBJECT_TYPE_FILE));
|
tmpf->initialized = FALSE;
|
||||||
goto out;
|
return TRUE;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = TRUE;
|
|
||||||
out:
|
|
||||||
g_free (state->temp_filename);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
#include "ostree-ref.h"
|
#include "ostree-ref.h"
|
||||||
#include "ostree-repo.h"
|
#include "ostree-repo.h"
|
||||||
#include "ostree-remote-private.h"
|
#include "ostree-remote-private.h"
|
||||||
#include "libglnx.h"
|
#include "otutil.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
@ -305,17 +305,11 @@ _ostree_repo_commit_loose_final (OstreeRepo *self,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int fd;
|
|
||||||
char *temp_filename;
|
|
||||||
} OstreeRepoContentBareCommit;
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_ostree_repo_open_content_bare (OstreeRepo *self,
|
_ostree_repo_open_content_bare (OstreeRepo *self,
|
||||||
const char *checksum,
|
const char *checksum,
|
||||||
guint64 content_len,
|
guint64 content_len,
|
||||||
OstreeRepoContentBareCommit *out_state,
|
OtTmpfile *out_tmpf,
|
||||||
GOutputStream **out_stream,
|
|
||||||
gboolean *out_have_object,
|
gboolean *out_have_object,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
@ -323,7 +317,7 @@ _ostree_repo_open_content_bare (OstreeRepo *self,
|
||||||
gboolean
|
gboolean
|
||||||
_ostree_repo_commit_trusted_content_bare (OstreeRepo *self,
|
_ostree_repo_commit_trusted_content_bare (OstreeRepo *self,
|
||||||
const char *checksum,
|
const char *checksum,
|
||||||
OstreeRepoContentBareCommit *state,
|
OtTmpfile *tmpf,
|
||||||
guint32 uid,
|
guint32 uid,
|
||||||
guint32 gid,
|
guint32 gid,
|
||||||
guint32 mode,
|
guint32 mode,
|
||||||
|
|
|
||||||
|
|
@ -1108,7 +1108,7 @@ meta_fetch_on_complete (GObject *object,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now delete it, keeping the fd open as the last reference); see comment in
|
/* Now delete it, keeping the fd open as the last reference; see comment in
|
||||||
* corresponding content fetch path.
|
* corresponding content fetch path.
|
||||||
*/
|
*/
|
||||||
ot_cleanup_unlinkat (&tmp_unlinker);
|
ot_cleanup_unlinkat (&tmp_unlinker);
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ typedef struct {
|
||||||
GError **async_error;
|
GError **async_error;
|
||||||
|
|
||||||
OstreeObjectType output_objtype;
|
OstreeObjectType output_objtype;
|
||||||
OstreeRepoContentBareCommit barecommitstate;
|
OtTmpfile tmpf;
|
||||||
guint64 content_size;
|
guint64 content_size;
|
||||||
GOutputStream *content_out;
|
GOutputStream *content_out;
|
||||||
GChecksum *content_checksum;
|
GChecksum *content_checksum;
|
||||||
|
|
@ -281,6 +281,8 @@ _ostree_static_delta_part_execute (OstreeRepo *repo,
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
out:
|
out:
|
||||||
|
ot_tmpfile_clear (&state->tmpf);
|
||||||
|
g_clear_object (&state->content_out);
|
||||||
g_clear_pointer (&state->content_checksum, g_checksum_free);
|
g_clear_pointer (&state->content_checksum, g_checksum_free);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -419,8 +421,6 @@ do_content_open_generic (OstreeRepo *repo,
|
||||||
if (!read_varuint64 (state, &xattr_offset, error))
|
if (!read_varuint64 (state, &xattr_offset, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
state->barecommitstate.fd = -1;
|
|
||||||
|
|
||||||
modev = g_variant_get_child_value (state->mode_dict, mode_offset);
|
modev = g_variant_get_child_value (state->mode_dict, mode_offset);
|
||||||
g_variant_get (modev, "(uuu)", &uid, &gid, &mode);
|
g_variant_get (modev, "(uuu)", &uid, &gid, &mode);
|
||||||
state->uid = GUINT32_FROM_BE (uid);
|
state->uid = GUINT32_FROM_BE (uid);
|
||||||
|
|
@ -608,14 +608,14 @@ dispatch_open_splice_and_close (OstreeRepo *repo,
|
||||||
{
|
{
|
||||||
if (!_ostree_repo_open_content_bare (repo, state->checksum,
|
if (!_ostree_repo_open_content_bare (repo, state->checksum,
|
||||||
state->content_size,
|
state->content_size,
|
||||||
&state->barecommitstate,
|
&state->tmpf,
|
||||||
&state->content_out,
|
|
||||||
&state->have_obj,
|
&state->have_obj,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!state->have_obj)
|
if (!state->have_obj)
|
||||||
{
|
{
|
||||||
|
state->content_out = g_unix_output_stream_new (state->tmpf.fd, FALSE);
|
||||||
if (!handle_untrusted_content_checksum (repo, state, cancellable, error))
|
if (!handle_untrusted_content_checksum (repo, state, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
@ -711,11 +711,12 @@ dispatch_open (OstreeRepo *repo,
|
||||||
|
|
||||||
if (!_ostree_repo_open_content_bare (repo, state->checksum,
|
if (!_ostree_repo_open_content_bare (repo, state->checksum,
|
||||||
state->content_size,
|
state->content_size,
|
||||||
&state->barecommitstate,
|
&state->tmpf,
|
||||||
&state->content_out,
|
|
||||||
&state->have_obj,
|
&state->have_obj,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
if (!state->have_obj)
|
||||||
|
state->content_out = g_unix_output_stream_new (state->tmpf.fd, FALSE);
|
||||||
|
|
||||||
if (!handle_untrusted_content_checksum (repo, state, cancellable, error))
|
if (!handle_untrusted_content_checksum (repo, state, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -899,11 +900,12 @@ dispatch_close (OstreeRepo *repo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_ostree_repo_commit_trusted_content_bare (repo, state->checksum, &state->barecommitstate,
|
if (!_ostree_repo_commit_trusted_content_bare (repo, state->checksum, &state->tmpf,
|
||||||
state->uid, state->gid, state->mode,
|
state->uid, state->gid, state->mode,
|
||||||
state->xattrs,
|
state->xattrs,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
g_clear_object (&state->content_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dispatch_unset_read_source (repo, state, cancellable, error))
|
if (!dispatch_unset_read_source (repo, state, cancellable, error))
|
||||||
|
|
@ -911,7 +913,6 @@ dispatch_close (OstreeRepo *repo,
|
||||||
|
|
||||||
g_clear_pointer (&state->xattrs, g_variant_unref);
|
g_clear_pointer (&state->xattrs, g_variant_unref);
|
||||||
g_clear_pointer (&state->content_checksum, g_checksum_free);
|
g_clear_pointer (&state->content_checksum, g_checksum_free);
|
||||||
g_clear_object (&state->content_out);
|
|
||||||
|
|
||||||
state->checksum_index++;
|
state->checksum_index++;
|
||||||
state->output_target = NULL;
|
state->output_target = NULL;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue