diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 6e6f0cd2..750c68f5 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -935,8 +935,7 @@ static_deltapart_fetch_on_complete (GObject *object, g_autoptr(GVariant) metadata = NULL; g_autofree char *temp_path = NULL; g_autoptr(GInputStream) in = NULL; - g_autofree char *actual_checksum = NULL; - g_autofree guint8 *csum = NULL; + g_autoptr(GVariant) part = NULL; GError *local_error = NULL; GError **error = &local_error; gs_fd_close int fd = -1; @@ -950,54 +949,33 @@ static_deltapart_fetch_on_complete (GObject *object, fd = openat (_ostree_fetcher_get_dfd (fetcher), temp_path, O_RDONLY | O_CLOEXEC); if (fd == -1) { - gs_set_error_from_errno (error, errno); + glnx_set_error_from_errno (error); goto out; } + + /* From here on, if we fail to apply the delta, we'll re-fetch it */ + if (unlinkat (_ostree_fetcher_get_dfd (fetcher), temp_path, 0) < 0) + { + glnx_set_error_from_errno (error); + goto out; + } + in = g_unix_input_stream_new (fd, FALSE); - /* TODO - consider making async */ - if (!ot_gio_checksum_stream (in, &csum, pull_data->cancellable, error)) + /* TODO - make async */ + if (!_ostree_static_delta_part_open (in, NULL, 0, fetch_data->expected_checksum, + &part, pull_data->cancellable, error)) goto out; - actual_checksum = ostree_checksum_from_bytes (csum); - - if (strcmp (actual_checksum, fetch_data->expected_checksum) != 0) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Corrupted static delta part; checksum expected='%s' actual='%s'", - fetch_data->expected_checksum, actual_checksum); - goto out; - } - - /* Might as well close the fd here */ - (void) g_input_stream_close (in, NULL, NULL); - - { - GMappedFile *mfile = NULL; - g_autoptr(GBytes) delta_data = NULL; - - mfile = g_mapped_file_new_from_fd (fd, FALSE, error); - if (!mfile) - goto out; - delta_data = g_mapped_file_get_bytes (mfile); - g_mapped_file_unref (mfile); - - /* Unlink now while we're holding an open fd, so that on success - * or error, the file will be gone. This is particularly - * important if say we hit e.g. ENOSPC. - */ - (void) unlinkat (_ostree_fetcher_get_dfd (fetcher), temp_path, 0); - - _ostree_static_delta_part_execute_async (pull_data->repo, - fetch_data->objects, - delta_data, - /* Trust checksums if summary was gpg signed */ - pull_data->gpg_verify_summary && pull_data->summary_data_sig, - pull_data->cancellable, - on_static_delta_written, - fetch_data); - pull_data->n_outstanding_deltapart_write_requests++; - } + _ostree_static_delta_part_execute_async (pull_data->repo, + fetch_data->objects, + part, + /* Trust checksums if summary was gpg signed */ + pull_data->gpg_verify_summary && pull_data->summary_data_sig, + pull_data->cancellable, + on_static_delta_written, + fetch_data); + pull_data->n_outstanding_deltapart_write_requests++; out: g_assert (pull_data->n_outstanding_deltapart_fetches > 0); @@ -1604,10 +1582,10 @@ process_one_static_delta (OtPullData *pull_data, FetchStaticDeltaData *fetch_data; g_autoptr(GVariant) csum_v = NULL; g_autoptr(GVariant) objects = NULL; - g_autoptr(GVariant) part_data = NULL; - g_autoptr(GBytes) delta_data = NULL; + g_autoptr(GBytes) inline_part_bytes = NULL; guint64 size, usize; guint32 version; + const gboolean trusted = pull_data->gpg_verify_summary && pull_data->summary_data_sig; header = g_variant_get_child_value (headers, i); g_variant_get (header, "(u@aytt@ay)", &version, &csum_v, &size, &usize, &objects); @@ -1623,31 +1601,6 @@ process_one_static_delta (OtPullData *pull_data, if (!csum) goto out; - deltapart_path = _ostree_get_relative_static_delta_part_path (from_revision, to_revision, i); - - part_data = g_variant_lookup_value (metadata, deltapart_path, G_VARIANT_TYPE ("(yay)")); - if (part_data) - { - g_autofree char *actual_checksum = NULL; - g_autofree char *expected_checksum = ostree_checksum_from_bytes_v (csum_v); - - delta_data = g_variant_get_data_as_bytes (part_data); - - /* For inline parts we are relying on per-commit GPG, so this isn't strictly necessary for security. - * See https://github.com/GNOME/ostree/pull/139 - */ - actual_checksum = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, delta_data); - if (strcmp (actual_checksum, expected_checksum) != 0) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Corrupted static delta part; checksum expected='%s' actual='%s'", - expected_checksum, actual_checksum); - goto out; - } - } - - pull_data->total_deltapart_size += size; - if (!_ostree_repo_static_delta_part_have_all_objects (pull_data->repo, objects, &have_all, @@ -1663,18 +1616,38 @@ process_one_static_delta (OtPullData *pull_data, continue; } + deltapart_path = _ostree_get_relative_static_delta_part_path (from_revision, to_revision, i); + + { g_autoptr(GVariant) part_datav = + g_variant_lookup_value (metadata, deltapart_path, G_VARIANT_TYPE ("(yay)")); + + if (part_datav) + inline_part_bytes = g_variant_get_data_as_bytes (part_datav); + } + + pull_data->total_deltapart_size += size; + fetch_data = g_new0 (FetchStaticDeltaData, 1); fetch_data->pull_data = pull_data; fetch_data->objects = g_variant_ref (objects); fetch_data->expected_checksum = ostree_checksum_from_bytes_v (csum_v); - if (delta_data != NULL) + if (inline_part_bytes != NULL) { + g_autoptr(GInputStream) memin = g_memory_input_stream_new_from_bytes (inline_part_bytes); + g_autoptr(GVariant) inline_delta_part = NULL; + + /* For inline parts we are relying on per-commit GPG, so don't bother checksumming. */ + if (!_ostree_static_delta_part_open (memin, inline_part_bytes, + OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM, + NULL, &inline_delta_part, + cancellable, error)) + goto out; + _ostree_static_delta_part_execute_async (pull_data->repo, fetch_data->objects, - delta_data, - /* Trust checksums if summary was gpg signed */ - pull_data->gpg_verify_summary && pull_data->summary_data_sig, + inline_delta_part, + trusted, pull_data->cancellable, on_static_delta_written, fetch_data); diff --git a/src/libostree/ostree-repo-static-delta-core.c b/src/libostree/ostree-repo-static-delta-core.c index bc1b460c..e9d5c15e 100644 --- a/src/libostree/ostree-repo-static-delta-core.c +++ b/src/libostree/ostree-repo-static-delta-core.c @@ -20,9 +20,14 @@ #include "config.h" +#include +#include +#include #include "ostree-core-private.h" #include "ostree-repo-private.h" +#include "ostree-lzma-decompressor.h" #include "ostree-cmdprivate.h" +#include "ostree-checksum-input-stream.h" #include "ostree-repo-static-delta-private.h" #include "otutil.h" @@ -226,31 +231,45 @@ ostree_repo_static_delta_execute_offline (OstreeRepo *self, { gboolean ret = FALSE; guint i, n; - g_autoptr(GFile) meta_file = NULL; - g_autoptr(GFile) dir = NULL; + const char *dir_or_file_path = NULL; + glnx_fd_close int meta_fd = -1; + glnx_fd_close int dfd = -1; g_autoptr(GVariant) meta = NULL; g_autoptr(GVariant) headers = NULL; g_autoptr(GVariant) metadata = NULL; g_autoptr(GVariant) fallback = NULL; g_autofree char *to_checksum = NULL; g_autofree char *from_checksum = NULL; - GFileType file_type; + dir_or_file_path = gs_file_get_path_cached (dir_or_file); - file_type = g_file_query_file_type (dir_or_file, 0, cancellable); - if (file_type == G_FILE_TYPE_DIRECTORY) + /* First, try opening it as a directory */ + dfd = glnx_opendirat_with_errno (AT_FDCWD, dir_or_file_path, TRUE); + if (dfd < 0) { - dir = g_object_ref (dir_or_file); - meta_file = g_file_get_child (dir, "superblock"); - } - else - { - meta_file = g_object_ref (dir_or_file); - dir = g_file_get_parent (meta_file); + if (errno != ENOTDIR) + { + glnx_set_error_from_errno (error); + goto out; + } + else + { + g_autofree char *dir = dirname (g_strdup (dir_or_file_path)); + + if (!glnx_opendirat (AT_FDCWD, dir, TRUE, &dfd, error)) + goto out; + } } - if (!ot_util_variant_map (meta_file, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), - FALSE, &meta, error)) + meta_fd = openat (dfd, "superblock", O_RDONLY | O_CLOEXEC); + if (meta_fd < 0) + { + glnx_set_error_from_errno (error); + goto out; + } + + if (!ot_util_variant_map_fd (meta_fd, 0, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), + FALSE, &meta, error)) goto out; /* Parsing OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT */ @@ -330,14 +349,18 @@ ostree_repo_static_delta_execute_offline (OstreeRepo *self, guint64 size; guint64 usize; const guchar *csum; + char checksum[65]; gboolean have_all; + g_autoptr(GInputStream) part_in = NULL; g_autoptr(GBytes) delta_data = NULL; - g_autoptr(GVariant) part_data = NULL; + g_autoptr(GVariant) inline_part_data = NULL; g_autoptr(GVariant) header = NULL; g_autoptr(GVariant) csum_v = NULL; g_autoptr(GVariant) objects = NULL; - g_autoptr(GBytes) bytes = NULL; + g_autoptr(GVariant) part = NULL; g_autofree char *deltapart_path = NULL; + OstreeStaticDeltaOpenFlags delta_open_flags = + skip_validation ? OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM : 0; header = g_variant_get_child_value (headers, i); g_variant_get (header, "(u@aytt@ay)", &version, &csum_v, &size, &usize, &objects); @@ -362,41 +385,56 @@ ostree_repo_static_delta_execute_offline (OstreeRepo *self, csum = ostree_checksum_bytes_peek_validate (csum_v, error); if (!csum) goto out; + ostree_checksum_inplace_from_bytes (csum, checksum); deltapart_path = _ostree_get_relative_static_delta_part_path (from_checksum, to_checksum, i); - part_data = g_variant_lookup_value (metadata, deltapart_path, G_VARIANT_TYPE("(yay)")); - if (part_data) + inline_part_data = g_variant_lookup_value (metadata, deltapart_path, G_VARIANT_TYPE("(yay)")); + if (inline_part_data) { - bytes = g_variant_get_data_as_bytes (part_data); + g_autoptr(GBytes) inline_part_bytes = g_variant_get_data_as_bytes (inline_part_data); + part_in = g_memory_input_stream_new_from_bytes (inline_part_bytes); + + /* For inline parts, we don't checksum, because it's + * included with the metadata, so we're not trying to + * protect against MITM or such. Non-security related + * checksums should be done at the underlying storage layer. + */ + delta_open_flags |= OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM; + + if (!_ostree_static_delta_part_open (part_in, inline_part_bytes, + delta_open_flags, + NULL, + &part, + cancellable, error)) + goto out; } else { - g_autoptr(GFile) part_path = ot_gfile_resolve_path_printf (dir, "%u", i); - GMappedFile *mfile = gs_file_map_noatime (part_path, cancellable, error); - if (!mfile) - goto out; + g_autofree char *relpath = g_strdup_printf ("%u", i); /* TODO avoid malloc here */ + glnx_fd_close int part_fd = openat (dfd, relpath, O_RDONLY | O_CLOEXEC); + if (part_fd < 0) + { + glnx_set_error_from_errno (error); + g_prefix_error (error, "Opening deltapart '%s': ", deltapart_path); + goto out; + } - bytes = g_mapped_file_get_bytes (mfile); - g_mapped_file_unref (mfile); - } + part_in = g_unix_input_stream_new (part_fd, FALSE); - if (!skip_validation) - { - g_autoptr(GInputStream) in = g_memory_input_stream_new_from_bytes (bytes); - - g_autofree char *expected_checksum = ostree_checksum_from_bytes (csum); - if (!_ostree_static_delta_part_validate (self, in, i, - expected_checksum, - cancellable, error)) + if (!_ostree_static_delta_part_open (part_in, NULL, + delta_open_flags, + checksum, + &part, + cancellable, error)) goto out; } - if (!_ostree_static_delta_part_execute (self, objects, bytes, skip_validation, + if (!_ostree_static_delta_part_execute (self, objects, part, skip_validation, cancellable, error)) { - g_prefix_error (error, "executing delta part %i: ", i); + g_prefix_error (error, "Executing delta part %i: ", i); goto out; } } @@ -406,6 +444,140 @@ ostree_repo_static_delta_execute_offline (OstreeRepo *self, return ret; } +gboolean +_ostree_static_delta_part_open (GInputStream *part_in, + GBytes *inline_part_bytes, + OstreeStaticDeltaOpenFlags flags, + const char *expected_checksum, + GVariant **out_part, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + const gboolean trusted = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_VARIANT_TRUSTED) > 0; + const gboolean skip_checksum = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM) > 0; + gsize bytes_read; + guint8 comptype; + g_autoptr(GChecksum) checksum = NULL; + g_autoptr(GInputStream) checksum_in = NULL; + g_autoptr(GVariant) ret_part = NULL; + GInputStream *source_in; + + /* We either take a fd or a GBytes reference */ + g_return_val_if_fail (G_IS_FILE_DESCRIPTOR_BASED (part_in) || inline_part_bytes != NULL, FALSE); + g_return_val_if_fail (skip_checksum || expected_checksum != NULL, FALSE); + + if (!skip_checksum) + { + checksum = g_checksum_new (G_CHECKSUM_SHA256); + checksum_in = (GInputStream*)ostree_checksum_input_stream_new (part_in, checksum); + source_in = checksum_in; + } + else + { + source_in = part_in; + } + + { guint8 buf[1]; + /* First byte is compression type */ + if (!g_input_stream_read_all (source_in, buf, sizeof(buf), &bytes_read, + cancellable, error)) + { + g_prefix_error (error, "Reading initial compression flag byte: "); + goto out; + } + comptype = buf[0]; + } + + switch (comptype) + { + case 0: + if (!inline_part_bytes) + { + int part_fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)part_in); + + /* No compression, no checksums - a fast path */ + if (!ot_util_variant_map_fd (part_fd, 1, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), + trusted, &ret_part, error)) + goto out; + } + else + { + g_autoptr(GBytes) content_bytes = g_bytes_new_from_bytes (inline_part_bytes, 1, + g_bytes_get_size (inline_part_bytes) - 1); + ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), + content_bytes, trusted); + } + + if (!skip_checksum) + g_checksum_update (checksum, g_variant_get_data (ret_part), + g_variant_get_size (ret_part)); + + break; + case 'x': + { + g_autofree char *tmppath = g_strdup ("/var/tmp/ostree-delta-XXXXXX"); + g_autoptr(GConverter) decomp = (GConverter*) _ostree_lzma_decompressor_new (); + g_autoptr(GInputStream) convin = g_converter_input_stream_new (source_in, decomp); + g_autoptr(GOutputStream) unpacked_out = NULL; + glnx_fd_close int unpacked_fd = -1; + gssize n_bytes_written; + + unpacked_fd = g_mkstemp_full (tmppath, O_RDWR | O_CLOEXEC, 0640); + if (unpacked_fd < 0) + { + glnx_set_error_from_errno (error); + goto out; + } + + /* Now make it autocleanup on process exit - in the future, we + * should consider caching unpacked deltas as well. + */ + if (unlink (tmppath) < 0) + { + glnx_set_error_from_errno (error); + goto out; + } + + unpacked_out = g_unix_output_stream_new (unpacked_fd, FALSE); + + n_bytes_written = g_output_stream_splice (unpacked_out, convin, + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | + G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + cancellable, error); + if (n_bytes_written < 0) + goto out; + + if (!ot_util_variant_map_fd (unpacked_fd, 0, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), + trusted, &ret_part, error)) + goto out; + } + break; + default: + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid compression type '%u'", comptype); + goto out; + } + + if (checksum) + { + const char *actual_checksum = g_checksum_get_string (checksum); + g_assert (expected_checksum != NULL); + if (strcmp (actual_checksum, expected_checksum) != 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Checksum mismatch in static delta part; expected=%s actual=%s", + expected_checksum, actual_checksum); + goto out; + } + } + + ret = TRUE; + *out_part = g_steal_pointer (&ret_part); + out: + return ret; +} + gboolean _ostree_repo_static_delta_dump (OstreeRepo *self, const char *delta_id, diff --git a/src/libostree/ostree-repo-static-delta-private.h b/src/libostree/ostree-repo-static-delta-private.h index b0e82ade..55777fcd 100644 --- a/src/libostree/ostree-repo-static-delta-private.h +++ b/src/libostree/ostree-repo-static-delta-private.h @@ -103,35 +103,36 @@ G_BEGIN_DECLS */ #define OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT "(a{sv}tayay" OSTREE_COMMIT_GVARIANT_STRING "aya" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT ")" +typedef enum { + OSTREE_STATIC_DELTA_OPEN_FLAGS_NONE = 0, + OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM = (1 << 0), + OSTREE_STATIC_DELTA_OPEN_FLAGS_VARIANT_TRUSTED = (1 << 1) +} OstreeStaticDeltaOpenFlags; + +gboolean +_ostree_static_delta_part_open (GInputStream *part_in, + GBytes *inline_part_bytes, + OstreeStaticDeltaOpenFlags flags, + const char *expected_checksum, + GVariant **out_part, + GCancellable *cancellable, + GError **error); + gboolean _ostree_static_delta_dump (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error); -gboolean _ostree_static_delta_part_validate (OstreeRepo *repo, - GInputStream *in, - guint part_offset, - const char *expected_checksum, - GCancellable *cancellable, - GError **error); - gboolean _ostree_static_delta_part_execute (OstreeRepo *repo, GVariant *header, - GBytes *partdata, + GVariant *part_payload, gboolean trusted, GCancellable *cancellable, GError **error); -gboolean _ostree_static_delta_part_execute_raw (OstreeRepo *repo, - GVariant *header, - GVariant *part, - gboolean trusted, - GCancellable *cancellable, - GError **error); - void _ostree_static_delta_part_execute_async (OstreeRepo *repo, GVariant *header, - GBytes *partdata, + GVariant *part_payload, gboolean trusted, GCancellable *cancellable, GAsyncReadyCallback callback, diff --git a/src/libostree/ostree-repo-static-delta-processing.c b/src/libostree/ostree-repo-static-delta-processing.c index 10e533c6..74423e7c 100644 --- a/src/libostree/ostree-repo-static-delta-processing.c +++ b/src/libostree/ostree-repo-static-delta-processing.c @@ -150,42 +150,12 @@ open_output_target (StaticDeltaExecutionState *state, } gboolean -_ostree_static_delta_part_validate (OstreeRepo *repo, - GInputStream *in, - guint part_offset, - const char *expected_checksum, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - g_autofree guchar *actual_checksum_bytes = NULL; - g_autofree char *actual_checksum = NULL; - - if (!ot_gio_checksum_stream (in, &actual_checksum_bytes, - cancellable, error)) - goto out; - - actual_checksum = ostree_checksum_from_bytes (actual_checksum_bytes); - if (strcmp (actual_checksum, expected_checksum) != 0) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Checksum mismatch in static delta part %u; expected=%s actual=%s", - part_offset, expected_checksum, actual_checksum); - goto out; - } - - ret = TRUE; - out: - return ret; -} - -gboolean -_ostree_static_delta_part_execute_raw (OstreeRepo *repo, - GVariant *objects, - GVariant *part, - gboolean trusted, - GCancellable *cancellable, - GError **error) +_ostree_static_delta_part_execute (OstreeRepo *repo, + GVariant *objects, + GVariant *part, + gboolean trusted, + GCancellable *cancellable, + GError **error) { gboolean ret = FALSE; guint8 *checksums_data; @@ -280,99 +250,10 @@ _ostree_static_delta_part_execute_raw (OstreeRepo *repo, return ret; } -static gboolean -decompress_all (GConverter *converter, - GBytes *data, - GBytes **out_uncompressed, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - g_autoptr(GMemoryInputStream) memin = (GMemoryInputStream*)g_memory_input_stream_new_from_bytes (data); - g_autoptr(GMemoryOutputStream) memout = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free); - g_autoptr(GInputStream) convin = g_converter_input_stream_new ((GInputStream*)memin, converter); - - { - gssize n_bytes_written = g_output_stream_splice ((GOutputStream*)memout, convin, - G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | - G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, - cancellable, error); - if (n_bytes_written < 0) - goto out; - } - - ret = TRUE; - *out_uncompressed = g_memory_output_stream_steal_as_bytes (memout); - out: - return ret; -} - -gboolean -_ostree_static_delta_part_execute (OstreeRepo *repo, - GVariant *header, - GBytes *part_bytes, - gboolean trusted, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - gsize partlen; - const guint8*partdata; - g_autoptr(GBytes) part_payload_bytes = NULL; - g_autoptr(GBytes) payload_data = NULL; - g_autoptr(GVariant) payload = NULL; - guint8 comptype; - - partdata = g_bytes_get_data (part_bytes, &partlen); - - if (partlen < 1) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Corrupted 0 length delta part"); - goto out; - } - - /* First byte is compression type */ - comptype = partdata[0]; - /* Then the rest may be compressed or uncompressed */ - part_payload_bytes = g_bytes_new_from_bytes (part_bytes, 1, partlen - 1); - switch (comptype) - { - case 0: - /* No compression */ - payload_data = g_bytes_ref (part_payload_bytes); - break; - case 'x': - { - g_autoptr(GConverter) decomp = - (GConverter*) _ostree_lzma_decompressor_new (); - - if (!decompress_all (decomp, part_payload_bytes, &payload_data, - cancellable, error)) - goto out; - } - break; - default: - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid compression type '%u'", comptype); - goto out; - } - - payload = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), - payload_data, FALSE); - if (!_ostree_static_delta_part_execute_raw (repo, header, payload, trusted, - cancellable, error)) - goto out; - - ret = TRUE; - out: - return ret; -} - typedef struct { OstreeRepo *repo; GVariant *header; - GBytes *partdata; + GVariant *part; GCancellable *cancellable; GSimpleAsyncResult *result; gboolean trusted; @@ -385,7 +266,7 @@ static_delta_part_execute_async_data_free (gpointer user_data) g_clear_object (&data->repo); g_variant_unref (data->header); - g_bytes_unref (data->partdata); + g_variant_unref (data->part); g_clear_object (&data->cancellable); g_free (data); } @@ -401,7 +282,7 @@ static_delta_part_execute_thread (GSimpleAsyncResult *res, data = g_simple_async_result_get_op_res_gpointer (res); if (!_ostree_static_delta_part_execute (data->repo, data->header, - data->partdata, + data->part, data->trusted, cancellable, &error)) g_simple_async_result_take_error (res, error); @@ -410,7 +291,7 @@ static_delta_part_execute_thread (GSimpleAsyncResult *res, void _ostree_static_delta_part_execute_async (OstreeRepo *repo, GVariant *header, - GBytes *partdata, + GVariant *part, gboolean trusted, GCancellable *cancellable, GAsyncReadyCallback callback, @@ -421,7 +302,7 @@ _ostree_static_delta_part_execute_async (OstreeRepo *repo, asyncdata = g_new0 (StaticDeltaPartExecuteAsyncData, 1); asyncdata->repo = g_object_ref (repo); asyncdata->header = g_variant_ref (header); - asyncdata->partdata = g_bytes_ref (partdata); + asyncdata->part = g_variant_ref (part); asyncdata->trusted = trusted; asyncdata->cancellable = cancellable ? g_object_ref (cancellable) : NULL;